// Late phases: Pattern callout detail, Apology on-ramp, Artifact
// Depends on: SCENARIO, Icons, ScribbleCheck, AgentBadge

function CalloutPhase({ seat, godView, onPhase }) {
  const S = window.SCENARIO;
  const calloutEvent = S.chat.find(c => c.type === 'callout');

  // Firewall-aware sim stages:
  // 1 trigger   — maya's problematic message is live in the room
  // 2 detect    — mediator detects pattern (internal; no public leak yet)
  // 3 room      — neutral callout posts PUBLICLY (no quote, no pattern names)
  // 4 opaque    — jordan sees status chip: "claude is speaking privately with maya"
  // 5 private   — maya's coach opens private intervention with quote + evidence + taxonomy
  // 6 response  — maya picks an action (withdraw / park / open new topic)
  // 7 resume    — room resumes; jordan sees only that the pause ended
  const [stage, setStage] = React.useState(1);
  const [playing, setPlaying] = React.useState(true);
  const [resetKey, setResetKey] = React.useState(0);
  const [done, setDone] = React.useState(false);
  const [mayaAction, setMayaAction] = React.useState(null);

  const reset = () => {
    setStage(1);
    setDone(false);
    setMayaAction(null);
    setResetKey(k => k + 1);
    setPlaying(true);
  };

  React.useEffect(() => {
    if (!playing) return;
    const timers = [];
    const at = (ms, fn) => timers.push(setTimeout(fn, ms));
    at(1100, () => setStage(2));
    at(2300, () => setStage(3));
    at(3500, () => setStage(4));
    at(4700, () => setStage(5));
    at(7600, () => setMayaAction('withdraw'));
    at(8400, () => setStage(6));
    at(9800, () => { setStage(7); setDone(true); setPlaying(false); });
    return () => timers.forEach(clearTimeout);
  }, [playing, resetKey]);

  const stageLabel = {
    1: "maya's message just posted · mediator reading for patterns…",
    2: "2 patterns detected · deciding what's public vs. private…",
    3: "neutral callout posting to the room · no quote, no pattern names…",
    4: "jordan sees only an opaque status chip · content stays walled",
    5: "maya's coach opens a private intervention · quote + evidence + taxonomy",
    6: "maya chose an action · coach relays only the action, not the conversation",
    7: "room resumes · accountability was public, content wasn't",
  }[stage];

  const taxonomy = [
    { name: 'kitchen-sinking', desc: 'piling unrelated grievances on the current topic', severity: 'yellow', triggered: true },
    { name: 'absolutizing', desc: '"always" / "never" / "everything"', severity: 'yellow', triggered: true },
    { name: 'mind-reading', desc: "claiming knowledge of the other's motive", severity: 'yellow' },
    { name: 'criticism', desc: 'attacking character vs. the behavior', severity: 'yellow' },
    { name: 'defensiveness', desc: 'redirecting instead of engaging', severity: 'yellow' },
    { name: 'stonewalling', desc: 'refusing to respond after prompts', severity: 'red' },
    { name: 'contempt', desc: 'mockery, sneering — most corrosive', severity: 'red' },
    { name: 'DARVO', desc: 'deny, attack, reverse victim and offender', severity: 'red' },
    { name: 'gaslighting', desc: 'denying shared reality', severity: 'red' },
    { name: 'whataboutism', desc: "redirecting to the other's faults to dodge", severity: 'yellow' },
  ];

  // What each seat renders
  const isMaya = seat === 'A';
  const isJordan = seat === 'B';
  const isGod = seat === 'god';

  return (
    <div style={{ padding: '22px 40px 60px', maxWidth: 1200, margin: '0 auto' }}>
      <div className="tiny">phase 06 · pattern callout · firewall in action</div>
      <h1 style={{ marginTop: 6, marginBottom: 6 }}>
        same moment. three different views. that's the point.
      </h1>
      <p style={{ color: 'var(--ink-2)', maxWidth: 740, marginBottom: 14 }}>
        when the mediator flags a pattern, <b>accountability is public, content is private</b>. maya sees her coach pulling her aside with evidence. jordan sees that maya was pulled aside. the room sees a neutral callout — <span className="hand" style={{ color: 'var(--blue)' }}>no quote, no pattern names, no diagnosis.</span>
      </p>

      <SimBar
        playing={playing} onPlay={() => setPlaying(true)} onPause={() => setPlaying(false)} onReset={reset}
        done={done} label={stageLabel}
      />

      {/* Ledger symmetry panel — the coach's ledger is ALWAYS building for both parties */}
      <div className="paper-card" style={{
        padding: '14px 16px', marginBottom: 16,
        background: 'var(--paper-2)', borderLeft: '3px solid var(--blue)',
      }}>
        <div style={{ display: 'flex', alignItems: 'baseline', gap: 8, marginBottom: 4 }}>
          <div className="tiny" style={{ color: 'var(--blue)' }}>why this callout exists</div>
          <div style={{ flex: 1 }} />
          <span className="mono" style={{ fontSize: '0.65rem', color: 'var(--ink-3)' }}>
            maya's ledger: 4 entries · jordan's ledger: 5 entries
          </span>
        </div>
        <div style={{ lineHeight: 1.5, fontSize: '0.9rem', color: 'var(--ink-2)' }}>
          this yellow card isn't fresh. maya's coach has <b>been tracking patterns across every phase</b> — intake, openings, each room turn — and kitchen-sinking + absolutizing were already in her ledger before c5. jordan's coach is also building a ledger. {isJordan ? "you have your own — it's in the drawer bottom-right." : isMaya ? "you can read yours below, and jordan has his own that you can't see." : "both are visible to you in god view."} <span className="hand" style={{ color: 'var(--blue)' }}>the callout is evidence-backed, not vibes-based.</span>
        </div>
      </div>

      {/* Seat lens strip — makes the asymmetry literal */}
      <div style={{
        display: 'flex', gap: 6, marginBottom: 14,
        padding: '8px 12px',
        border: '1px dashed var(--rule)',
      }}>
        <div className="micro">viewing as</div>
        <div style={{ flex: 1 }} />
        <SeatLens active={isMaya} label="maya (subject)" color={S.parties.A.accent} note="full callout + private coaching + evidence" />
        <SeatLens active={isJordan} label="jordan (partner)" color={S.parties.B.accent} note="status chip only · no content" />
        <SeatLens active={isGod} label="god view" color="var(--blue)" note="both seats + mediator reasoning · firewall visualized" />
      </div>

      {/* Stage 1/2: always show the trigger in maya's/god view */}
      {(isMaya || isGod) && (
        <div className="fade-up">
          <div className="tiny mb-2">what triggered it · maya's last message <span style={{ color: 'var(--ink-4)' }}>· still in the room</span></div>
          <div className="msg msg-a" style={{ marginBottom: 14, background: 'var(--paper)' }}>
            <div className="micro mb-1" style={{ color: S.parties.A.accent }}>maya</div>
            <div style={{ lineHeight: 1.5 }}>
              "honestly also — you <u style={{ textDecorationStyle: 'wavy', textDecorationColor: 'var(--red)' }}>ALWAYS</u> do this. <u style={{ textDecorationStyle: 'wavy', textDecorationColor: 'var(--red)' }}>your family always comes first</u>, your friends, and i'm left reheating pasta. and your sister never asks how i'm doing either, by the way—"
            </div>
            {stage >= 2 && (
              <div className="mono mt-2 fade-up" style={{ color: 'var(--red)', fontSize: '0.7rem' }}>
                2 patterns detected · yellow severity · <span style={{ color: 'var(--ink-3)' }}>(mediator-internal · not posted)</span>
              </div>
            )}
          </div>
        </div>
      )}

      {isGod && <div className="dashed" style={{ margin: '20px 0' }} />}

      {/* Three-column god view OR one-column seat view */}
      <div style={{
        display: 'grid',
        gridTemplateColumns: isGod ? '1fr 1fr 1fr' : '1fr',
        gap: 18,
        position: 'relative',
      }}>
        {/* Column: THE ROOM — what gets posted publicly */}
        {(isGod) && (
          <LensColumn title="the room · public" sub="what both parties see" accent="var(--ink)" lens="room">
            <RoomLens stage={stage} calloutEvent={calloutEvent} />
          </LensColumn>
        )}

        {/* Column: MAYA's seat */}
        {(isMaya || isGod) && (
          <LensColumn title={isMaya ? "your view · maya" : "maya · subject of callout"} sub={isMaya ? "this is what you see right now" : "coach A is pulling her aside"} accent={S.parties.A.accent} lens="maya">
            <MayaLens stage={stage} calloutEvent={calloutEvent} taxonomy={taxonomy} mayaAction={mayaAction} setMayaAction={setMayaAction} canAct={isMaya || isGod} />
          </LensColumn>
        )}

        {/* Column: JORDAN's seat */}
        {(isJordan || isGod) && (
          <LensColumn title={isJordan ? "your view · jordan" : "jordan · partner"} sub={isJordan ? "you are jordan — this is all you see" : "no content leaks · just status"} accent={S.parties.B.accent} lens="jordan">
            <JordanLens stage={stage} mayaAction={mayaAction} />
          </LensColumn>
        )}

        {/* Firewall dashes between columns in god view */}
        {isGod && (
          <>
            <div aria-hidden style={{
              position: 'absolute', left: 'calc(33.33% - 9px)', top: 0, bottom: 0, width: 1,
              background: 'repeating-linear-gradient(to bottom, var(--ink-3) 0 4px, transparent 4px 9px)',
              pointerEvents: 'none',
            }} />
            <div aria-hidden style={{
              position: 'absolute', left: 'calc(66.66% - 9px)', top: 0, bottom: 0, width: 1,
              background: 'repeating-linear-gradient(to bottom, var(--ink-3) 0 4px, transparent 4px 9px)',
              pointerEvents: 'none',
            }} />
          </>
        )}
      </div>

      {godView && stage >= 3 && (
        <div className="god-panel mt-4">
          <b>firewall reasoning · </b>the public callout names the <i>shape</i> (temperature rose, new topics piled on) but never the <i>diagnosis</i> or the <i>quote</i>. the diagnosis is clinical; airing it publicly would humiliate maya and be counterproductive. jordan's opaque status preserves accountability (he knows something happened) without inviting him to weaponize it. if maya refuses the coaching, <i>that refusal</i> is what becomes visible — not the content.
        </div>
      )}

      {stage === 7 && (
        <div className="mt-4 fade-up" style={{ textAlign: 'center' }}>
          <div className="hand" style={{ color: 'var(--green)', fontSize: '1.3rem', marginBottom: 10 }}>
            the room exhales. nothing about maya's private conversation leaked — except the action she chose.
          </div>
          <button className="btn btn-primary" onClick={() => onPhase && onPhase('apology')}>
            continue → phase 07 · apology on-ramp <Icons.Arrow size={10} />
          </button>
        </div>
      )}

      {/* Full ledger section — shown after stage 5 when coaching is happening */}
      {stage >= 5 && (
        <div className="fade-up" style={{ marginTop: 28, paddingTop: 20, borderTop: '1px dashed var(--rule)' }}>
          <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', marginBottom: 6 }}>
            <h2 style={{ margin: 0, fontSize: '1.4rem' }}>the ledger behind this moment.</h2>
            <span className="mono" style={{ fontSize: '0.7rem', color: 'var(--ink-3)' }}>
              {isGod ? "god view · both visible · firewall still enforced in reality" :
               isMaya ? "your ledger · jordan's is firewalled" :
               "your ledger · maya's is firewalled"}
            </span>
          </div>
          <p style={{ color: 'var(--ink-2)', maxWidth: 780, marginBottom: 18, fontSize: '0.92rem', lineHeight: 1.5 }}>
            each coach has been noting things throughout — not to weaponize them, but so patterns can be named with evidence and strengths get their due. <span className="hand" style={{ color: 'var(--blue)' }}>you only ever read your own. dismiss anything you disagree with; your coach will push back once, then drop it.</span>
          </p>
          {isGod ? (
            <CoachLedger seat="god" currentPhase="callout" />
          ) : (
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 24 }}>
              <CoachLedger seat={seat} currentPhase="callout" />
              <div>
                <div style={{
                  display: 'flex', alignItems: 'center', gap: 8,
                  padding: '6px 10px',
                  borderBottom: `1.5px solid ${isMaya ? S.parties.B.accent : S.parties.A.accent}`,
                  marginBottom: 10,
                }}>
                  <div style={{ width: 8, height: 8, background: isMaya ? S.parties.B.accent : S.parties.A.accent, borderRadius: '50%', opacity: 0.5 }} />
                  <div className="mono" style={{ fontSize: '0.72rem', textTransform: 'uppercase', letterSpacing: '0.06em', color: isMaya ? S.parties.B.accent : S.parties.A.accent }}>
                    coach's ledger · {isMaya ? 'jordan' : 'maya'}
                  </div>
                  <div style={{ flex: 1 }} />
                  <span className="mono" style={{ fontSize: '0.65rem', color: 'var(--ink-3)' }}>firewalled</span>
                </div>
                <div style={{
                  padding: 20,
                  background: 'repeating-linear-gradient(135deg, transparent 0 8px, var(--paper-3) 8px 9px)',
                  border: '1px dashed var(--ink-3)',
                  minHeight: 280,
                  display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: 10,
                }}>
                  <Icons.Lock size={18} />
                  <div className="hand" style={{ color: 'var(--blue)', fontSize: '1.15rem', textAlign: 'center', lineHeight: 1.3, maxWidth: 280 }}>
                    {isMaya ? "jordan" : "maya"}'s coach is keeping their own notes. you will never see them.
                  </div>
                  <div className="mono" style={{ fontSize: '0.7rem', color: 'var(--ink-3)', textAlign: 'center' }}>
                    {((isMaya ? S.ledgerB : S.ledgerA) || []).length} entries · privacy holds forever
                  </div>
                  <div className="dashed" style={{ width: '60%', margin: '8px 0' }} />
                  <div style={{ fontStyle: 'italic', fontSize: '0.8rem', color: 'var(--ink-3)', textAlign: 'center', maxWidth: 280, lineHeight: 1.4 }}>
                    this is the point. you both know the other is being watched and helped — not graded and exposed.
                  </div>
                </div>
              </div>
            </div>
          )}
        </div>
      )}
    </div>
  );
}

function SeatLens({ active, label, color, note }) {
  return (
    <div style={{
      padding: '4px 10px',
      border: active ? `1.5px solid ${color}` : '1px dashed var(--rule)',
      background: active ? 'var(--paper-2)' : 'transparent',
      opacity: active ? 1 : 0.6,
      minWidth: 180,
    }}>
      <div className="mono" style={{ fontSize: '0.7rem', textTransform: 'uppercase', letterSpacing: '0.05em', color }}>
        {label}
      </div>
      <div className="micro" style={{ textTransform: 'none', letterSpacing: 0, color: 'var(--ink-3)', lineHeight: 1.25 }}>
        {note}
      </div>
    </div>
  );
}

function LensColumn({ title, sub, accent, lens, children }) {
  return (
    <div>
      <div className="tiny mb-1" style={{ color: accent, display: 'flex', alignItems: 'center', gap: 6 }}>
        {lens === 'room' && <span style={{ fontFamily: 'var(--font-mono)', fontSize: '0.6rem' }}>◎</span>}
        {lens === 'maya' && <span style={{ fontFamily: 'var(--font-mono)', fontSize: '0.6rem' }}>A</span>}
        {lens === 'jordan' && <span style={{ fontFamily: 'var(--font-mono)', fontSize: '0.6rem' }}>B</span>}
        {title}
      </div>
      <div className="micro mb-3" style={{ textTransform: 'none', letterSpacing: 0, color: 'var(--ink-3)' }}>{sub}</div>
      {children}
    </div>
  );
}

function RoomLens({ stage, calloutEvent }) {
  // What EVERYONE sees in the shared thread. Strictly neutral.
  return (
    <div className="paper-card p-3" style={{ minHeight: 320, background: 'var(--paper)' }}>
      <div style={{ fontStyle: 'italic', color: 'var(--ink-3)', marginBottom: 12, fontSize: '0.85rem' }}>
        ↑ earlier messages in the room ↑
      </div>

      {stage < 3 && (
        <div className="mono" style={{ color: 'var(--ink-4)', padding: '30px 10px', textAlign: 'center', fontSize: '0.75rem' }}>
          (nothing posted yet — mediator still reading)
        </div>
      )}

      {stage >= 3 && (
        <div className="fade-up" style={{
          padding: '12px 14px',
          background: 'oklch(97% 0.04 85)',
          border: '1px solid oklch(80% 0.1 85)',
          borderLeft: '3px solid oklch(60% 0.15 85)',
          margin: '6px 0 12px',
        }}>
          <div className="tiny mb-2" style={{ color: 'oklch(45% 0.14 85)', display: 'flex', justifyContent: 'space-between' }}>
            <span>public callout · to both</span>
            <AgentBadge agent="mediator" />
          </div>
          <div style={{ lineHeight: 1.5, color: 'var(--ink)' }}>
            i'm pausing us. the temperature rose and we drifted — new topics got added to the current one. let's stick to the one we locked. i'm going to speak with each of you briefly.
          </div>
          <div className="micro mt-2" style={{ color: 'oklch(45% 0.14 85)' }}>
            behavior named · no quote · no names of patterns · no blame assigned
          </div>
        </div>
      )}

      {stage >= 4 && stage < 7 && (
        <div className="fade-up" style={{
          padding: '10px 12px',
          background: 'var(--paper-3)',
          border: '1px dashed var(--ink-3)',
          margin: '6px 0',
          display: 'flex', alignItems: 'center', gap: 10,
        }}>
          <span className="blink-dot" style={{ width: 6, height: 6, borderRadius: '50%', background: 'var(--ink-3)', animation: 'blink 1.4s infinite' }} />
          <div className="mono" style={{ fontSize: '0.75rem', color: 'var(--ink-2)' }}>
            claude is speaking privately with maya. room paused.
          </div>
        </div>
      )}

      {stage === 7 && (
        <div className="fade-up" style={{
          padding: '10px 12px',
          background: 'var(--green-soft)',
          borderLeft: '2px solid var(--green)',
          margin: '6px 0',
        }}>
          <div className="mono" style={{ fontSize: '0.75rem', color: 'var(--green)' }}>
            private coaching complete · maya withdrew "always" and parked new topics · resuming
          </div>
          <div className="micro mt-1" style={{ textTransform: 'none', letterSpacing: 0, color: 'var(--ink-3)' }}>
            only the <i>action taken</i> is relayed. the conversation itself stays in maya's coach room.
          </div>
        </div>
      )}
    </div>
  );
}

function MayaLens({ stage, calloutEvent, taxonomy, mayaAction, setMayaAction, canAct }) {
  return (
    <div className="paper-card p-3" style={{ minHeight: 320, borderLeft: `3px solid ${window.SCENARIO.parties.A.accent}` }}>
      {stage < 5 && (
        <div className="mono" style={{ color: 'var(--ink-4)', padding: '30px 10px', textAlign: 'center', fontSize: '0.75rem', lineHeight: 1.5 }}>
          {stage < 3 ? "(your message is being read…)"
            : stage === 3 ? "a neutral callout just appeared in the room — same for both of you."
            : "heads up — coach is asking to talk privately…"}
        </div>
      )}

      {stage >= 5 && (
        <div className="fade-up">
          <div className="tiny mb-2" style={{ display: 'flex', justifyContent: 'space-between' }}>
            <span>coach · private with you</span>
            <AgentBadge agent="coachA" />
          </div>

          <div style={{ fontStyle: 'italic', lineHeight: 1.5, marginBottom: 12, color: 'var(--ink-2)' }}>
            "i want to talk with you about what just posted. two things i noticed — and i'm only saying them to you, not jordan."
          </div>

          <div style={{
            padding: '10px 12px', background: 'var(--paper-2)',
            borderLeft: '2px solid var(--ink-3)', marginBottom: 12,
          }}>
            <div className="micro mb-2">evidence · cited from your message</div>
            <ul style={{ margin: 0, paddingLeft: 16, fontSize: '0.85rem', lineHeight: 1.5 }}>
              <li><span style={{ background: 'oklch(92% 0.06 30)', padding: '0 3px' }}>"ALWAYS"</span> — absolutizing</li>
              <li><span style={{ background: 'oklch(92% 0.06 30)', padding: '0 3px' }}>"your family, your friends, your sister"</span> — 3 new topics piled on mid-thread (kitchen-sinking)</li>
            </ul>
          </div>

          <div style={{ fontStyle: 'italic', lineHeight: 1.5, marginBottom: 12, color: 'var(--ink-2)' }}>
            "is 'always' literally true, or is the recent pattern closer to three? and your sister — that's real stuff, but it's not <i>this</i> topic. do you want to park it, or open a second topic after we finish this one?"
          </div>

          {!mayaAction ? (
            <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap' }}>
              <button className="btn btn-sm" disabled={!canAct} onClick={() => setMayaAction('withdraw')}>withdraw "always"</button>
              <button className="btn btn-sm" disabled={!canAct} onClick={() => setMayaAction('park')}>park sister/friends</button>
              <button className="btn btn-sm btn-ghost" disabled={!canAct} onClick={() => setMayaAction('open')}>open new topic</button>
            </div>
          ) : (
            <div className="fade-up" style={{
              padding: '8px 10px', background: 'var(--green-soft)',
              borderLeft: '2px solid var(--green)',
            }}>
              <div className="mono" style={{ fontSize: '0.72rem', color: 'var(--green)' }}>
                chosen · {mayaAction === 'withdraw' ? 'withdraw "always"' : mayaAction === 'park' ? 'park the side topics' : 'open a new topic after this one'}
              </div>
              <div className="micro mt-1" style={{ textTransform: 'none', letterSpacing: 0, color: 'var(--ink-3)' }}>
                coach will relay <i>only the action</i> — never the conversation.
              </div>
            </div>
          )}
        </div>
      )}
    </div>
  );
}

function JordanLens({ stage, mayaAction }) {
  return (
    <div className="paper-card p-3" style={{ minHeight: 320, borderLeft: `3px solid ${window.SCENARIO.parties.B.accent}` }}>
      {stage < 3 && (
        <div className="mono" style={{ color: 'var(--ink-4)', padding: '30px 10px', textAlign: 'center', fontSize: '0.75rem' }}>
          (room is live · nothing new yet)
        </div>
      )}

      {stage >= 3 && (
        <div className="fade-up" style={{ marginBottom: 12 }}>
          <div className="tiny mb-2">from the room</div>
          <div style={{
            padding: '10px 12px',
            background: 'oklch(97% 0.04 85)',
            borderLeft: '3px solid oklch(60% 0.15 85)',
            fontSize: '0.85rem', lineHeight: 1.5,
            color: 'var(--ink-2)',
          }}>
            mediator paused the room. (same message maya sees.)
          </div>
        </div>
      )}

      {stage >= 4 && stage < 7 && (
        <div className="fade-up">
          <div className="tiny mb-2">status chip · no content</div>
          <div style={{
            padding: '14px',
            background: 'repeating-linear-gradient(135deg, transparent 0 8px, var(--paper-3) 8px 9px)',
            border: '1px dashed var(--ink-3)',
            position: 'relative',
          }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 8 }}>
              <Icons.Lock size={12} />
              <span className="micro" style={{ color: 'var(--ink-3)' }}>firewalled</span>
            </div>
            <div className="hand" style={{ fontSize: '1.15rem', color: 'var(--blue)', lineHeight: 1.2, marginBottom: 8 }}>
              "claude is speaking privately with maya about that last exchange."
            </div>
            <div style={{ fontStyle: 'italic', color: 'var(--ink-3)', lineHeight: 1.4, fontSize: '0.8rem' }}>
              you don't see what was said. you don't see which pattern was named. you only know this is happening — and that if maya declined the coaching, <i>that</i> would also be visible.
            </div>
          </div>

          <div className="dashed" style={{ margin: '14px 0' }} />

          <div className="micro mb-1" style={{ color: 'var(--ink-3)' }}>what you can <b>not</b> see</div>
          <ul style={{ margin: 0, paddingLeft: 16, fontSize: '0.78rem', lineHeight: 1.5, color: 'var(--ink-3)' }}>
            <li>the specific words that triggered it</li>
            <li>the pattern names (kitchen-sinking, absolutizing)</li>
            <li>the evidence cited</li>
            <li>what maya is saying back to her coach</li>
          </ul>
        </div>
      )}

      {stage === 7 && (
        <div className="fade-up">
          <div className="tiny mb-2">resumed</div>
          <div style={{
            padding: '10px 12px',
            background: 'var(--green-soft)',
            borderLeft: '2px solid var(--green)',
            fontSize: '0.85rem', lineHeight: 1.5,
          }}>
            the room is live again. you see that maya withdrew "always" and parked the side topics.
          </div>
          <div className="micro mt-2" style={{ textTransform: 'none', letterSpacing: 0, color: 'var(--ink-3)' }}>
            that's the <b>action</b>, not the conversation. the coaching itself stays in her room — forever.
          </div>
        </div>
      )}
    </div>
  );
}

// ApologyPhase moved to components/phases-apology.jsx

function ArtifactPhase({ seat, godView }) {
  const S = window.SCENARIO;
  const [asymPolicy, setAsymPolicy] = React.useState('hybrid');
  return (
    <div style={{ padding: '28px 40px 60px', maxWidth: 920, margin: '0 auto' }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: 24 }}>
        <div>
          <div className="tiny">phase 08 · artifact · both parties must approve before generation</div>
          <h1 style={{ marginTop: 6 }}>the document you both sign. the plan you'll actually follow.</h1>
        </div>
        <div style={{ display: 'flex', gap: 8 }}>
          <button className="btn btn-sm btn-ghost">request redaction</button>
          <button className="btn btn-sm btn-primary"><Icons.Stamp size={10}/> co-sign</button>
        </div>
      </div>

      {/* the document */}
      <div className="paper-card" style={{ padding: '44px 48px', position: 'relative' }}>
        <div className="tape" style={{ top: -8, left: 40, transform: 'rotate(-3deg)' }} />
        <div className="tape" style={{ top: -8, right: 50, transform: 'rotate(2deg)' }} />

        <div style={{ textAlign: 'center', marginBottom: 22 }}>
          <div className="tiny" style={{ color: 'var(--ink-3)' }}>clarguments · room {S.room.id}</div>
          <h2 style={{ fontFamily: 'var(--font-prose)', marginTop: 6, fontWeight: 500 }}>
            what we agreed, what we didn't, and what happens next.
          </h2>
          <div className="mono mt-1" style={{ color: 'var(--ink-3)' }}>
            apr 15 · 10:42pm · 58 minutes in-room
          </div>
          <div style={{ margin: '14px auto 0', width: 120 }}><InkLine width={120} height={6} /></div>
        </div>

        {/* the topic */}
        <section style={{ marginBottom: 28 }}>
          <div className="tiny mb-2">01 · the topic we locked</div>
          <div style={{ fontFamily: 'var(--font-prose)', fontSize: '1.15rem', fontStyle: 'italic', lineHeight: 1.4 }}>
            <span className="highlight">{S.topic.refined}</span>
          </div>
          <div className="micro mt-2">co-signed · maya · jordan — with amendment: "…and what counts as 'last-minute'?"</div>
        </section>

        {/* each position */}
        <section style={{ marginBottom: 28, display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 20 }}>
          <div>
            <div className="tiny mb-2" style={{ color: S.parties.A.accent }}>02a · maya's position</div>
            <div style={{ fontStyle: 'italic', lineHeight: 1.55 }}>{S.openings.A.synthesis}</div>
          </div>
          <div>
            <div className="tiny mb-2" style={{ color: S.parties.B.accent }}>02b · jordan's position</div>
            <div style={{ fontStyle: 'italic', lineHeight: 1.55 }}>{S.openings.B.synthesis}</div>
          </div>
        </section>

        {/* established truths */}
        <section style={{ marginBottom: 28 }}>
          <div className="tiny mb-2">03 · what we both acknowledged as true</div>
          {S.mapItems.filter(m => m.bucket === 'agreed').map(t => (
            <div key={t.id} style={{ display: 'flex', gap: 10, alignItems: 'flex-start', marginBottom: 8 }}>
              <ScribbleCheck />
              <div style={{ lineHeight: 1.45 }}>
                <span className="highlight">{t.text}</span>
              </div>
            </div>
          ))}
        </section>

        {/* what each acknowledged doing wrong */}
        <section style={{ marginBottom: 28 }}>
          <div className="tiny mb-2">04 · what each of us acknowledged doing wrong <span style={{ color: 'var(--ink-4)', fontWeight: 'normal' }}>· voluntary · both approved this wording</span></div>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 20 }}>
            <div style={{ borderLeft: `3px solid ${S.parties.A.accent}`, paddingLeft: 12 }}>
              <div className="micro mb-2" style={{ color: S.parties.A.accent }}>maya</div>
              {S.acknowledgments.A.map((a, i) => (
                <div key={i} style={{ marginBottom: 8, fontStyle: 'italic', lineHeight: 1.45 }}>"{a.text}"</div>
              ))}
            </div>
            <div style={{ borderLeft: `3px solid ${S.parties.B.accent}`, paddingLeft: 12 }}>
              <div className="micro mb-2" style={{ color: S.parties.B.accent }}>jordan</div>
              {S.acknowledgments.B.map((a, i) => (
                <div key={i} style={{ marginBottom: 8, fontStyle: 'italic', lineHeight: 1.45 }}>"{a.text}"</div>
              ))}
            </div>
          </div>

          {/* asymmetry policy */}
          <div style={{ marginTop: 16, padding: 14, background: 'var(--paper-2)', border: '1px dashed var(--ink-3)' }}>
            <div className="tiny mb-2">mediator's asymmetry note · both parties approved inclusion</div>
            <div style={{ fontStyle: 'italic', lineHeight: 1.55 }}>
              On the Apr 9 incident specifically, the record shows Jordan changed plans with under an hour's notice and the reason initially given was incomplete; he has acknowledged this. Maya's patterns (absolutizing, extended silences) are real and acknowledged, but operate at a different level of specificity. <span className="highlight-deep">We're noting this not to assign blame but so the action items are proportionate.</span>
            </div>
            <div className="mono mt-2" style={{ color: 'var(--ink-3)' }}>
              policy · hybrid (symmetric default, asymmetric where evidence supports it, both must sign)
            </div>
            <div style={{ display: 'flex', gap: 6, marginTop: 8 }}>
              <span className="stamp stamp-green">maya approved · 10:38pm</span>
              <span className="stamp stamp-green">jordan approved · 10:40pm</span>
            </div>
          </div>
        </section>

        {/* action items */}
        <section style={{ marginBottom: 28 }}>
          <div className="tiny mb-2">05 · action items · specific · operational · with check-ins</div>
          {S.actionItems.map((a, i) => (
            <div key={a.id} style={{
              display: 'grid',
              gridTemplateColumns: '60px 1fr 100px 80px',
              gap: 12,
              padding: '10px 0',
              borderBottom: '1px dashed var(--rule)',
              alignItems: 'flex-start',
            }}>
              <div className="mono" style={{ fontSize: '0.7rem', color: 'var(--ink-3)' }}>
                {String(i+1).padStart(2, '0')}
              </div>
              <div style={{ lineHeight: 1.4 }}>
                <div>{a.text}</div>
                <div className="micro mt-1">{a.timeframe}</div>
              </div>
              <div>
                <span className="pill" style={{
                  background: a.owner === 'both' ? 'var(--paper-3)' : a.owner === 'A' ? 'oklch(92% 0.05 25)' : 'oklch(92% 0.04 240)',
                  color: a.owner === 'A' ? S.parties.A.accent : a.owner === 'B' ? S.parties.B.accent : 'var(--ink-2)',
                  borderColor: 'transparent',
                }}>
                  {a.owner === 'both' ? 'both' : a.owner === 'A' ? 'maya' : 'jordan'}
                </span>
              </div>
              <div className="mono" style={{ fontSize: '0.68rem', color: 'var(--ink-3)' }}>
                check · {a.checkin}
              </div>
            </div>
          ))}
        </section>

        {/* parked */}
        <section style={{ marginBottom: 28 }}>
          <div className="tiny mb-2">06 · parked for future sessions</div>
          <div style={{ background: 'var(--paper-3)', padding: 12 }}>
            {S.parkingLot.map(p => (
              <div key={p.id} className="parked" style={{ marginBottom: 4, fontSize: '0.92rem' }}>{p.text}</div>
            ))}
          </div>
        </section>

        <section>
          <div className="tiny mb-2">07 · follow-up</div>
          <div style={{ fontStyle: 'italic', lineHeight: 1.5 }}>
            We'll re-open this room on <span className="highlight">April 30</span> for a 15-minute check-in on the action items. Either party can call a pause sooner with no penalty.
          </div>
        </section>

        <div className="dashed" style={{ margin: '32px 0 20px' }} />
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-end', marginTop: 24 }}>
          <div style={{ textAlign: 'center' }}>
            <div className="hand" style={{ fontSize: '2rem', color: S.parties.A.accent, lineHeight: 1, transform: 'rotate(-4deg)', display: 'inline-block' }}>maya</div>
            <div style={{ marginTop: 6 }}><InkLine width={140} /></div>
            <div className="micro mt-1">maya · apr 15 · 10:42pm</div>
          </div>
          <div style={{ textAlign: 'center' }}>
            <div className="hand" style={{ fontSize: '2rem', color: S.parties.B.accent, lineHeight: 1, transform: 'rotate(3deg)', display: 'inline-block' }}>jordan</div>
            <div style={{ marginTop: 6 }}><InkLine width={140} /></div>
            <div className="micro mt-1">jordan · apr 15 · 10:42pm</div>
          </div>
        </div>
      </div>

      {godView && (
        <div className="god-panel mt-4">
          <b>asymmetry reasoning · </b>{S.godNotes.asymmetry}
        </div>
      )}
    </div>
  );
}

Object.assign(window, { CalloutPhase, ArtifactPhase });
