{
  "name": "TakeoverConsole",
  "package": "@magicblocksai/ui",
  "file": "packages/ui/src/components/TakeoverConsole.tsx",
  "chapterTag": "19 Conversation",
  "chapter": "19-conversation.html",
  "sectionId": "takeover-console",
  "elName": "TakeoverConsole",
  "demoUrl": "https://brand.magicblocks.ai/components/19-conversation#takeover-console",
  "hasLiveDemo": false,
  "description": "The live human-takeover console — `<SessionPage mode=\"live\">`'s body. When a\nconversation needs a person, the AI **pauses** and the operator replies as the\nbrand on the contact's own channel, with **guardrails off** (a human may say\nwhat the AI can't). Two control states drive everything:",
  "useClient": true,
  "interactivity": "interactive",
  "namedExports": [
    {
      "name": "TakeoverConsole",
      "isPrincipal": true,
      "isType": false
    },
    {
      "name": "TakeoverConsoleProps",
      "isPrincipal": false,
      "isType": true
    },
    {
      "name": "TakeoverState",
      "isPrincipal": false,
      "isType": true
    },
    {
      "name": "SageSuggestion",
      "isPrincipal": false,
      "isType": true
    }
  ],
  "importStatement": "import { TakeoverConsole } from \"@magicblocksai/ui\";",
  "props": [
    {
      "name": "state",
      "optional": true,
      "type": "TakeoverState",
      "doc": "Controlled takeover state."
    },
    {
      "name": "defaultState",
      "optional": true,
      "type": "TakeoverState",
      "doc": "Uncontrolled initial state. Default `\"ai_driving\"`."
    },
    {
      "name": "onStateChange",
      "optional": true,
      "type": "(state: TakeoverState) => void",
      "doc": "Fires whenever the takeover state changes."
    },
    {
      "name": "channel",
      "optional": false,
      "type": "SessionChannel",
      "doc": "Channel the operator replies on — drives the chip."
    },
    {
      "name": "channelLabel",
      "optional": true,
      "type": "ReactNode",
      "doc": "Channel detail line — \"+1 (415) 555-0132\", \"sarah@acme.com\"."
    },
    {
      "name": "onTakeOver",
      "optional": true,
      "type": "() => void",
      "doc": "Fires when the operator takes over (also flips state → `human_in_control`)."
    },
    {
      "name": "handBackOptions",
      "optional": true,
      "type": "JourneyBlockOption[]",
      "doc": "Hand-back targets for the `<JourneyBlockPicker>` (shown once in control)."
    },
    {
      "name": "onHandBack",
      "optional": true,
      "type": "(id: string) => void",
      "doc": "Fires with the chosen hand-back target id."
    },
    {
      "name": "transcript",
      "optional": false,
      "type": "ReactNode",
      "doc": "Composed `<ChatTranscript>` — the conversation, incl. the \"took over\" system note."
    },
    {
      "name": "composerValue",
      "optional": true,
      "type": "string",
      "doc": "Composer value (controlled)."
    },
    {
      "name": "onComposerChange",
      "optional": true,
      "type": "(value: string) => void",
      "doc": ""
    },
    {
      "name": "onSend",
      "optional": true,
      "type": "(value: string) => void",
      "doc": "Fires when the operator sends a reply."
    },
    {
      "name": "sending",
      "optional": true,
      "type": "boolean",
      "doc": ""
    },
    {
      "name": "brandName",
      "optional": true,
      "type": "ReactNode; // ── operator-context sidebar ── /** Sidebar header — typically a compact contact summary. */ contextHeader?: ReactNode",
      "doc": "The operator sends *as* this brand — composer placeholder \"Reply as {brandName}…\"."
    },
    {
      "name": "keyFacts",
      "optional": true,
      "type": "KeyFact[]",
      "doc": "\"Key facts so far\" — rendered via `<KeyFactGrid layout=\"list\">`."
    },
    {
      "name": "sage",
      "optional": true,
      "type": "SageSuggestion",
      "doc": "\"Sage suggests\" co-pilot draft — insertable into the composer."
    },
    {
      "name": "journeyPosition",
      "optional": true,
      "type": "ReactNode",
      "doc": "\"Journey position\" — the block the contact is currently in."
    },
    {
      "name": "hideSidebar",
      "optional": true,
      "type": "boolean",
      "doc": "Hide the operator-context sidebar (narrow embeds). Default `false`."
    }
  ],
  "classesUsed": [
    "channel-chip",
    "takeover-console",
    "tc-aside",
    "tc-aside-head",
    "tc-aside-k",
    "tc-channel",
    "tc-channel-id",
    "tc-composer",
    "tc-controlbar",
    "tc-controlbar-action",
    "tc-cta",
    "tc-cta-text",
    "tc-facts",
    "tc-guard",
    "tc-guard-dot",
    "tc-journey",
    "tc-journey-v",
    "tc-main",
    "tc-sage-insert",
    "tc-sage-text",
    "tc-state",
    "tc-state-dot",
    "tc-takeover",
    "tc-transcript",
    "title"
  ],
  "examples": {
    "react": "<TakeoverConsole\n  defaultState=\"ai_driving\"\n  channel=\"sms\"\n  channelLabel=\"+1 (415) 555-0132\"\n  brandName=\"Acme\"\n  transcript={<ChatTranscript>{messages}</ChatTranscript>}\n  handBackOptions={[\n    { id: \"resume\", kind: \"resume\", label: \"Resume where the AI paused\", detail: \"Recommended\" },\n    { id: \"meeting\", kind: \"block\", label: \"Book a meeting\" },\n    { id: \"end\", kind: \"end\", label: \"End — no further automation\" },\n  ]}\n  onHandBack={(id) => handBack(id)}\n  keyFacts={facts}\n  sage={{ text: \"Offer the 14-day trial extension…\", onInsert: insertDraft }}\n  journeyPosition=\"Post-demo nurture · step 2\"\n/>",
    "html": "<div class=\"takeover-console\" data-state=\"human_in_control\">\n          <div class=\"tc-main\">\n            <div class=\"tc-controlbar\">\n              <span class=\"tc-state\"><span class=\"tc-state-dot\" aria-hidden=\"true\"></span> You're in control · AI paused</span>\n              <span class=\"tc-channel\"><span class=\"channel-chip\" data-channel=\"sms\">SMS</span><span class=\"tc-channel-id\">+1 (415) 555-0132</span></span>\n              <div class=\"tc-controlbar-action\">\n                <button type=\"button\" class=\"jbp-trigger\">Hand back <span class=\"jbp-caret\" aria-hidden=\"true\"></span></button>\n              </div>\n            </div>\n            <div class=\"tc-transcript\">\n              <div class=\"chat-transcript\">\n                <div class=\"chat-transcript-scroll\" role=\"log\">\n                  <div class=\"chat-transcript-list\">\n                    <div class=\"chat-msg is-from-user\">\n                      <div class=\"chat-msg-avatar\" aria-hidden=\"true\">MR</div>\n                      <div class=\"chat-msg-stack\">\n                        <div class=\"chat-msg-meta\"><span class=\"chat-msg-name\">Marcus</span><span class=\"chat-msg-time\">2:31</span></div>\n                        <div class=\"chat-msg-bubble-wrap\"><div class=\"chat-msg-bubble\"><div class=\"chat-msg-body\">This still isn't working and I've tried twice now.</div></div></div>\n                      </div>\n                    </div>\n                    <div class=\"chat-msg is-from-agent\">\n                      <div class=\"chat-msg-avatar\" aria-hidden=\"true\">S</div>\n                      <div class=\"chat-msg-stack\">\n                        <div class=\"chat-msg-meta\"><span class=\"chat-msg-name\">Sage</span><span class=\"chat-msg-time\">2:31</span></div>\n                        <div class=\"chat-msg-bubble-wrap\"><div class=\"chat-msg-bubble\"><div class=\"chat-msg-body\">I'm sorry about that — connecting you with a teammate now.</div></div></div>\n                      </div>\n                    </div>\n                    <div class=\"chat-msg is-from-system\" role=\"status\">\n                      <div class=\"chat-msg-system-line\">You took over · AI paused<span class=\"chat-msg-system-time\">2:32</span></div>\n                    </div>\n                    <div class=\"chat-msg is-from-operator\">\n                      <div class=\"chat-msg-avatar\" aria-hidden=\"true\">JS</div>\n                      <div class=\"chat-msg-stack\">\n                        <div class=\"chat-msg-meta\"><span class=\"chat-msg-name\">You</span><span class=\"chat-msg-human\">human</span><span class=\"chat-msg-time\">2:32</span></div>\n                        <div class=\"chat-msg-bubble-wrap\"><div class=\"chat-msg-bubble\"><div class=\"chat-msg-body\">Hi Marcus — I'll sort this out personally. What do you see on the final step?</div></div></div>\n                      </div>\n                    </div>\n                  </div>\n                </div>\n                <div class=\"chat-transcript-footer\">\n                  <form class=\"chat-composer\">\n                    <div class=\"chat-composer-row\">\n                      <textarea class=\"chat-composer-input\" rows=\"1\" placeholder=\"Reply as Acme…\" aria-label=\"Message\"></textarea>\n                      <div class=\"chat-composer-actions\"><button type=\"button\" class=\"tc-sage-insert\">Insert Sage draft</button></div>\n                      <button type=\"submit\" class=\"chat-composer-send\" aria-label=\"Send as human\"><span class=\"chat-composer-send-label\">Send as human</span></button>\n                    </div>\n                    <div class=\"chat-composer-helper\"><span class=\"tc-guard\"><span class=\"tc-guard-dot\" aria-hidden=\"true\"></span> Guardrails off · sending as a human</span></div>\n                  </form>\n                </div>\n              </div>\n            </div>\n          </div>\n          <aside class=\"tc-aside\" aria-label=\"Operator context\">\n            <div class=\"tc-aside-head\">\n              <span class=\"chat-msg-name\">Marcus Reid</span>\n              <span class=\"tc-channel-id\">SMS · negative sentiment</span>\n            </div>\n            <div class=\"tc-sage\">\n              <div class=\"tc-aside-k\">Sage suggests</div>\n              <div class=\"tc-sage-text\">Offer the 14-day trial extension and confirm their renewal date before they churn.</div>\n              <button type=\"button\" class=\"tc-sage-insert\">Insert into reply</button>\n            </div>\n            <div class=\"tc-facts\">\n              <div class=\"tc-aside-k\">Key facts so far</div>\n              <div class=\"key-fact-grid\" data-layout=\"list\">\n                <div class=\"kfg-row\"><span class=\"kfg-key\">Plan</span><span class=\"kfg-val\">Scale (5 seats)</span></div>\n                <div class=\"kfg-row\"><span class=\"kfg-key\">Renewal</span><span class=\"kfg-val\">Apr 30</span></div>\n              </div>\n            </div>\n            <div class=\"tc-journey\">\n              <div class=\"tc-aside-k\">Journey position</div>\n              <div class=\"tc-journey-v\">Post-demo nurture · step 2</div>\n            </div>\n          </aside>\n        </div>",
    "css": ".channel-chip { display: inline-flex; align-items: center; gap: var(--s-1); font: 600 10px/1 var(--f-mono); text-transform: uppercase; letter-spacing: 0.04em; padding: 5px 9px; border-radius: var(--r-sm); background: var(--bg-sunk); color: var(--fg-dim); }\n\n.takeover-console { display: grid; grid-template-columns: minmax(0, 1fr) 300px; gap: var(--s-4); align-items: start; }\n\n.tc-aside { display: flex; flex-direction: column; gap: var(--s-3); min-width: 0; }\n\n.tc-aside-head { display: flex; flex-direction: column; gap: 2px; }\n\n.tc-aside-k { font: 600 9.5px/1 var(--f-mono); text-transform: uppercase; letter-spacing: 0.05em; color: var(--fg-faint); margin-bottom: var(--s-2); }\n\n.tc-channel { display: inline-flex; align-items: center; gap: var(--s-2); }\n\n.tc-channel-id { font: 500 11.5px/1 var(--f-mono); color: var(--fg-faint); }\n\n.tc-composer { min-width: 0; }\n\n.tc-controlbar {\n  display: flex; align-items: center; gap: var(--s-3); flex-wrap: wrap;\n  background: var(--bg-paper); border: 1px solid var(--hair); border-radius: var(--r-lg);\n  padding: var(--s-3) var(--s-4);\n}\n\n.tc-controlbar-action { margin-left: auto; }\n\n.tc-cta {\n  display: flex; align-items: center; gap: var(--s-3); flex-wrap: wrap;\n  border: 1px dashed var(--hair); border-radius: var(--r-lg);\n  padding: var(--s-4); background: var(--bg-warm);\n}\n\n.tc-cta-text { font: 500 13px/1.5 var(--f-body); color: var(--fg-dim); flex: 1; min-width: 200px; }\n\n.tc-facts { min-width: 0; }\n\n.tc-guard { display: inline-flex; align-items: center; gap: 7px; font: 600 11.5px/1 var(--f-body); color: var(--warning-text); }\n\n.tc-guard-dot { width: 8px; height: 8px; border-radius: 50%; flex: none; background: var(--warning, #F9AD03); }\n\n.tc-journey { min-width: 0; }\n\n.tc-journey-v { font: 500 12.5px/1.4 var(--f-body); color: var(--fg); }\n\n.tc-main { display: flex; flex-direction: column; gap: var(--s-3); min-width: 0; }\n\n.tc-sage-insert {\n  font: 600 11.5px/1 var(--f-body); color: var(--accent-text); background: var(--accent-soft);\n  border: 0; border-radius: var(--r-sm); padding: 6px 10px; cursor: pointer;\n}\n\n.tc-sage-text { font: 400 12.5px/1.5 var(--f-body); color: var(--fg); margin-bottom: var(--s-2); }\n\n.tc-state { display: inline-flex; align-items: center; gap: 8px; font: 600 13px/1 var(--f-body); color: var(--fg); }\n\n.tc-state-dot { width: 9px; height: 9px; border-radius: 50%; flex: none; background: var(--fg-faint); position: relative; }\n\n.tc-takeover {\n  font: 600 13px/1 var(--f-body); color: var(--on-accent, var(--paper)); background: var(--accent);\n  border: 0; border-radius: var(--r-md); padding: 9px 16px; cursor: pointer; white-space: nowrap;\n  transition: background var(--dur-2) var(--ease);\n}\n\n.tc-transcript { display: flex; flex-direction: column; min-width: 0; }\n\n.title { font: 700 32px/1.15 var(--f-display); letter-spacing: -0.015em; margin: 0; }"
  }
}
