/* SA Matrix — 통합 페르소나의 검색광고(SA) 집행 스펙 뷰.
   같은 페르소나에 대해 GFA(오디언스) 스펙과 별개로 SA(검색의도) 집행안을 제시.
   의도단계 분포 · 키워드 그룹×매칭타입 · 입찰/품질지수/노출순위/예상 성과 · 소재 가이드.
   "검색광고 키워드도구 반영" 버튼으로 검색량·경쟁도·입찰가 실데이터(tier B) 보정.
*/

const { useState: useSAState, useMemo: useSAMemo } = React;

function SAMatrix({ chosen, brand }) {
  const [kwData, setKwData] = useSAState(null);
  const [loading, setLoading] = useSAState(false);
  const [msg, setMsg] = useSAState('');
  const [src, setSrc] = useSAState('est');

  const profile = useSAMemo(() => {
    if (!window.BrandProfiles || !brand) return null;
    return window.BrandProfiles.match(brand) || null;
  }, [brand]);

  const sa = useSAMemo(() => {
    if (!window.SAEngine) return null;
    return window.SAEngine.buildSAMatrix(chosen.query, { brand, profile, result: chosen.result || {}, kwData });
  }, [JSON.stringify(chosen.query), brand, kwData, profile]);

  const strategy = useSAMemo(() => {
    if (!window.SAEngine || !window.SAEngine.buildStrategy || !sa) return null;
    const cpa = (chosen.result && chosen.result.cpa) || (profile && profile.economics && profile.economics.cpa) || null;
    // 카테고리 fallback: 키워드도구 미반영 시 realCategory가 비므로 페르소나 쿼리 leaf + 브랜드 업종으로 보정
    const catFromQuery = (chosen.query || []).flatMap(g => g.leaves || []).join(' ');
    const category = sa.realCategory || catFromQuery || '';
    return window.SAEngine.buildStrategy(chosen.query, { sa, profile, category, cpa });
  }, [sa, profile]);

  async function pullKwTool() {
    if (!window.DataLab || !sa) return;
    setLoading(true); setMsg('키워드도구 조회 중…');
    try {
      const res = await window.DataLab.keywordTool({ keywords: sa.allKeywords.slice(0, 80) });
      const map = {};
      for (const it of (res.items || [])) map[it.keyword] = { volume: it.volume, comp: it.comp, bid: it.bid };
      setKwData(map);
      const real = res.__source === 'real';
      setSrc(real ? 'real' : 'mock');
      setMsg((real ? '실 API' : 'MOCK(데모)') + ` · ${(res.items || []).length}개 키워드 검색량·경쟁도·입찰가 반영`);
    } catch (e) { setMsg('조회 실패: ' + (e.message || e)); }
    setLoading(false);
  }

  if (!sa) return <div className="sa-empty">SA 엔진 로드 대기 — 페르소나 키워드가 필요합니다.</div>;
  const won = n => '₩' + Math.round(n).toLocaleString();
  const fmtN = n => n >= 10000 ? (n / 10000).toFixed(1) + '만' : n.toLocaleString();
  const T = sa.totals;

  return (
    <div className="sa">
      {strategy && <StrategyBridge strategy={strategy} brand={brand} />}
      <div className="sa-note">
        <div className="sa-note-top">
          <span><b>통합 페르소나 · SA 집행</b> — 같은 페르소나를 <b>검색의도</b>로 잡는 검색광고 스펙. GFA(오디언스)와 병행 집행.</span>
          <button className="sa-btn" onClick={pullKwTool} disabled={loading} data-on={!!kwData}>
            {loading ? '조회 중…' : kwData ? '✓ 키워드도구 반영됨' : '🔎 검색광고 키워드도구 반영'}
          </button>
        </div>
        <span className="sa-prov">
          {kwData
            ? (src === 'real' ? <>검색량·경쟁도·입찰가 <b style={{ color: 'var(--plant)' }}>실 키워드도구(tier B)</b> 반영. {msg}</>
                              : <>데모(MOCK) 키워드도구 반영 — 메커니즘 시연. 실 검색광고 API 연결 시 tier B. {msg}</>)
            : <>검색량·경쟁도·입찰가·품질지수·노출순위는 휴리스틱 <b>추정</b> — 우측 버튼으로 검색광고 키워드도구 실데이터 반영(tier B). {msg}</>}
        </span>
      </div>

      {/* 검색의도 단계 분포 */}
      <div className="sa-intent">
        <span className="sa-mini">검색의도 단계 분포 (예상 클릭 기준)</span>
        <div className="sa-intent-bar">
          {sa.intentDist.map(i => i.pct > 0 && (
            <div key={i.id} className={'sa-iseg sa-tone-' + i.tone} style={{ width: i.pct + '%' }} title={i.label + ' ' + i.pct + '%'}>
              <span>{i.label}</span><em>{i.pct}%</em>
            </div>
          ))}
        </div>
        <div className="sa-intent-legend">
          {sa.intentDist.map(i => <span key={i.id} className={'sa-dot sa-tone-' + i.tone}>{i.label} · {i.note}</span>)}
        </div>
      </div>

      {/* 통합 예상 성과 */}
      <div className="sa-totals">
        <div className="sa-tot"><span>예상 클릭/월</span><b>{fmtN(T.clicks)}</b></div>
        <div className="sa-tot"><span>예상 전환/월</span><b>{T.conv}</b></div>
        <div className="sa-tot"><span>예상 비용/월</span><b>{won(T.cost)}</b></div>
        <div className="sa-tot sa-roas"><span>예상 ROAS</span><b>{T.roas}%</b></div>
      </div>

      {/* 키워드 그룹 × 매칭타입 */}
      <div className="sa-groups">
        {sa.groups.map(g => (
          <div key={g.id} className={'sa-grp sa-grp-' + g.id}>
            <div className="sa-grp-head">
              <div className="sa-grp-title">
                <strong>{g.label}</strong>
                <span className="sa-match" data-m={g.matchEn}>{g.match}</span>
                <span className="sa-grp-cnt">{g.count}개</span>
              </div>
              <div className="sa-grp-why">{g.why}</div>
            </div>
            <div className="sa-grp-stats">
              <span>품질 <b>{g.avgQuality}</b>/10</span>
              <span>입찰 <b>{won(g.bidLo)}~{won(g.bidHi)}</b></span>
              <span>클릭 <b>{fmtN(g.clicks)}</b></span>
              <span>전환 <b>{g.conv}</b></span>
              <span className="sa-grp-roas">ROAS <b>{g.roas}%</b></span>
            </div>
            <table className="sa-tbl">
              <thead><tr><th>키워드</th><th>의도</th><th>검색량</th><th>경쟁</th><th>입찰</th><th>품질</th><th>예상순위</th></tr></thead>
              <tbody>
                {g.keywords.slice(0, 8).map((k, i) => (
                  <tr key={i}>
                    <td className="sa-kw">{k.kw}</td>
                    <td><span className={'sa-itag sa-tone-' + k.intentTone}>{k.intentLabel}</span></td>
                    <td className="sa-num">{fmtN(k.volume)}</td>
                    <td className="sa-num" data-c={k.compLabel}>{k.compLabel}</td>
                    <td className="sa-num">{won(k.bid)}</td>
                    <td className="sa-num">{k.quality}</td>
                    <td className="sa-num">{k.rank}위</td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        ))}
      </div>

      {/* 소재 가이드 */}
      <SACreative brand={brand} />

      <style>{`
        .sa { display: flex; flex-direction: column; gap: 12px; }
        .sa-empty { padding: 22px; text-align: center; color: var(--text-dim); border: 1px dashed var(--border-strong); font-size: 13px; }
        .sa-mini { font-family: var(--font-mono); font-size: 10px; color: var(--text-mute); }
        .sa-note { font-size: 12px; line-height: 1.6; color: var(--text-dim); padding: 10px 12px; background: oklch(0.78 0.12 220 / 0.06); border-left: 2px solid var(--cyan); }
        .sa-note b { color: var(--text); font-weight: 600; }
        .sa-note-top { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; }
        .sa-btn { flex-shrink: 0; padding: 5px 11px; background: var(--cyan-soft); border: 1px solid var(--cyan); color: var(--cyan); font-size: 11px; font-weight: 600; font-family: var(--font-sans); cursor: pointer; white-space: nowrap; border-radius: 3px; }
        .sa-btn:hover:not(:disabled) { background: var(--cyan); color: var(--ink-000); }
        .sa-btn:disabled { opacity: .5; cursor: wait; }
        .sa-btn[data-on="true"] { background: var(--plant-soft); border-color: var(--plant); color: var(--plant); }
        .sa-prov { display: block; margin-top: 5px; font-size: 10.5px; color: var(--text-mute); }
        .sa-prov b { color: var(--cyan); }

        .sa-intent { padding: 10px 12px; background: oklch(0.10 0.02 240 / 0.5); border: 1px solid var(--border); }
        .sa-intent-bar { display: flex; height: 26px; margin: 7px 0 6px; border-radius: 4px; overflow: hidden; background: rgba(0,0,0,0.3); }
        .sa-iseg { display: flex; align-items: center; justify-content: center; gap: 5px; font-size: 10px; color: var(--ink-000); font-weight: 700; min-width: 0; overflow: hidden; white-space: nowrap; }
        .sa-iseg em { font-style: normal; font-family: var(--font-mono); }
        .sa-tone-cyan { background: var(--cyan); } .sa-tone-signal { background: var(--signal); } .sa-tone-plant { background: var(--plant); }
        .sa-intent-legend { display: flex; flex-wrap: wrap; gap: 4px 12px; }
        .sa-dot { font-size: 10px; color: var(--text-mute); display: inline-flex; align-items: center; gap: 5px; }
        .sa-dot::before { content: ''; width: 7px; height: 7px; border-radius: 50%; }
        .sa-dot.sa-tone-cyan::before { background: var(--cyan); } .sa-dot.sa-tone-signal::before { background: var(--signal); } .sa-dot.sa-tone-plant::before { background: var(--plant); }

        .sa-totals { display: flex; gap: 1px; background: var(--border); }
        .sa-tot { flex: 1; display: flex; flex-direction: column; gap: 2px; padding: 9px 10px; background: var(--ink-050, oklch(0.11 0.015 240)); }
        .sa-tot span { font-size: 10px; color: var(--text-mute); }
        .sa-tot b { font-family: var(--font-mono); font-size: 16px; color: var(--text); font-weight: 700; }
        .sa-roas b { color: var(--plant); }

        .sa-groups { display: flex; flex-direction: column; gap: 10px; }
        .sa-grp { padding: 11px 12px; background: oklch(0.10 0.02 240 / 0.5); border: 1px solid var(--border); border-left-width: 2px; }
        .sa-grp-brand { border-left-color: var(--plant); } .sa-grp-generic { border-left-color: var(--cyan); }
        .sa-grp-competitor { border-left-color: var(--alert); } .sa-grp-longtail { border-left-color: var(--signal); }
        .sa-grp-title { display: flex; align-items: center; gap: 8px; }
        .sa-grp-title strong { font-size: 13px; color: var(--text); }
        .sa-match { font-family: var(--font-mono); font-size: 9.5px; padding: 1px 7px; border-radius: 3px; border: 1px solid var(--border-strong); color: var(--text-dim); }
        .sa-match[data-m="exact"] { color: var(--plant); border-color: var(--plant); }
        .sa-match[data-m="phrase"] { color: var(--cyan); border-color: var(--cyan-dim); }
        .sa-match[data-m="broad"] { color: var(--signal); border-color: var(--signal-dim); }
        .sa-grp-cnt { font-family: var(--font-mono); font-size: 10px; color: var(--text-mute); margin-left: auto; }
        .sa-grp-why { font-size: 11px; color: var(--text-mute); margin-top: 3px; }
        .sa-grp-stats { display: flex; flex-wrap: wrap; gap: 4px 14px; margin: 8px 0; font-size: 11px; color: var(--text-dim); }
        .sa-grp-stats b { font-family: var(--font-mono); color: var(--text); }
        .sa-grp-roas b { color: var(--plant); }
        .sa-tbl { width: 100%; border-collapse: collapse; font-size: 10.5px; }
        .sa-tbl th { text-align: right; font-weight: 500; color: var(--text-mute); font-family: var(--font-mono); font-size: 9px; padding: 3px 5px; border-bottom: 1px solid var(--border); }
        .sa-tbl th:first-child, .sa-tbl td:first-child { text-align: left; }
        .sa-tbl td { padding: 3px 5px; border-bottom: 1px solid oklch(0.5 0.02 240 / 0.12); color: var(--text-dim); }
        .sa-kw { font-family: var(--font-mono); color: var(--text); }
        .sa-num { text-align: right; font-family: var(--font-mono); }
        .sa-num[data-c="높음"] { color: var(--alert); } .sa-num[data-c="중간"] { color: var(--signal); } .sa-num[data-c="낮음"] { color: var(--plant); }
        .sa-itag { font-size: 9px; padding: 1px 5px; border-radius: 3px; color: var(--ink-000); font-weight: 600; }
        .sa-itag.sa-tone-cyan { background: var(--cyan); } .sa-itag.sa-tone-signal { background: var(--signal); } .sa-itag.sa-tone-plant { background: var(--plant); }
      `}</style>
    </div>
  );
}

function StrategyBridge({ strategy, brand }) {
  const s = strategy.strat;
  const b = brand || '브랜드';
  return (
    <div className={'sgb sgb-' + s.tone}>
      <div className="sgb-head">
        <div>
          <div className="sgb-eyebrow">GFA × SA 전략 브릿지 · 공식 SA&DA 가이드 기반</div>
          <h3 className="sgb-title">{b}는 <span className="sgb-aware">{s.label}</span></h3>
          <div className="sgb-market">{s.market}</div>
        </div>
      </div>

      {/* 선순환 */}
      <div className="sgb-cycle">
        <span className="sgb-cnode sgb-sa">SA<small>검색량 한계</small></span>
        <span className="sgb-carrow">→</span>
        <span className="sgb-cnode sgb-da">DA(GFA)<small>전환·인지·검색량↑</small></span>
        <span className="sgb-carrow">→</span>
        <span className="sgb-cnode sgb-sa">SA<small>볼륨·효율 개선</small></span>
        <span className="sgb-cloop">⟲ 선순환</span>
      </div>

      {/* 인지도별 역할 표 */}
      <div className="sgb-grid">
        <div className="sgb-cell"><span className="sgb-l">SA 강점</span>{s.saStrength}</div>
        <div className="sgb-cell"><span className="sgb-l">SA 한계</span>{s.saLimit}</div>
        <div className="sgb-cell"><span className="sgb-l">DA 역할</span>{s.daRole}</div>
        <div className="sgb-cell sgb-goal"><span className="sgb-l">DA 목표</span><b>{s.daGoal}</b></div>
      </div>

      <div className="sgb-recos">
        <div className="sgb-reco"><span className="sgb-l">추천 캠페인 믹스</span><div className="sgb-chips">{s.mix.map((m, i) => <span key={i} className="sgb-chip sgb-chip-mix">{m}</span>)}</div><div className="sgb-why">{s.mixWhy}</div></div>
        <div className="sgb-reco"><span className="sgb-l">추천 타겟팅</span><div className="sgb-chips">{s.targeting.map((t, i) => <span key={i} className="sgb-chip">{t}</span>)}</div></div>
        <div className="sgb-reco"><span className="sgb-l">권장 일예산</span><div className="sgb-budget">{s.budget}{strategy.cpaX10 && <em> ≈ ₩{strategy.cpaX10.toLocaleString()}/일</em>}</div></div>
      </div>

      {/* SA→GFA 키워드 그룹 다리 */}
      <div className="sgb-bridge">
        <span className="sgb-l">SA → GFA 맞춤타겟 키워드 그룹 (SA 노출/전환 볼륨 → 그룹핑, 최소 모수 1,000)</span>
        <div className="sgb-bridge-cols">
          {strategy.bridge.map(g => (
            <div key={g.id} className="sgb-bcol">
              <div className="sgb-bcol-h"><strong>{g.label}</strong><span className={'sgb-min ' + (g.meetsMin ? 'ok' : 'no')}>{g.volume.toLocaleString()} {g.meetsMin ? '✓' : '< 1,000'}</span></div>
              <div className="sgb-axis">{g.axis}</div>
              <div className="sgb-bkws">{g.keywords.map((k, i) => <span key={i}>{k}</span>)}</div>
              <div className="sgb-bnote">{g.note}</div>
            </div>
          ))}
        </div>
      </div>

      {/* 소재 USP Align */}
      <div className="sgb-align">
        <span className="sgb-l">소재 USP Align — SA 고효율 T&D ↔ DA 소재 (동일 USP 양방향)</span>
        <div className="sgb-align-row">
          <div className="sgb-ac"><span className="sgb-ac-l">Pain</span>{strategy.align.pain.map((p, i) => <span key={i} className="sgb-atag sgb-pain">{p}</span>)}</div>
          <span className="sgb-carrow">→</span>
          <div className="sgb-ac"><span className="sgb-ac-l">USP/Solution</span>{strategy.align.usp.map((p, i) => <span key={i} className="sgb-atag sgb-usp">{p}</span>)}</div>
        </div>
        <div className="sgb-why">{strategy.align.tip}</div>
      </div>

      <style>{`
        .sgb { border: 1px solid var(--border-strong); border-radius: 6px; overflow: hidden; background: radial-gradient(120% 80% at 0% 0%, oklch(0.66 0.15 28 / 0.05), transparent 60%), var(--ink-100, oklch(0.13 0.02 240)); }
        .sgb-signal { border-left: 3px solid var(--signal); } .sgb-plant { border-left: 3px solid var(--plant); }
        .sgb-head { padding: 14px 16px 10px; border-bottom: 1px solid var(--border); }
        .sgb-eyebrow { font-family: var(--font-mono); font-size: 10px; letter-spacing: .12em; text-transform: uppercase; color: var(--signal); }
        .sgb-title { margin: 5px 0 3px; font-size: 17px; font-weight: 700; color: var(--text); letter-spacing: -0.02em; }
        .sgb-aware { color: var(--signal); }
        .sgb-plant .sgb-aware { color: var(--plant); }
        .sgb-market { font-size: 12px; color: var(--text-dim); }
        .sgb-cycle { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 11px 16px; background: rgba(0,0,0,0.18); border-bottom: 1px solid var(--border); }
        .sgb-cnode { display: inline-flex; flex-direction: column; font-family: var(--font-mono); font-size: 12px; font-weight: 700; color: var(--text); padding: 4px 10px; border: 1px solid var(--border-strong); border-radius: 4px; }
        .sgb-cnode small { font-size: 9px; font-weight: 400; color: var(--text-mute); }
        .sgb-da { border-color: var(--signal); color: var(--signal); }
        .sgb-carrow { color: var(--text-mute); font-family: var(--font-mono); }
        .sgb-cloop { margin-left: auto; font-size: 11px; color: var(--signal); font-weight: 600; }
        .sgb-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1px; background: var(--border); }
        @media (max-width: 680px) { .sgb-grid { grid-template-columns: 1fr; } }
        .sgb-cell { background: var(--ink-050, oklch(0.11 0.015 240)); padding: 9px 14px; font-size: 11.5px; color: var(--text-dim); line-height: 1.45; }
        .sgb-goal b { color: var(--text); }
        .sgb-l { display: block; font-family: var(--font-mono); font-size: 9px; color: var(--text-mute); letter-spacing: .03em; margin-bottom: 3px; text-transform: uppercase; }
        .sgb-recos { display: flex; flex-wrap: wrap; gap: 14px; padding: 12px 16px; border-bottom: 1px solid var(--border); }
        .sgb-reco { flex: 1 1 200px; }
        .sgb-chips { display: flex; flex-wrap: wrap; gap: 5px; }
        .sgb-chip { font-family: var(--font-mono); font-size: 10px; padding: 2px 8px; border-radius: 3px; border: 1px solid var(--border-strong); color: var(--text-dim); }
        .sgb-chip-mix { color: var(--cyan); border-color: var(--cyan-dim); }
        .sgb-why { font-size: 10.5px; color: var(--text-mute); margin-top: 5px; line-height: 1.5; }
        .sgb-budget { font-family: var(--font-mono); font-size: 13px; color: var(--signal); font-weight: 700; }
        .sgb-budget em { font-style: normal; color: var(--text-mute); font-size: 11px; font-weight: 400; }
        .sgb-bridge { padding: 12px 16px; border-bottom: 1px solid var(--border); }
        .sgb-bridge-cols { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-top: 7px; }
        @media (max-width: 680px) { .sgb-bridge-cols { grid-template-columns: 1fr; } }
        .sgb-bcol { padding: 9px 10px; background: rgba(0,0,0,0.2); border: 1px solid var(--border); border-radius: 4px; }
        .sgb-bcol-h { display: flex; justify-content: space-between; align-items: center; gap: 6px; }
        .sgb-bcol-h strong { font-size: 12px; color: var(--text); }
        .sgb-min { font-family: var(--font-mono); font-size: 9px; padding: 1px 5px; border-radius: 3px; }
        .sgb-min.ok { color: var(--plant); border: 1px solid var(--plant); }
        .sgb-min.no { color: var(--alert); border: 1px solid var(--alert); }
        .sgb-axis { font-size: 10px; color: var(--text-mute); margin: 3px 0 5px; }
        .sgb-bkws { display: flex; flex-wrap: wrap; gap: 3px; }
        .sgb-bkws span { font-family: var(--font-mono); font-size: 9.5px; padding: 1px 5px; background: var(--ink-100); border: 1px solid var(--border-strong); border-radius: 3px; color: var(--text-dim); }
        .sgb-bnote { font-size: 10px; color: var(--text-mute); margin-top: 5px; line-height: 1.4; }
        .sgb-align { padding: 12px 16px; }
        .sgb-align-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 7px; }
        .sgb-ac { display: flex; align-items: center; gap: 5px; flex-wrap: wrap; }
        .sgb-ac-l { font-family: var(--font-mono); font-size: 9px; color: var(--text-mute); }
        .sgb-atag { font-size: 10.5px; padding: 2px 8px; border-radius: 3px; }
        .sgb-pain { background: oklch(0.68 0.21 22 / 0.12); border: 1px solid oklch(0.68 0.21 22 / 0.3); color: oklch(0.74 0.16 22); }
        .sgb-usp { background: var(--plant-soft); border: 1px solid var(--plant); color: var(--plant); }
      `}</style>
    </div>
  );
}

function SACreative({ brand }) {
  const [stage, setStage] = useSAState('ready');
  const guide = window.SAEngine ? window.SAEngine.creativeGuide(brand) : null;
  if (!guide) return null;
  const g = guide[stage];
  const stages = [{ id: 'info', label: '정보탐색' }, { id: 'compare', label: '비교' }, { id: 'ready', label: '구매임박' }];
  return (
    <div className="sac">
      <div className="sac-head">
        <span className="sa-mini">소재 가이드 — 검색의도 단계별 제목·설명·확장소재</span>
        <div className="sac-seg">
          {stages.map(s => <button key={s.id} data-on={stage === s.id} onClick={() => setStage(s.id)}>{s.label}</button>)}
        </div>
      </div>
      <div className="sac-cols">
        <div className="sac-col"><span className="sac-l">제목(T)</span>{g.title.map((t, i) => <div key={i} className="sac-item">{t}</div>)}</div>
        <div className="sac-col"><span className="sac-l">설명(D)</span>{g.desc.map((t, i) => <div key={i} className="sac-item">{t}</div>)}</div>
        <div className="sac-col"><span className="sac-l">확장소재</span>{g.ext.map((t, i) => <div key={i} className="sac-item">{t}</div>)}</div>
      </div>
      <style>{`
        .sac { padding: 11px 12px; background: oklch(0.10 0.02 240 / 0.5); border: 1px solid var(--border); }
        .sac-head { display: flex; justify-content: space-between; align-items: center; gap: 10px; margin-bottom: 8px; flex-wrap: wrap; }
        .sac-seg { display: flex; }
        .sac-seg button { padding: 4px 10px; background: oklch(0.10 0.02 240); border: 1px solid var(--border-strong); color: var(--text-dim); font-size: 10.5px; cursor: pointer; font-family: var(--font-sans); }
        .sac-seg button + button { border-left: none; }
        .sac-seg button[data-on="true"] { background: var(--cyan); color: var(--ink-000); border-color: var(--cyan); font-weight: 600; }
        .sac-cols { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 8px; }
        @media (max-width: 680px) { .sac-cols { grid-template-columns: 1fr; } }
        .sac-col { display: flex; flex-direction: column; gap: 4px; }
        .sac-l { font-family: var(--font-mono); font-size: 9px; color: var(--cyan); }
        .sac-item { font-size: 11px; color: var(--text-dim); padding: 5px 8px; background: rgba(0,0,0,0.22); border: 1px solid var(--border-strong); border-radius: 4px; line-height: 1.4; }
      `}</style>
    </div>
  );
}

Object.assign(window, { SAMatrix, StrategyBridge, SACreative });
