{
  "name": "ChatTranscript",
  "package": "@magicblocksai/ui",
  "file": "packages/ui/src/components/ChatTranscript.tsx",
  "chapterTag": "16 Pipeline & CRM",
  "chapter": "16-app-pipeline.html",
  "sectionId": "session-card",
  "elName": "SessionCard",
  "demoUrl": "https://brand.magicblocks.ai/components/16-app-pipeline#session-card",
  "hasLiveDemo": false,
  "description": "Conversation viewer shell — header, scrollable message area, footer.\nChildren are a flat stack of `<ChatMessage>` nodes.",
  "useClient": true,
  "interactivity": "interactive",
  "namedExports": [
    {
      "name": "ChatTranscript",
      "isPrincipal": true,
      "isType": false
    },
    {
      "name": "ChatTranscriptProps",
      "isPrincipal": false,
      "isType": true
    }
  ],
  "importStatement": "import { ChatTranscript } from \"@magicblocksai/ui\";",
  "props": [
    {
      "name": "children",
      "optional": true,
      "type": "ReactNode",
      "doc": "Stack of `<ChatMessage>` (and any embedded system notes)."
    },
    {
      "name": "header",
      "optional": true,
      "type": "ReactNode",
      "doc": "Optional sticky header rendered above the scroll area — agent name, status, channel chip. Stays visible while the transcript scrolls."
    },
    {
      "name": "footer",
      "optional": true,
      "type": "ReactNode",
      "doc": "Optional pinned footer — typically `<ChatComposer>`. Stays at the bottom of the transcript shell regardless of scroll position."
    },
    {
      "name": "scrollToBottom",
      "optional": true,
      "type": "boolean",
      "doc": "Auto-scroll to the bottom when new children arrive. Only fires when the user is already at/near the bottom (within ~120px), so reading older messages isn't disrupted. Default `true`."
    },
    {
      "name": "agentTyping",
      "optional": true,
      "type": "boolean",
      "doc": "When `true`, renders a typing indicator at the end of the message stack — three pulsing dots in an agent bubble."
    },
    {
      "name": "agentTypingName",
      "optional": true,
      "type": "ReactNode",
      "doc": "Sender name shown beside the typing indicator."
    },
    {
      "name": "agentTypingAvatar",
      "optional": true,
      "type": "ReactNode",
      "doc": "Sender avatar shown beside the typing indicator."
    },
    {
      "name": "loading",
      "optional": true,
      "type": "boolean",
      "doc": "Renders a skeleton state instead of children."
    },
    {
      "name": "emptyState",
      "optional": true,
      "type": "ReactNode",
      "doc": "Empty-state node — shown when there are no children and not loading."
    },
    {
      "name": "centerEmptyState",
      "optional": true,
      "type": "boolean",
      "doc": "Centre the empty state vertically in the scroll viewport (welcome scenes)."
    },
    {
      "name": "density",
      "optional": true,
      "type": "\"comfortable\" | \"compact\"",
      "doc": "Density preset. Default `\"comfortable\"`."
    },
    {
      "name": "scrollThreshold",
      "optional": true,
      "type": "number",
      "doc": "Override the bottom-distance threshold for the auto-scroll check. Default `120` (px from bottom counts as \"at the bottom\")."
    }
  ],
  "classesUsed": [
    "chat-msg",
    "chat-msg-avatar",
    "chat-msg-bubble",
    "chat-msg-bubble-wrap",
    "chat-msg-meta",
    "chat-msg-name",
    "chat-msg-stack",
    "chat-transcript",
    "chat-transcript-empty",
    "chat-transcript-footer",
    "chat-transcript-header",
    "chat-transcript-list",
    "chat-transcript-scroll",
    "chat-transcript-skeleton",
    "chat-transcript-skeleton-row",
    "chat-typing-dots",
    "inbox",
    "title"
  ],
  "examples": {
    "react": null,
    "html": "<div class=\"session-card\" data-sentiment=\"positive\">\n  <div class=\"session-card-rail\"></div>\n  <div class=\"session-card-main\">\n    <div class=\"session-card-head\">\n      <span class=\"session-card-agent\" data-channel=\"webchat\">CL</span>\n      <div class=\"session-card-id\"><div class=\"session-card-name\">CREFCO Lead Agent</div><div class=\"session-card-sub\">Today, 2:14 PM</div></div>\n      <span class=\"channel-chip\" data-channel=\"webchat\">Webchat</span>\n      <span class=\"session-card-outcome\" data-tone=\"ok\">Meeting booked</span>\n    </div>\n    <div class=\"session-card-metrics\">\n      <div class=\"session-card-metric\"><b>18</b><span>messages</span></div>\n      <div class=\"session-card-metric\"><b>4m 12s</b><span>duration</span></div>\n      <div class=\"session-card-metric\"><b>2</b><span>sources</span></div>\n      <div class=\"session-card-metric\"><b data-tone=\"positive\">Positive</b><span>sentiment</span></div>\n    </div>\n    <div class=\"session-card-summary\">Returning lead asked about current refinance rates. Sage confirmed eligibility, captured loan details, and booked a 2 PM call with John Carter. No objections raised.</div>\n    <div class=\"session-card-facts\"><span class=\"badge\">loan_purpose = Refinance</span> <span class=\"badge\">amount = $420,000</span></div>\n    <button type=\"button\" class=\"session-card-toggle\" aria-expanded=\"false\">Show transcript (18)</button>\n  </div>\n</div>",
    "css": ".chat-msg {\n  display: grid;\n  /* minmax(0, 1fr) (not 1fr) so the bubble track can shrink below its\n     content's min-content — otherwise word-break:break-word collapses the\n     bubble to one character per line in a narrow container (e.g. a ~340px\n     test rail). */\n  grid-template-columns: 32px minmax(0, 1fr);\n  gap: var(--s-3);\n  margin: 0;\n  padding: 0 var(--s-4);\n}\n\n.chat-msg-avatar {\n  width: 32px;\n  height: 32px;\n  border-radius: 999px;\n  display: inline-flex;\n  align-items: center;\n  justify-content: center;\n  background: var(--bg-warm);\n  color: var(--fg);\n  font: 600 12px/1 var(--f-mono);\n  flex-shrink: 0;\n  overflow: hidden;\n}\n\n.chat-msg-bubble {\n  padding: 10px 14px;\n  font: 400 14px/1.5 var(--f-body);\n  background: var(--bg-warm);\n  color: var(--fg);\n  border-radius: 16px 16px 16px 4px;\n  word-break: break-word;\n  position: relative;\n}\n\n.chat-msg-bubble-wrap {\n  position: relative;\n  display: inline-flex;\n  max-width: min(560px, 80%);\n}\n\n.chat-msg-meta {\n  display: inline-flex;\n  align-items: baseline;\n  gap: 6px;\n  color: var(--fg-soft);\n  font: 400 11.5px/1 var(--f-body);\n}\n\n.chat-msg-name {\n  font: 500 12.5px/1 var(--f-body);\n  color: var(--fg);\n}\n\n.chat-msg-stack {\n  display: flex;\n  flex-direction: column;\n  gap: 4px;\n  min-width: 0;\n}\n\n.chat-transcript {\n  display: grid;\n  grid-template-rows: auto 1fr auto;\n  height: 100%;\n  min-height: 320px;\n  background: var(--bg-paper);\n  border: 1px solid var(--hair);\n  border-radius: var(--r-md);\n  overflow: hidden;\n}\n\n.chat-transcript-empty {\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  padding: var(--s-6) var(--s-4);\n  color: var(--fg-soft);\n  font: 400 13px/1.5 var(--f-body);\n  text-align: center;\n}\n\n.chat-transcript-footer {\n  border-top: 1px solid var(--hair-soft);\n  padding: var(--s-3) var(--s-4);\n  background: var(--bg-paper);\n}\n\n.chat-transcript-header {\n  padding: var(--s-3) var(--s-4);\n  border-bottom: 1px solid var(--hair-soft);\n  background: var(--bg-paper);\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  gap: var(--s-3);\n}\n\n.chat-transcript-list {\n  display: flex;\n  flex-direction: column;\n  gap: 0;\n}\n\n.chat-transcript-scroll {\n  overflow-y: auto;\n  overflow-x: hidden;\n  padding: var(--s-4) 0;\n  scroll-behavior: smooth;\n}\n\n.chat-transcript-skeleton {\n  display: flex;\n  flex-direction: column;\n  gap: var(--s-3);\n  padding: 0 var(--s-4);\n}\n\n.chat-transcript-skeleton-row {\n  height: 36px;\n  border-radius: 14px;\n  background: linear-gradient(90deg,\n    color-mix(in oklab, var(--fg) 6%, transparent) 0%,\n    color-mix(in oklab, var(--fg) 10%, transparent) 50%,\n    color-mix(in oklab, var(--fg) 6%, transparent) 100%);\n  background-size: 200% 100%;\n  max-width: 60%;\n  animation: skel-shimmer 1.8s ease-in-out infinite;\n}\n\n.chat-typing-dots {\n  display: inline-flex;\n  gap: 4px;\n  align-items: center;\n}\n\n.inbox {\n  display: flex; flex-direction: column;\n  background: var(--bg-paper);\n  border: 1px solid var(--hair);\n  border-radius: var(--r-lg);\n  overflow: hidden;\n}\n\n.title { font: 700 32px/1.15 var(--f-display); letter-spacing: -0.015em; margin: 0; }"
  }
}
