/* MeasuredProfilePanel — 브랜드 1st-party 실측 데이터 패널
   추정(카테고리)이 아닌 측정값임을 명확히 표시하고, 성별×연령 결합(그물망),
   재구매, 카테고리 매출, 시간대·요일·시즌성, 베스트셀러를 한 화면에 시각화.
   props: { profile }  // window.BrandProfiles.match() 결과
*/
const { useMemo: useMPMemo } = React;

function MeasuredProfilePanel({ profile }) {
  if (!profile) return null;
  const BP = window.BrandProfiles;
  const eco = profile.economics || {};
  const rep = profile.repurchase || {};
  const won = n => '₩' + Math.round(n).toLocaleString();
  const grid = BP.genderAgeGrid(profile);          // null 이면 결합분포 미제공
  const ageBars = BP.ageBars(profile);
  const seasonIdx = profile.seasonality ? BP.seasonalityIndex(profile) : [];
  const hasHourly = Array.isArray(profile.hourly) && profile.hourly.length === 24;
  const catEntries = profile.catMix ? Object.entries(profile.catMix).slice(0, 6) : [];
  const chEntries = profile.channelMix ? Object.entries(profile.channelMix).sort((a, b) => b[1] - a[1]) : [];

  // KPI 스트립 — 존재하는 값만
  const kpis = [];
  if (eco.gmv) kpis.push(['총 매출', won(eco.gmv)]);
  else if (eco.gmv2025) kpis.push(['2025 매출', won(eco.gmv2025)]);
  if (eco.gmvYoYPct != null) kpis.push(['전년比 YoY', '+' + eco.gmvYoYPct + '%']);
  if (eco.aov) kpis.push(['객단가 AOV', won(eco.aov)]);
  if (eco.orders) kpis.push(['결제 건수', eco.orders.toLocaleString() + '건']);
  if (eco.convRatePct != null) kpis.push(['구매 전환율', eco.convRatePct + '%']);
  if (rep.monthlyRatePct != null) kpis.push(['월 재구매율', rep.monthlyRatePct + '%']);
  if (rep.existingRatioPct != null) kpis.push(['기존고객 비율', rep.existingRatioPct + '%']);
  if (eco.refundRatePct != null) kpis.push(['환불률', eco.refundRatePct + '%']);
  if (profile.device && profile.device.mobile != null) kpis.push(['모바일 비중', profile.device.mobile + '%']);

  const maxCell = grid ? Math.max(...grid.female, ...grid.male, 0.1) : 1;
  const cellBg = (v, hue) => 'oklch(0.62 0.13 ' + hue + ' / ' + (v / maxCell * 0.92 + 0.05).toFixed(3) + ')';
  const maxAge = ageBars.length ? Math.max(...ageBars.map(a => a.pct)) : 1;
  const maxCat = catEntries.length ? Math.max(...catEntries.map(c => c[1])) : 1;
  const maxCh = chEntries.length ? Math.max(...chEntries.map(c => c[1])) : 1;
  const fem = profile.gender ? (profile.gender['여성'] || 0) : null;
  const mal = profile.gender ? (profile.gender['남성'] || 0) : null;

  const maxHour = hasHourly ? Math.max(...profile.hourly) : 1;
  const peakHour = hasHourly ? profile.hourly.indexOf(maxHour) : 0;
  const dowEntries = profile.dow ? Object.entries(profile.dow) : [];
  const maxDow = dowEntries.length ? Math.max(...dowEntries.map(d => d[1])) : 1;
  const maxSeason = seasonIdx.length ? Math.max(...seasonIdx, 100) : 100;
  const trend = profile.gmvTrend;
  const maxTrend = trend ? Math.max(...trend.billionWon) : 1;

  return (
    <div className="mtp">
      <div className="mtp-head">
        <div className="mtp-title">
          <span className="mtp-dot" />
          실측 데이터 연동 — {profile.meta.brand}
          <span className="mtp-tier">tier {profile.meta.tier} · 1st-party{profile.meta.dataShape === 'summary' ? ' · 집계' : ''}</span>
        </div>
        <div className="mtp-src">{profile.meta.sourceLabel} · {profile.meta.period}</div>
      </div>
      <div className="mtp-note">{profile.meta.note}</div>

      {kpis.length > 0 && (
        <div className="mtp-kpis">
          {kpis.map(([k, v]) => <div key={k} className="mtp-kpi"><span>{k}</span><strong>{v}</strong></div>)}
        </div>
      )}

      <div className="mtp-grid2">
        {/* 데모: 결합분포 있으면 히트맵, 없으면 연령막대 + 성별 split */}
        <div className="mtp-card">
          {grid ? (
            <React.Fragment>
              <div className="mtp-card-h">성별 × 연령 결합 분포 <span className="mtp-mute">실측 결제 비중(%)</span></div>
              <div className="mtp-heat">
                <div className="mtp-heat-row mtp-heat-axis">
                  <span className="mtp-heat-lbl" />
                  {grid.ages.map(a => <span key={a} className="mtp-heat-col">{a.replace('~', '–')}</span>)}
                </div>
                <div className="mtp-heat-row">
                  <span className="mtp-heat-lbl">여성</span>
                  {grid.female.map((v, i) => <span key={i} className="mtp-heat-cell" style={{ background: cellBg(v, 12) }} title={'여성 ' + grid.ages[i] + ' · ' + v + '%'}>{v >= 4 ? v : ''}</span>)}
                </div>
                <div className="mtp-heat-row">
                  <span className="mtp-heat-lbl">남성</span>
                  {grid.male.map((v, i) => <span key={i} className="mtp-heat-cell" style={{ background: cellBg(v, 230) }} title={'남성 ' + grid.ages[i] + ' · ' + v + '%'}>{v >= 4 ? v : ''}</span>)}
                </div>
              </div>
              <div className="mtp-cells">핵심 셀: {BP.topCells(profile, 3).map(c => <span key={c.label} className="mtp-chip">{c.label} {c.pct}%</span>)}</div>
            </React.Fragment>
          ) : (
            <React.Fragment>
              <div className="mtp-card-h">연령 분포 <span className="mtp-mute">실측 결제 비중(%){ageBars.some(a => a.aov) ? ' · 객단가' : ''}</span></div>
              {fem != null && (
                <div className="mtp-gsplit">
                  <span className="mtp-gseg mtp-gseg-f" style={{ width: fem + '%' }}>여 {fem}%</span>
                  <span className="mtp-gseg mtp-gseg-m" style={{ width: mal + '%' }}>남 {mal}%</span>
                </div>
              )}
              <div className="mtp-bars">
                {ageBars.map(a => (
                  <div key={a.label} className="mtp-bar-row">
                    <span className="mtp-bar-lbl">{a.label}</span>
                    <span className="mtp-bar-track"><span className="mtp-bar-fill" style={{ width: (a.pct / maxAge * 100) + '%' }} /></span>
                    <span className="mtp-bar-val">{a.pct}%{a.aov ? ' · ₩' + (a.aov / 1000).toFixed(0) + 'k' : ''}</span>
                  </div>
                ))}
              </div>
            </React.Fragment>
          )}
        </div>

        {/* 카테고리 + (베스트셀러 또는 유입채널) */}
        <div className="mtp-card">
          <div className="mtp-card-h">카테고리 매출 비중 <span className="mtp-mute">실측</span></div>
          <div className="mtp-bars">
            {catEntries.map(([k, v]) => (
              <div key={k} className="mtp-bar-row">
                <span className="mtp-bar-lbl">{k}</span>
                <span className="mtp-bar-track"><span className="mtp-bar-fill" style={{ width: (v / maxCat * 100) + '%' }} /></span>
                <span className="mtp-bar-val">{v}%</span>
              </div>
            ))}
          </div>
          {profile.topProducts ? (
            <React.Fragment>
              <div className="mtp-card-h" style={{ marginTop: 12 }}>베스트셀러</div>
              <ol className="mtp-prod">
                {profile.topProducts.slice(0, 4).map((p, i) => <li key={i}><span className="mtp-prod-n">{p.name}</span><span className="mtp-prod-v">{p.revShare}%</span></li>)}
              </ol>
            </React.Fragment>
          ) : chEntries.length > 0 ? (
            <React.Fragment>
              <div className="mtp-card-h" style={{ marginTop: 12 }}>유입 채널 <span className="mtp-mute">평균 비중</span></div>
              <div className="mtp-bars">
                {chEntries.map(([k, v]) => (
                  <div key={k} className="mtp-bar-row">
                    <span className="mtp-bar-lbl">{k}</span>
                    <span className="mtp-bar-track"><span className="mtp-bar-fill mtp-bar-fill-ch" style={{ width: (v / maxCh * 100) + '%' }} /></span>
                    <span className="mtp-bar-val">{v}%</span>
                  </div>
                ))}
              </div>
            </React.Fragment>
          ) : null}
        </div>
      </div>

      <div className="mtp-grid2">
        {/* 시간대(있으면) / 없으면 유입채널이 위에 안 쓰였을 때 */}
        {hasHourly && (
          <div className="mtp-card">
            <div className="mtp-card-h">시간대 결제 강도 <span className="mtp-mute">피크 {String(peakHour).padStart(2, '0')}시</span></div>
            <div className="mtp-hours">
              {profile.hourly.map((v, i) => (
                <span key={i} className="mtp-hour" title={i + '시 · ' + v + '%'}>
                  <span className="mtp-hour-fill" style={{ height: (v / maxHour * 100) + '%', background: i === peakHour ? 'var(--signal)' : 'var(--cyan-dim)' }} />
                  {i % 6 === 0 && <span className="mtp-hour-tick">{i}</span>}
                </span>
              ))}
            </div>
            {dowEntries.length > 0 && (
              <div className="mtp-dow">
                {dowEntries.map(([d, v]) => (
                  <span key={d} className="mtp-dow-cell">
                    <span className="mtp-dow-bar" style={{ height: (v / maxDow * 34) + 'px', background: v === maxDow ? 'var(--signal)' : 'var(--ink-400)' }} />
                    <span className="mtp-dow-lbl">{d}</span>
                  </span>
                ))}
              </div>
            )}
          </div>
        )}

        {/* 시즌성(월매출) 또는 GMV 추이 + 재구매 */}
        <div className="mtp-card">
          {seasonIdx.length > 0 ? (
            <React.Fragment>
              <div className="mtp-card-h">월별 매출 지수 <span className="mtp-mute">100 = 평균</span></div>
              <div className="mtp-season">
                {seasonIdx.map((v, i) => (
                  <span key={i} className="mtp-season-col">
                    <span className="mtp-season-val">{v}</span>
                    <span className="mtp-season-bar" style={{ height: (v / maxSeason * 90) + 'px', background: v >= 120 ? 'var(--signal)' : 'var(--cyan-dim)' }} />
                    <span className="mtp-season-lbl">{(profile.seasonality.months[i] || '').slice(2)}</span>
                  </span>
                ))}
              </div>
            </React.Fragment>
          ) : trend ? (
            <React.Fragment>
              <div className="mtp-card-h">GMV 추이 <span className="mtp-mute">억원</span></div>
              <div className="mtp-season">
                {trend.billionWon.map((v, i) => (
                  <span key={i} className="mtp-season-col">
                    <span className="mtp-season-val">{v}</span>
                    <span className="mtp-season-bar" style={{ height: (v / maxTrend * 90) + 'px', background: i === 1 ? 'var(--signal)' : 'var(--cyan-dim)' }} />
                    <span className="mtp-season-lbl">{trend.labels[i]}</span>
                  </span>
                ))}
              </div>
            </React.Fragment>
          ) : null}
          {(rep.d30 != null || Array.isArray(rep.monthly)) && (
            <div className="mtp-repeat">
              <span className="mtp-mute">{rep.d30 != null ? '재구매율 30 / 90 / 180일 (%)' : '월별 재구매율(%)'}</span>
              <div className="mtp-repeat-row">
                {(rep.d30 != null ? [rep.d30, rep.d90, rep.d180] : rep.monthly).map((v, i) => (
                  <span key={i} className="mtp-repeat-cell"><span className="mtp-repeat-bar" style={{ height: (v / Math.max(rep.d30 != null ? rep.d180 : Math.max(...rep.monthly), 1) * 28) + 'px' }} />{v}{rep.d30 != null ? (['·30d', '·90d', '·180d'][i]) : ''}</span>
                ))}
              </div>
            </div>
          )}
        </div>
      </div>

      <style>{`
        .mtp { border: 1px solid var(--border-strong); border-radius: 12px; background: linear-gradient(180deg, var(--signal-soft), transparent 60%), var(--surface); padding: 16px 18px; margin-bottom: 18px; }
        .mtp-head { display: flex; justify-content: space-between; align-items: baseline; flex-wrap: wrap; gap: 6px; }
        .mtp-title { display: flex; align-items: center; gap: 8px; font-size: 15px; font-weight: 700; color: var(--text); }
        .mtp-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--signal); box-shadow: 0 0 8px var(--signal); }
        .mtp-tier { font-family: var(--font-mono); font-size: 10px; font-weight: 600; color: var(--signal); border: 1px solid var(--signal-dim); border-radius: 999px; padding: 2px 8px; letter-spacing: 0.02em; }
        .mtp-src { font-family: var(--font-mono); font-size: 11px; color: var(--text-mute); }
        .mtp-note { font-size: 12px; color: var(--text-dim); margin: 8px 0 14px; line-height: 1.5; }
        .mtp-mute { font-family: var(--font-mono); font-size: 10px; color: var(--text-mute); font-weight: 400; }
        .mtp-kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(110px, 1fr)); gap: 1px; background: var(--border); border: 1px solid var(--border); border-radius: 8px; overflow: hidden; margin-bottom: 14px; }
        .mtp-kpi { background: var(--ink-100); padding: 9px 11px; display: flex; flex-direction: column; gap: 3px; }
        .mtp-kpi span { font-size: 10px; color: var(--text-mute); }
        .mtp-kpi strong { font-size: 15px; color: var(--text); font-family: var(--font-mono); }
        .mtp-grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 12px; }
        @media (max-width: 720px) { .mtp-grid2 { grid-template-columns: 1fr; } }
        .mtp-card { border: 1px solid var(--border); border-radius: 9px; background: var(--ink-050); padding: 12px 13px; }
        .mtp-card-h { font-size: 12px; font-weight: 700; color: var(--text); margin-bottom: 9px; display: flex; justify-content: space-between; align-items: baseline; }
        .mtp-heat { display: flex; flex-direction: column; gap: 3px; }
        .mtp-heat-row { display: grid; grid-template-columns: 34px repeat(9, 1fr); gap: 3px; align-items: center; }
        .mtp-heat-axis .mtp-heat-col { font-size: 8.5px; color: var(--text-mute); text-align: center; font-family: var(--font-mono); }
        .mtp-heat-lbl { font-size: 11px; color: var(--text-dim); }
        .mtp-heat-cell { height: 26px; border-radius: 3px; display: flex; align-items: center; justify-content: center; font-size: 9.5px; font-family: var(--font-mono); color: var(--bone-100); }
        .mtp-cells { margin-top: 9px; font-size: 10px; color: var(--text-mute); display: flex; flex-wrap: wrap; gap: 5px; align-items: center; }
        .mtp-chip { background: var(--signal-soft); color: var(--signal); border-radius: 999px; padding: 2px 8px; font-family: var(--font-mono); font-size: 10px; }
        .mtp-gsplit { display: flex; height: 22px; border-radius: 6px; overflow: hidden; margin-bottom: 10px; font-size: 10px; font-family: var(--font-mono); }
        .mtp-gseg { display: flex; align-items: center; justify-content: center; color: var(--ink-000); white-space: nowrap; }
        .mtp-gseg-f { background: oklch(0.70 0.13 12); }
        .mtp-gseg-m { background: oklch(0.70 0.10 230); }
        .mtp-bars { display: flex; flex-direction: column; gap: 6px; }
        .mtp-bar-row { display: grid; grid-template-columns: 92px 1fr 78px; gap: 8px; align-items: center; }
        .mtp-bar-lbl { font-size: 11px; color: var(--text-dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
        .mtp-bar-track { height: 8px; background: var(--ink-200); border-radius: 999px; overflow: hidden; }
        .mtp-bar-fill { display: block; height: 100%; background: linear-gradient(90deg, var(--cyan-dim), var(--cyan)); border-radius: 999px; }
        .mtp-bar-fill-ch { background: linear-gradient(90deg, var(--signal-dim), var(--signal)); }
        .mtp-bar-val { font-family: var(--font-mono); font-size: 11px; color: var(--text); text-align: right; }
        .mtp-prod { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 5px; }
        .mtp-prod li { display: flex; justify-content: space-between; gap: 8px; font-size: 11px; color: var(--text-dim); }
        .mtp-prod-n { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
        .mtp-prod-v { font-family: var(--font-mono); color: var(--signal); flex-shrink: 0; }
        .mtp-hours { display: flex; align-items: flex-end; gap: 2px; height: 70px; padding-bottom: 14px; position: relative; }
        .mtp-hour { flex: 1; height: 100%; display: flex; align-items: flex-end; position: relative; }
        .mtp-hour-fill { width: 100%; border-radius: 2px 2px 0 0; min-height: 2px; }
        .mtp-hour-tick { position: absolute; bottom: -14px; left: 0; font-size: 8px; color: var(--text-mute); font-family: var(--font-mono); }
        .mtp-dow { display: flex; gap: 6px; margin-top: 12px; align-items: flex-end; justify-content: space-between; }
        .mtp-dow-cell { display: flex; flex-direction: column; align-items: center; gap: 3px; flex: 1; }
        .mtp-dow-bar { width: 60%; border-radius: 2px; min-height: 3px; }
        .mtp-dow-lbl { font-size: 10px; color: var(--text-mute); }
        .mtp-season { display: flex; gap: 7px; align-items: flex-end; height: 118px; }
        .mtp-season-col { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; gap: 3px; }
        .mtp-season-val { font-size: 10px; font-family: var(--font-mono); color: var(--text-dim); }
        .mtp-season-bar { width: 70%; border-radius: 3px 3px 0 0; min-height: 3px; }
        .mtp-season-lbl { font-size: 9px; color: var(--text-mute); font-family: var(--font-mono); }
        .mtp-repeat { margin-top: 12px; }
        .mtp-repeat-row { display: flex; gap: 5px; align-items: flex-end; margin-top: 5px; }
        .mtp-repeat-cell { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 2px; font-size: 9px; font-family: var(--font-mono); color: var(--text-mute); }
        .mtp-repeat-bar { width: 60%; background: var(--plant); border-radius: 2px; min-height: 2px; }
      `}</style>
    </div>
  );
}

Object.assign(window, { MeasuredProfilePanel });

/* ReferencePriorPanel — 표본 "참고 추정"(tier C) 패널.
   실측이 아니라 동일/유사 카테고리 표본을 렌즈로 쓴 추정임을 명확히 구분.
   override가 아니라 "접근 도구"라는 점을 시각·문구로 강조.
   props: { reference }  // window.BrandProfiles.reference() 결과
*/
function ReferencePriorPanel({ reference }) {
  if (!reference) return null;
  const r = reference;
  const pct = v => (v * 100).toFixed(1) + '%';
  const won = n => '₩' + Math.round(n).toLocaleString();
  const ageTop = Object.entries(r.ageRaw || {}).sort((a, b) => b[1] - a[1]).slice(0, 3).map(x => x[0]).join(', ');
  return (
    <div className="rpp">
      <div className="rpp-head">
        <div className="rpp-title">
          <span className="rpp-icon">◇</span>
          표본 참고 추정 — {r.forBrand || '신규 브랜드'}
          <span className="rpp-tier">tier {r.tier} · prior</span>
        </div>
        <div className="rpp-conf">신뢰도 {r.confidence}<span>/100</span></div>
      </div>
      <div className="rpp-caution">⚠ {r.caution}</div>
      <div className="rpp-srcline">
        참고 표본: {r.sampleBrands.map(b => <span key={b} className="rpp-chip">{b}</span>)} · 카테고리 {r.category}
      </div>
      <div className="rpp-grid">
        <div className="rpp-cell"><span>여성 비중(prior)</span><strong>{r.femaleSkew != null ? pct(r.femaleSkew) : '—'}</strong>{r.femaleSkewStd != null && <em>±{pct(r.femaleSkewStd)}</em>}</div>
        <div className="rpp-cell"><span>AOV(prior)</span><strong>{r.aov != null ? won(r.aov) : '—'}</strong>{r.aovStd != null && <em>±{won(r.aovStd)}</em>}</div>
        <div className="rpp-cell"><span>월 재구매율(prior)</span><strong>{r.repurchasePct != null ? r.repurchasePct + '%' : '—'}</strong>{r.repurchaseStd != null && <em>±{r.repurchaseStd}%</em>}</div>
        <div className="rpp-cell"><span>모바일 비중(prior)</span><strong>{r.mobilePct != null ? r.mobilePct + '%' : '미제공'}</strong></div>
        <div className="rpp-cell"><span>참고 핵심 연령</span><strong>{ageTop}</strong></div>
      </div>
      <div className="rpp-foot">이 값은 표본을 렌즈로 한 <b>출발 추정치</b>일 뿐, 이 브랜드의 측정값이 아닙니다. 실데이터를 적재하면 tier-A 실측으로 확정됩니다.</div>
      <style>{`
        .rpp { border: 1px dashed var(--cyan-dim); border-radius: 12px; background: linear-gradient(180deg, var(--cyan-soft), transparent 55%), var(--surface); padding: 15px 17px; margin-bottom: 18px; }
        .rpp-head { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 6px; }
        .rpp-title { display: flex; align-items: center; gap: 8px; font-size: 14px; font-weight: 700; color: var(--text); }
        .rpp-icon { color: var(--cyan); font-size: 13px; }
        .rpp-tier { font-family: var(--font-mono); font-size: 10px; font-weight: 600; color: var(--cyan); border: 1px solid var(--cyan-dim); border-radius: 999px; padding: 2px 8px; }
        .rpp-conf { font-family: var(--font-mono); font-size: 12px; color: var(--cyan); }
        .rpp-conf span { color: var(--text-mute); font-size: 10px; }
        .rpp-caution { font-size: 11.5px; color: var(--text-dim); background: var(--cyan-soft); border-left: 2px solid var(--cyan-dim); padding: 7px 10px; border-radius: 0 6px 6px 0; margin: 10px 0; line-height: 1.5; }
        .rpp-srcline { font-size: 11px; color: var(--text-mute); display: flex; flex-wrap: wrap; gap: 5px; align-items: center; margin-bottom: 11px; }
        .rpp-chip { background: var(--cyan-soft); color: var(--cyan); border-radius: 999px; padding: 2px 8px; font-family: var(--font-mono); font-size: 10px; }
        .rpp-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 1px; background: var(--border); border: 1px solid var(--border); border-radius: 8px; overflow: hidden; }
        .rpp-cell { background: var(--ink-100); padding: 9px 11px; display: flex; flex-direction: column; gap: 2px; }
        .rpp-cell span { font-size: 10px; color: var(--text-mute); }
        .rpp-cell strong { font-size: 14px; color: var(--text); font-family: var(--font-mono); }
        .rpp-cell em { font-style: normal; font-size: 10px; color: var(--cyan-dim); font-family: var(--font-mono); }
        .rpp-foot { font-size: 11px; color: var(--text-mute); margin-top: 11px; line-height: 1.5; }
        .rpp-foot b { color: var(--text-dim); }
      `}</style>
    </div>
  );
}

Object.assign(window, { ReferencePriorPanel });

/* BrandMetaLens — 공식몰 제품 메타(tier-B) 렌즈 패널.
   성/연령 실측이 아직 없는 브랜드(예: 샥즈)에 라인업·가격·경쟁사·시그니처를 보여준다.
   "실측"이 아니라 "공식몰 메타 — 스토어 통계 수신 시 tier-A 승격"임을 명확히 표기(거짓 정밀 금지).
   props: { meta }  // analysis.brandMetaProfile (BrandProfiles 프로파일, dataShape:'meta-only')
*/
function BrandMetaLens({ meta }) {
  if (!meta) return null;
  const m = meta;
  const won = n => '₩' + (+n).toLocaleString();
  const lineup = m.lineup || [];
  const kws = m.signatureKeywords || [];
  const comps = m.competitors || [];
  return (
    <div className="bml">
      <div className="bml-head">
        <div>
          <div className="bml-eyebrow">공식몰 제품 메타 · tier-B 렌즈</div>
          <h3 className="bml-title">{m.meta.brand} <span className="bml-cat">{m.meta.categoryLabel}</span></h3>
        </div>
        <span className="bml-pending">스토어 통계 수신 시 tier-A 승격</span>
      </div>
      <div className="bml-note">{m.meta.note}</div>
      <div className="bml-grid">
        {lineup.length > 0 && (
          <div className="bml-col">
            <span className="bml-l">제품 라인업 (공식몰 실가격)</span>
            <ul className="bml-lineup">
              {lineup.map((p, i) => <li key={i}><span>{p.name}</span><em>{won(p.price)}</em></li>)}
            </ul>
            {m.priceMedian && <div className="bml-pm">중앙값 {won(m.priceMedian)}{m.priceRange && <span> · {won(m.priceRange.min)}~{won(m.priceRange.max)}</span>}</div>}
          </div>
        )}
        <div className="bml-col">
          {kws.length > 0 && (<>
            <span className="bml-l">시그니처 키워드</span>
            <div className="bml-chips">{kws.map((k, i) => <span key={i} className="bml-kw">{k}</span>)}</div>
          </>)}
          {comps.length > 0 && (<>
            <span className="bml-l" style={{ marginTop: 10 }}>경쟁군</span>
            <div className="bml-chips">{comps.map((c, i) => <span key={i} className="bml-comp">{c}</span>)}</div>
          </>)}
        </div>
      </div>
      <div className="bml-foot">
        <b>※ 공식몰 크롤링(tier-B)</b> — 제품·가격·포지셔닝 렌즈입니다. 성·연령·재구매·GMV 등 <b>구매자 실측은 미적재</b>(추정 안 함).
        스마트스토어 판매자센터 통계를 적재하면 실측(tier-A)으로 승격되어 페르소나가 측정값으로 치환됩니다.
      </div>
      <style>{`
        .bml { margin: 16px 0 6px; border: 1px solid var(--border-strong); border-radius: 6px; overflow: hidden; background: radial-gradient(120% 80% at 100% 0%, var(--cyan-soft), transparent 60%), var(--ink-100, oklch(0.13 0.02 240)); border-left: 3px solid var(--cyan); }
        .bml-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; padding: 14px 16px 10px; border-bottom: 1px solid var(--border); flex-wrap: wrap; }
        .bml-eyebrow { font-family: var(--font-mono); font-size: 10px; letter-spacing: .12em; text-transform: uppercase; color: var(--cyan); }
        .bml-title { margin: 5px 0 0; font-size: 16px; font-weight: 700; color: var(--text); letter-spacing: -0.02em; }
        .bml-cat { font-size: 11px; font-weight: 400; color: var(--text-mute); font-family: var(--font-mono); margin-left: 6px; }
        .bml-pending { flex-shrink: 0; font-family: var(--font-mono); font-size: 9.5px; padding: 3px 8px; border-radius: 3px; color: var(--signal); border: 1px solid var(--signal-dim); }
        .bml-note { padding: 9px 16px; font-size: 11.5px; color: var(--text-dim); line-height: 1.5; border-bottom: 1px solid var(--border); }
        .bml-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1px; background: var(--border); }
        @media (max-width: 680px) { .bml-grid { grid-template-columns: 1fr; } }
        .bml-col { background: var(--ink-050, oklch(0.11 0.015 240)); padding: 11px 14px; }
        .bml-l { display: block; font-family: var(--font-mono); font-size: 9px; color: var(--text-mute); letter-spacing: .03em; text-transform: uppercase; margin-bottom: 6px; }
        .bml-lineup { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
        .bml-lineup li { display: flex; justify-content: space-between; gap: 8px; font-size: 12px; color: var(--text-dim); }
        .bml-lineup em { font-style: normal; font-family: var(--font-mono); color: var(--text); }
        .bml-pm { margin-top: 7px; font-family: var(--font-mono); font-size: 11px; color: var(--cyan); }
        .bml-chips { display: flex; flex-wrap: wrap; gap: 4px; }
        .bml-kw { font-family: var(--font-mono); font-size: 10px; padding: 2px 7px; border-radius: 3px; background: var(--cyan-soft); border: 1px solid var(--cyan-dim); color: var(--cyan); }
        .bml-comp { font-family: var(--font-mono); font-size: 10px; padding: 2px 7px; border-radius: 3px; border: 1px solid var(--border-strong); color: var(--text-dim); }
        .bml-foot { padding: 10px 16px; font-size: 11px; color: var(--text-mute); line-height: 1.55; border-top: 1px solid var(--border); }
        .bml-foot b { color: var(--text-dim); }
      `}</style>
    </div>
  );
}

Object.assign(window, { BrandMetaLens });
