/* --- Dynamic overrides: selected law/case now propagates across all modules --- */
const { useState: useStateO } = React;

function severityBadge(c){
  return <Badge tone={RSData.syncSeverityTone(c.severity)} size="sm">{RSData.syncSeverityLabel(c.severity)}</Badge>;
}

function CaseMetric({l, v, s, tone}){
  return (
    <div style={{padding:'12px 14px', background:'#F8FAFC', borderRadius:8}}>
      <div style={{fontSize:11, color:'var(--ink-3)'}}>{l}</div>
      <div style={{display:'flex', alignItems:'baseline', gap:4, marginTop:6}}>
        <span className="mono" style={{fontSize:22, fontWeight:700, color:tone}}>{v}</span>
        <span style={{fontSize:11, color:'var(--ink-4)'}}>{s}</span>
      </div>
    </div>
  );
}

const A_GRADE_LEGEND =
  'A등급 = 4개 검증조건 전부 통과 / B등급 = 3개 통과 / C등급 = 2개 통과 / D등급 = 1개 이하\n' +
  '4개 검증조건: ① 같은 규율대상 ② 같은 행위 또는 절차 ③ 같은 단위와 산식 ④ 직접 상위근거';

const CASE_SOURCE_META = {
  '1975961': {
    url: `https://www.law.go.kr/자치법규/${encodeURIComponent('구미시의회 행정사무감사·조사 시 불출석·증언거부 증인에 대한 과태료 부과·징수 조례')}`,
    checkedAt: '2026-05-18'
  },
  '1858093': {
    url: `https://www.law.go.kr/자치법규/${encodeURIComponent('대구광역시 군위군 지역보건법 위반 과태료 부과 징수 조례')}`,
    checkedAt: '2026-05-18'
  },
  '1672527': {
    url: `https://www.law.go.kr/자치법규/${encodeURIComponent('충청남도 건축 조례')}`,
    checkedAt: '2026-05-18'
  }
};

function gradeLegendIcon(){
  return (
    <span
      title={A_GRADE_LEGEND}
      aria-label="A등급 판정 기준"
      style={{
        display:'inline-flex',
        alignItems:'center',
        justifyContent:'center',
        width:16,
        height:16,
        marginLeft:4,
        borderRadius:999,
        border:'1px solid #A7D8CF',
        color:'#155F53',
        background:'#F0FBF8',
        fontSize:10,
        fontWeight:800,
        cursor:'help',
        verticalAlign:'middle'
      }}
    >
      ⓘ
    </span>
  );
}

function aiFirstClassification(review){
  const title = `${review?.title || ''} ${review?.agency || ''}`;
  if (title.includes('구미시의회') || title.includes('군위군')) {
    return {
      label: '절차적 비동기화 추정',
      text: '상위법(질서위반행위규제법 제20조제1항)은 모든 과태료에 적용되는 일반법 조항입니다. 조례에서 60일을 30일로 단축할 정책적 근거가 본문에 명시되어 있지 않아, 상위법 개정·정비 시점의 미반영 가능성이 높습니다.',
      tone: '#1F7A6B'
    };
  }
  if (title.includes('충청남도 건축 조례')) {
    return {
      label: '인용 조항 불일치 추정',
      text: '조례가 명시 인용한 항(제1항·제3항)과 실제 기한값(15일)이 위치한 항(제4항)이 불일치합니다. 또한 상위법 제4항은 재심의에 한정된 규정이나, 조례는 심의·재심의를 묶어 30일로 처리하고 있어 조문 인용 구조 정비 가능성을 확인해야 합니다.',
      tone: '#C77A1B'
    };
  }
  return null;
}

function repeatedPatternMeta(review){
  const title = `${review?.title || ''} ${review?.agency || ''}`;
  return title.includes('구미시의회') || title.includes('군위군')
    ? '📌 동일 패턴 반복 탐지 시연 - 시·군 간 전파 사례 (사례 ① ↔ ②)'
    : null;
}

function sourceMetaForReview(review){
  const mst = String(review?.mst || '');
  return CASE_SOURCE_META[mst] || null;
}

function computeAlertEffectiveStatus(effectiveStr){
  if (!effectiveStr) return { isInEffect: true, label: '시행 정보 없음', tone: 'neutral', days: null };
  const today = new Date();
  const todayUtc = Date.UTC(today.getUTCFullYear(), today.getUTCMonth(), today.getUTCDate());
  const parts = String(effectiveStr).split(/[-./]/).map(Number);
  if (parts.length !== 3 || parts.some((n) => !Number.isFinite(n))) return { isInEffect: true, label: '시행일 미상', tone: 'neutral', days: null };
  const targetUtc = Date.UTC(parts[0], parts[1]-1, parts[2]);
  const days = Math.round((todayUtc - targetUtc) / (24*60*60*1000));
  if (days >= 0) return { isInEffect: true, label: `시행 ${days}일 경과`, tone: 'in_effect', days };
  return { isInEffect: false, label: `시행 ${-days}일 전`, tone: 'scheduled', days };
}

function UpperLawScreen({ go }){
  const rawAlerts = RSData.RECENT_ALERTS;
  const [filterMode, setFilterMode] = useStateO('in_effect');
  const [graphModalOpen, setGraphModalOpen] = useStateO(false);
  const [selectedNode, setSelectedNode] = useStateO('시행령');

  const { inEffectAlerts, scheduledAlerts, displayed } = React.useMemo(() => {
    const withStatus = rawAlerts.map((a) => ({ a, status: computeAlertEffectiveStatus(a.effective) }));
    // 시행 중: 최근 시행이 위 = status.days(경과일) 작은 값이 위
    const inEffect = withStatus
      .filter((x) => x.status.isInEffect)
      .sort((a, b) => (a.status.days ?? 9999) - (b.status.days ?? 9999));
    // 시행 전: 시행일이 가까운 게 위 = status.days(음수)가 큰 값(0에 가까움)이 위
    const scheduled = withStatus
      .filter((x) => !x.status.isInEffect)
      .sort((a, b) => (b.status.days ?? -9999) - (a.status.days ?? -9999));
    return {
      inEffectAlerts: inEffect.map((x) => x.a),
      scheduledAlerts: scheduled.map((x) => x.a),
      displayed: (filterMode === 'in_effect' ? inEffect : scheduled).map((x) => x.a)
    };
  }, [rawAlerts, filterMode]);

  const [selected, setSelected] = useStateO(0);
  React.useEffect(() => { setSelected(0); }, [filterMode]);
  const sel = displayed[selected] || displayed[0] || rawAlerts[0];
  const c = RSData.getCaseByLaw(sel.law);
  const selStatus = computeAlertEffectiveStatus(sel.effective);
  React.useEffect(() => { if (sel) RSData.setCurrentCaseByLaw(sel.law); }, [sel?.law]);

  const TabButton = ({ mode, label, count }) => {
    const active = filterMode === mode;
    return (
      <button
        onClick={() => setFilterMode(mode)}
        style={{
          padding: '5px 11px',
          borderRadius: 99,
          fontSize: 11.5,
          fontWeight: active ? 700 : 600,
          background: active ? 'var(--navy)' : '#fff',
          color: active ? '#fff' : 'var(--ink-2)',
          border: '1px solid ' + (active ? 'var(--navy)' : 'var(--line-2)'),
          cursor: 'pointer'
        }}
      >
        {label} <span className="mono" style={{ opacity: 0.75, marginLeft: 3 }}>{count}</span>
      </button>
    );
  };

  return (
    <Page
      eyebrow="03 · 탐지 모듈"
      title="상위법 개정 감지"
      desc="국가법령정보센터 데이터를 모니터링하여, 선택한 상위법 개정이 영향을 미치는 하위 규정·자치법규·서식을 탐지합니다."
      actions={[
        <Btn key="1" kind="secondary" icon="bell" data-action="configure-alerts">알림 설정</Btn>,
        <Btn key="2" kind="primary" icon="spark" data-action="recalculate-impact">전체 영향도 재계산</Btn>,
      ]}
    >
      <div style={{display:'grid', gridTemplateColumns:'1.1fr 1.6fr', gap:14}}>
        <Card>
          <SectionHeader
            title="감지된 개정 (최근 30일)"
            right={
              <div style={{display:'flex', gap:5, flexWrap:'wrap'}}>
                <TabButton mode="in_effect" label="시행 중" count={inEffectAlerts.length} />
                <TabButton mode="scheduled" label="시행 전" count={scheduledAlerts.length} />
              </div>
            }
          />
          <div style={{fontSize:11, color:'var(--ink-4)', padding:'2px 0 8px', lineHeight:1.5}}>
            {filterMode === 'in_effect'
              ? '최근에 시행된 개정부터 위에 표시합니다. 시행 중인 항목만 자치법규 비교가 활성화됩니다.'
              : '시행일이 가까운 개정부터 위에 표시합니다. 아직 시행 전이므로 자치법규 비교는 시행일 이후에 활성화됩니다.'}
          </div>
          <div style={{margin:'0 -20px'}}>
            {displayed.length === 0 && (
              <div style={{padding:'40px 20px', textAlign:'center', color:'var(--ink-4)', fontSize:12}}>
                {filterMode === 'in_effect' ? '시행 중인 개정이 없습니다.' : '시행 예정 개정이 없습니다.'}
              </div>
            )}
            {displayed.map((a,i)=>{
              const status = computeAlertEffectiveStatus(a.effective);
              const isSelected = selected === i;
              return (
              <button key={a.law+i} data-action="select-detected-amendment" data-amendment-idx={i} data-law={a.law} onClick={()=>{setSelected(i); setSelectedNode('시행령'); RSData.setCurrentCaseByLaw(a.law);}} style={{
                display:'block', width:'100%', textAlign:'left', padding:'14px 20px', border:'none',
                background: isSelected ? 'var(--blue-soft)' : 'transparent',
                borderLeft: isSelected ? '3px solid var(--navy)' : '3px solid transparent',
                borderBottom:'1px solid var(--line)', cursor:'pointer'
              }}>
                <div style={{display:'flex', alignItems:'center', justifyContent:'space-between', marginBottom:4, gap:6, flexWrap:'wrap'}}>
                  <span className="mono" style={{fontSize:11, color:'var(--ink-3)'}}>공포 {a.date}</span>
                  <Badge tone={RSData.syncSeverityTone(a.severity)} size="sm">{RSData.syncSeverityLabel(a.severity)}</Badge>
                </div>
                <div style={{fontSize:14, fontWeight:700, color:'var(--ink)'}}>{a.law}</div>
                <div style={{fontSize:12, color:'var(--ink-3)', marginTop:2}}>{a.change}</div>
                <div style={{display:'flex', alignItems:'center', gap:6, marginTop:6, flexWrap:'wrap'}}>
                  <span style={{fontSize:10.5, fontWeight:600, color:status.isInEffect?'#1F7A6B':'#5B7C99', background:'transparent', padding:'1px 0', borderRadius:0}}>
                    {status.isInEffect ? `시행 ${a.effective}` : `시행 예정 ${a.effective}`}
                  </span>
                  <span style={{fontSize:10.5, color:'var(--ink-4)'}}>· {status.label}</span>
                </div>
                <div style={{display:'flex', gap:14, marginTop:8, fontSize:11, color:'var(--ink-3)'}}>
                  <span><span className="mono" style={{color:'var(--navy)', fontWeight:700}}>{a.impact}</span> 하위규정</span>
                  <span><span className="mono" style={{color:'var(--navy)', fontWeight:700}}>{Math.round(a.impact*0.4)}</span> 자치법규</span>
                  <span><span className="mono" style={{color:'var(--navy)', fontWeight:700}}>{Math.round(a.impact*0.2)}</span> 민원서식</span>
                </div>
              </button>
              );
            })}
          </div>
        </Card>

        <div>
          <Card style={{marginBottom:14}}>
            <div style={{display:'flex', alignItems:'flex-start', gap:14, marginBottom:12}}>
              <div>
                {severityBadge(c)}
                <div style={{fontSize:20, fontWeight:700, marginTop:8, color:'var(--ink)'}}>{c.law}</div>
                <div style={{fontSize:13, color:'var(--ink-3)', marginTop:4}}>
                  {c.article} · {c.change} · 공포일 {sel.date}
                  {' · '}
                  <span style={{color:selStatus.isInEffect?'#1F7A6B':'#5B7C99', fontWeight:700}}>
                    {selStatus.isInEffect ? `시행 ${sel.effective} (${selStatus.label})` : `시행 예정 ${sel.effective} (${selStatus.label})`}
                  </span>
                </div>
                {!selStatus.isInEffect && (
                  <div style={{marginTop:8, padding:'8px 12px', background:'#F8FAFC', border:'1px solid var(--line)', borderRadius:6, fontSize:12, color:'var(--ink-3)', lineHeight:1.55}}>
                    ⓘ 이 상위법은 아직 시행되지 않았습니다. 시행일({sel.effective}, {-selStatus.days}일 후) 이후에 자치법규 비교가 활성화됩니다.
                  </div>
                )}
              </div>
              <div style={{flex:1}}/>
              <Btn icon="compare" disabled={!selStatus.isInEffect} onClick={()=>{ if(!selStatus.isInEffect) return; RSData.setCurrentCase(c.key); go('compare'); }} data-action="open-compare-view" data-law={c.law} style={!selStatus.isInEffect?{opacity:0.45, cursor:'not-allowed'}:undefined}>
                {selStatus.isInEffect ? '신구조문 비교' : '비교 불가 (시행 전)'}
              </Btn>
            </div>
            <div style={{display:'grid', gridTemplateColumns:'repeat(3, 1fr)', gap:10, marginTop:12, paddingTop:14, borderTop:'1px solid var(--line)'}}>
              <CaseMetric l="영향 점수" v={c.score.toFixed(1)} s="/ 100" tone="#C77A1B"/>
              <CaseMetric l="연관 하위규정" v={c.impact} s="건" tone="#0B2E5C"/>
              <CaseMetric l="예상 정비 기간" v={c.period} s="개월" tone="#5B7C99"/>
            </div>
          </Card>

          <Card>
            <SectionHeader title="영향 범위 그래프" desc={`${c.law} → 하위 규정 인용 관계`} right={<Btn kind="secondary" size="sm" icon="arrow-right" onClick={()=>setGraphModalOpen(true)}>자세히 보기</Btn>}/>
            <ImpactGraph law={c.law}/>
            <div style={{display:'flex', gap:18, marginTop:10, paddingTop:10, borderTop:'1px solid var(--line)', fontSize:11, color:'var(--ink-3)'}}>
              <LegendDot color="#0B2E5C" label="상위법"/><LegendDot color="#2E5FB0" label="시행령·시행규칙"/><LegendDot color="#5B7C99" label="고시·훈령"/><LegendDot color="#C77A1B" label="자치법규"/><LegendDot color="#7DA9E6" label="민원서식"/>
            </div>
          </Card>
        </div>
      </div>
      {graphModalOpen && <ImpactGraphModal law={c.law} selectedNode={selectedNode} onSelectNode={setSelectedNode} onClose={()=>setGraphModalOpen(false)}/>} 
    </Page>
  );
}

function ImpactGraph({ onNodeClick, selectedNode, large=false, law }){
  const c = RSData.getCaseByLaw(law || RSData.getCurrentCase().law);
  const mids = c.graph.mids;
  const leaves = c.graph.leaves;
  const ROOT_X = 600, ROOT_Y_MID = 40;
  const MID_Y_TOP = 100, MID_Y_BOT = 136;
  const LEAF_Y_TOP = 188;
  const LEAF_W = 95, LEAF_H = 30;
  const MID_W = 110, MID_H = 36;
  const clickable = !!onNodeClick;
  const nodeStyle = clickable ? { cursor:'pointer' } : {};
  return (
    <svg viewBox="0 0 1200 240" width="100%" height={large?320:240} style={{display:'block'}}>
      {mids.map((m,i)=>(<path key={`rm-${i}`} d={`M ${ROOT_X} ${ROOT_Y_MID+22} C ${ROOT_X} ${(ROOT_Y_MID+MID_Y_TOP)/2 + 22}, ${m.x} ${(ROOT_Y_MID+MID_Y_TOP)/2 + 22}, ${m.x} ${MID_Y_TOP}`} stroke={selectedNode===m.l ? m.c : '#CBD5E1'} strokeWidth={selectedNode===m.l ? 2 : 1} fill="none"/>))}
      {leaves.map((l,i)=>(<path key={`ml-${i}`} d={`M ${l.parent} ${MID_Y_BOT} C ${l.parent} ${(MID_Y_BOT+LEAF_Y_TOP)/2}, ${l.x} ${(MID_Y_BOT+LEAF_Y_TOP)/2}, ${l.x} ${LEAF_Y_TOP}`} stroke={selectedNode===l.l ? l.c : '#CBD5E1'} strokeWidth={selectedNode===l.l ? 2 : 1} fill="none"/>))}
      <g style={nodeStyle} onClick={clickable ? ()=>onNodeClick(c.law) : undefined}>
        <rect x={ROOT_X-90} y={ROOT_Y_MID-22} width="180" height="44" rx="22" fill="#0B2E5C" stroke={selectedNode===c.law ? '#5EE6B5' : 'none'} strokeWidth={selectedNode===c.law ? 3 : 0}/>
        <text x={ROOT_X} y={ROOT_Y_MID+5} textAnchor="middle" fill="#fff" fontSize="13" fontWeight="600" pointerEvents="none">{c.law}</text>
      </g>
      {mids.map((n,i)=>{ const isSel = selectedNode === n.l; return (<g key={`m-${i}`} style={nodeStyle} onClick={clickable ? ()=>onNodeClick(n.l) : undefined}><rect x={n.x-MID_W/2} y={MID_Y_TOP} width={MID_W} height={MID_H} rx="18" fill={n.c} opacity={isSel?1:0.92} stroke={isSel?'#FFD86B':'none'} strokeWidth={isSel?3:0}/><text x={n.x} y={MID_Y_TOP+23} textAnchor="middle" fill="#fff" fontSize="11" fontWeight="600" pointerEvents="none">{n.l}</text></g>); })}
      {leaves.map((n,i)=>{ const isSel = selectedNode === n.l; return (<g key={`l-${i}`} style={nodeStyle} onClick={clickable ? ()=>onNodeClick(n.l) : undefined}><rect x={n.x-LEAF_W/2} y={LEAF_Y_TOP} width={LEAF_W} height={LEAF_H} rx="6" fill={isSel?n.c:'#fff'} stroke={n.c} strokeWidth={isSel?2:1.4}/><text x={n.x} y={LEAF_Y_TOP+19} textAnchor="middle" fill={isSel?'#fff':n.c} fontSize="10.5" fontWeight="600" pointerEvents="none">{n.l}</text></g>); })}
    </svg>
  );
}

function ImpactGraphModal({ law, selectedNode, onSelectNode, onClose }){
  const c = RSData.getCaseByLaw(law || RSData.getCurrentCase().law);
  const details = RSData.getNodeDetails(c.law);
  const detail = details[selectedNode] || details['시행령'];
  const tagColors = { teal:{bg:'#DBEEEA', fg:'#155F53', dot:'#1F7A6B'}, rose:{bg:'#F5E1E3', fg:'#7C2F35', dot:'#A8434A'}, amber:{bg:'#FBEFD9', fg:'#8B5410', dot:'#C77A1B'}, steel:{bg:'#EEF2F7', fg:'#3F5A75', dot:'#5B7C99'} };
  return (
    <div onClick={onClose} style={{position:'fixed', inset:0, background:'rgba(15,23,42,0.55)', display:'flex', alignItems:'center', justifyContent:'center', zIndex:9999, padding:'40px 32px', backdropFilter:'blur(4px)'}}>
      <div onClick={e=>e.stopPropagation()} style={{background:'#fff', borderRadius:14, width:'min(1320px, 100%)', maxHeight:'92vh', display:'flex', flexDirection:'column', overflow:'hidden', boxShadow:'0 24px 60px rgba(15,23,42,0.25)'}}>
        <div style={{display:'flex', alignItems:'center', justifyContent:'space-between', padding:'18px 28px', borderBottom:'1px solid var(--line)', background:'linear-gradient(120deg, #0B2E5C 0%, #143A73 100%)', color:'#fff'}}>
          <div><div style={{fontSize:11, fontWeight:700, color:'#7DA9E6', letterSpacing:'0.1em', marginBottom:4}}>IMPACT GRAPH · DETAIL</div><div style={{fontSize:18, fontWeight:700}}>{c.law} 영향 범위 상세 분석</div><div style={{fontSize:12, opacity:0.75, marginTop:3}}>노드를 클릭하면 해당 법령·규칙의 본문과 AI가 식별한 정비 후보를 확인할 수 있습니다.</div></div>
          <button onClick={onClose} style={{display:'inline-flex', alignItems:'center', gap:6, padding:'8px 14px', borderRadius:7, fontSize:12, fontWeight:600, background:'rgba(255,255,255,0.10)', color:'#fff', border:'1px solid rgba(255,255,255,0.22)', cursor:'pointer'}}>✕ 닫기</button>
        </div>
        <div style={{flex:1, overflowY:'auto', padding:'24px 28px', display:'flex', flexDirection:'column', gap:20}}>
          <div style={{background:'#FBFCFE', border:'1px solid var(--line)', borderRadius:12, padding:'18px 20px'}}>
            <div style={{display:'flex', alignItems:'center', justifyContent:'space-between', marginBottom:12}}><div style={{fontSize:13, fontWeight:700, color:'var(--ink)'}}>법령 인용 네트워크</div><div style={{display:'flex', gap:14, fontSize:11, color:'var(--ink-3)'}}><LegendDot color="#0B2E5C" label="상위법"/><LegendDot color="#2E5FB0" label="시행령·시행규칙"/><LegendDot color="#5B7C99" label="고시·훈령"/><LegendDot color="#C77A1B" label="자치법규"/><LegendDot color="#7DA9E6" label="민원서식"/></div></div>
            <ImpactGraph law={c.law} onNodeClick={onSelectNode} selectedNode={selectedNode} large/>
          </div>
          <div style={{background:'#fff', border:'1px solid var(--line)', borderRadius:12, overflow:'hidden'}}>
            <div style={{padding:'16px 20px', borderBottom:'1px solid var(--line)', display:'flex', alignItems:'center', gap:14, flexWrap:'wrap', background:'#F8FAFC'}}><span style={{fontSize:10, fontWeight:700, letterSpacing:'0.08em', color:'#fff', background:detail.tone, padding:'4px 10px', borderRadius:99}}>{detail.role}</span><div style={{flex:1, minWidth:240}}><div style={{fontSize:15, fontWeight:700, color:'var(--ink)'}}>{detail.title}</div><div style={{fontSize:11.5, color:'var(--ink-3)', marginTop:2}}>{detail.sub}</div></div><span style={{fontSize:11, fontWeight:700, color:'#fff', background:detail.status.tone, padding:'4px 10px', borderRadius:99}}>{detail.status.label}</span></div>
            <div style={{padding:'18px 22px', display:'flex', flexDirection:'column', gap:10}}>{detail.body.map((line,i)=>{ if(!line.tag) return <div key={i} style={{fontSize:13, color:'var(--ink-2)', lineHeight:1.75, paddingLeft:8}}>{line.text}</div>; const cc=tagColors[line.tone]||tagColors.steel; return <div key={i} style={{display:'flex', alignItems:'flex-start', gap:10, background:cc.bg, border:`1px solid ${cc.dot}33`, borderLeft:`3px solid ${cc.dot}`, padding:'10px 14px', borderRadius:8}}><span style={{fontSize:10.5, fontWeight:700, color:'#fff', background:cc.dot, padding:'3px 9px', borderRadius:99, whiteSpace:'nowrap', flexShrink:0, marginTop:1}}>{line.tag}</span><div style={{fontSize:13, color:cc.fg, lineHeight:1.7, fontWeight:500}}>{line.text}</div></div>; })}</div>
          </div>
        </div>
      </div>
    </div>
  );
}

function LegacyCompareScreen({ go }){
  const c = RSData.getCurrentCase();
  const firstSeg = c.compare.segments[0].id;
  const [picked, setPicked] = useStateO(firstSeg);
  const [tab, setTab] = useStateO('전체');
  const OLD = c.compare.old, NEW = c.compare.new, SEGMENTS = c.compare.segments;
  const sel = SEGMENTS.find(s=>s.id===picked) || SEGMENTS[0];
  const hits = c.compare.hits[picked] || [];
  const filtered = tab==='전체' ? hits : hits.filter(h=> h.kind===tab);
  const totalHits = SEGMENTS.reduce((a,s)=>a+s.hits,0);
  return (
    <Page eyebrow="04 · 싱크Law 분석" title="신·구 조문 싱크 분석 — 하위문서 잔존 문구 검토" desc={`${c.law} ${c.article} / ${c.date} ${c.change} · AI가 변경 조항과 동일·유사 표현이 남은 하위문서를 식별합니다.`} actions={[<Btn key="1" kind="secondary" icon="download" data-action="export-evidence-pdf">근거 자료 PDF</Btn>, <Btn key="2" kind="secondary" icon="layers" onClick={()=>go('lower')}>하위규정 화면</Btn>, <Btn key="3" kind="primary" icon="check" onClick={()=>go('analysis')}>분석 상세로 이동</Btn>]}> 
      <div style={{background:'#fff', border:'1px solid var(--line)', borderRadius:12, padding:'14px 18px', marginBottom:14, display:'flex', alignItems:'center', gap:14, boxShadow:'var(--shadow-sm)'}}><div style={{width:36, height:36, borderRadius:9, background:'var(--blue-soft)', display:'flex', alignItems:'center', justifyContent:'center', color:'var(--navy)'}}><Icon name="brain" size={18}/></div><div style={{flex:1}}><div style={{fontSize:13, fontWeight:700, color:'var(--ink)'}}>AI는 법률 판단을 내리지 않고, 변경 문구와 하위문서 표현 간 유사도를 분석해 검토 후보를 제시합니다.</div><div style={{fontSize:11.5, color:'var(--ink-3)', marginTop:3}}>선택 법령: {c.law} {c.article} · 출처: 국가법령정보센터 · 자치법규정보시스템 · 민원서식 OCR</div></div><Pill k="분석 조항" v="1건"/><Pill k="감지 변경" v={`${SEGMENTS.length}건`}/><Pill k="잔존 후보" v={`${totalHits}건`}/></div>
      <div data-report-section="per-document-sync-rates" style={{display:'grid', gridTemplateColumns:'repeat(4, 1fr)', gap:10, marginBottom:14}}>{c.syncRates.map(s=>{ const tone=s.v>=85?'#1F7A6B':s.v>=70?'#5B7C99':'#C77A1B'; const soft=s.v>=85?'#DBEEEA':s.v>=70?'#EEF2F7':'#FBEFD9'; const txt=s.v>=85?'대체로 정비 완료':s.v>=70?'일부 정비 필요':'잔존 규제 의심 다수'; return <div key={s.l} data-sync-rate={s.v} style={{background:'#fff', border:'1px solid var(--line)', borderRadius:11, padding:'12px 14px', position:'relative', overflow:'hidden'}}><div style={{position:'absolute', left:0, top:0, bottom:0, width:3, background:tone}}/><div style={{display:'flex', alignItems:'center', justifyContent:'space-between', marginBottom:6}}><span style={{fontSize:11.5, color:'var(--ink-3)', fontWeight:600}}>{s.l} 싱크Law율</span><span style={{fontSize:9.5, color:tone, fontWeight:700, background:soft, padding:'2px 6px', borderRadius:4}}>{txt}</span></div><div style={{display:'flex', alignItems:'baseline', gap:6}}><span className="mono" style={{fontSize:24, fontWeight:700, color:tone}}>{s.v}</span><span style={{fontSize:11, color:'var(--ink-4)'}}>%</span><div style={{flex:1}}/><span style={{fontSize:10.5, color:'var(--ink-3)'}}>{s.n}</span></div><div style={{height:4, background:'#EEF2F7', borderRadius:99, marginTop:8, overflow:'hidden'}}><div style={{width:`${s.v}%`, height:'100%', background:tone}}/></div></div>; })}</div>
      <div style={{display:'grid', gridTemplateColumns:'1.2fr 1fr 1.3fr', gap:14, marginBottom:14}}>
        <div style={{background:'#fff', border:'1px solid var(--line)', borderRadius:12, boxShadow:'var(--shadow-sm)', display:'flex', flexDirection:'column'}}><div style={{padding:'12px 16px', borderBottom:'1px solid var(--line)', background:'#FBFCFE', borderRadius:'12px 12px 0 0', display:'flex', alignItems:'center', justifyContent:'space-between'}}><Badge tone="navy" size="sm">{c.law} {c.article}</Badge><span style={{fontSize:11, color:'var(--ink-3)'}}>개정 전 ↔ 개정 후</span></div><div style={{display:'grid', gridTemplateColumns:'1fr 1fr', flex:1, minHeight:0}}><ArticleColumn label="개정 전" tone="rose" lines={OLD} picked={picked} onPick={setPicked}/><ArticleColumn label="개정 후" tone="teal" lines={NEW} picked={picked} onPick={setPicked} divider/></div></div>
        <div style={{background:'#fff', border:'1px solid var(--line)', borderRadius:12, boxShadow:'var(--shadow-sm)', display:'flex', flexDirection:'column'}}><div style={{padding:'12px 16px', borderBottom:'1px solid var(--line)', background:'#FBFCFE', borderRadius:'12px 12px 0 0'}}><div style={{display:'flex', alignItems:'center', gap:8}}><span style={{fontSize:10, fontWeight:700, color:'var(--blue)', letterSpacing:'0.08em', background:'var(--blue-soft)', padding:'2px 8px', borderRadius:4}}>AI 감지</span><span style={{fontSize:13, fontWeight:700, color:'var(--ink)'}}>변경 단위</span></div><div style={{fontSize:11.5, color:'var(--ink-3)', marginTop:4}}>{SEGMENTS.length}개 변경 단위 · 클릭 시 좌·우 패널 연동</div></div><div style={{flex:1, overflowY:'auto'}}>{SEGMENTS.map((s,i)=>{ const active=picked===s.id; const toneColor=s.tone==='amber'?'#C77A1B':s.tone==='blue'?'#2E5FB0':s.tone==='teal'?'#1F7A6B':'#5B7C99'; return <button key={s.id} onClick={()=>{setPicked(s.id); setTab('전체');}} style={{display:'block', width:'100%', textAlign:'left', padding:'14px 16px', border:'none', cursor:'pointer', background:active?'#FBFCFE':'#fff', borderLeft:active?`3px solid ${toneColor}`:'3px solid transparent', borderBottom:i<SEGMENTS.length-1?'1px solid var(--line)':'none'}}><div style={{display:'flex', alignItems:'center', gap:6, marginBottom:8}}><Badge tone={s.tone} size="sm">{s.kind}</Badge><span className="mono" style={{fontSize:10, color:'var(--ink-4)'}}>{s.id.toUpperCase()}</span><div style={{flex:1}}/><span className="mono" style={{fontSize:11, fontWeight:700, color:toneColor}}>{s.severity}</span><span style={{fontSize:10, color:'var(--ink-4)'}}>유사도</span></div><div style={{fontSize:11, color:'var(--ink-3)', marginBottom:4}}>변경 전</div><div style={{fontSize:12.5, color:'var(--ink-2)', padding:'7px 10px', background:'#FBE9EB', borderRadius:4, lineHeight:1.55, textDecoration:'line-through', textDecorationColor:'rgba(168,67,74,0.45)'}}>{s.from}</div><div style={{display:'flex', justifyContent:'center', margin:'4px 0', color:'var(--ink-4)'}}><Icon name="arrow-down" size={11}/></div><div style={{fontSize:11, color:'var(--ink-3)', marginBottom:4}}>변경 후</div><div style={{fontSize:12.5, color:'var(--ink-2)', padding:'7px 10px', background:'#E6F4F1', borderRadius:4, lineHeight:1.55}}>{s.to}</div><div style={{fontSize:11, color:'var(--ink-3)', lineHeight:1.5, marginTop:8}}>{s.summary}</div><div style={{display:'flex', alignItems:'center', gap:6, marginTop:6}}><Icon name="search" size={11} color="var(--blue)"/><span style={{fontSize:11, color:'var(--ink-3)'}}>잔존 의심 문구 <span className="mono" style={{color:'var(--navy)', fontWeight:700}}>{s.hits}</span>건 탐지</span></div></button>; })}</div></div>
        <div style={{background:'#fff', border:'1px solid var(--line)', borderRadius:12, boxShadow:'var(--shadow-sm)', display:'flex', flexDirection:'column'}}><div style={{padding:'12px 16px', borderBottom:'1px solid var(--line)', background:'#FBFCFE', borderRadius:'12px 12px 0 0'}}><div style={{display:'flex', alignItems:'center', justifyContent:'space-between', marginBottom:8}}><div style={{display:'flex', alignItems:'center', gap:8}}><span style={{fontSize:10, fontWeight:700, color:'var(--amber)', letterSpacing:'0.08em', background:'var(--amber-soft)', padding:'2px 8px', borderRadius:4}}>잔존 의심</span><span style={{fontSize:13, fontWeight:700, color:'var(--ink)'}}>하위문서 유사 문구</span></div><span style={{fontSize:11, color:'var(--ink-3)'}}>총 <span className="mono" style={{color:'var(--ink)', fontWeight:700}}>{hits.length}</span>건</span></div><div style={{display:'flex', gap:5, flexWrap:'wrap'}}>{['전체','시행령','고시','조례','민원서식','안내문'].map(t=>{ const cnt=t==='전체'?hits.length:hits.filter(h=>h.kind===t).length; return <button key={t} onClick={()=>setTab(t)} disabled={cnt===0&&t!=='전체'} style={{padding:'4px 10px', borderRadius:99, fontSize:11, fontWeight:tab===t?700:500, background:tab===t?'var(--navy)':'#fff', color:tab===t?'#fff':(cnt===0?'var(--ink-4)':'var(--ink-2)'), border:'1px solid '+(tab===t?'var(--navy)':'var(--line-2)'), cursor:cnt===0?'not-allowed':'pointer', opacity:cnt===0?0.5:1}}>{t} {cnt>0&&<span className="mono" style={{opacity:.7, marginLeft:3}}>{cnt}</span>}</button>; })}</div></div><div style={{flex:1, overflowY:'auto', padding:'8px 0'}}>{filtered.length===0&&<div style={{padding:'40px 20px', textAlign:'center', color:'var(--ink-4)', fontSize:12}}>선택한 유형에서 감지된 잔존 문구가 없습니다.</div>}{filtered.map((h,i)=>{ const docSync=h.sim?Math.max(40,100-h.sim+8):70; return <div key={h.id} data-residual-hit-id={h.id} data-agency={h.agency} data-sync-rate={docSync} style={{padding:'12px 16px', borderBottom:i<filtered.length-1?'1px dashed var(--line)':'none'}}><div style={{display:'flex', alignItems:'center', gap:6, marginBottom:6}}><Badge tone="ghost" size="sm">{h.kind}</Badge><span className="mono" style={{fontSize:10, color:'var(--ink-4)'}}>{h.id}</span>{h.hilite&&<Badge tone="amber" size="sm">{h.hilite}</Badge>}<div style={{flex:1}}/><span style={{fontSize:10, fontWeight:700, color:docSync<60?'#C77A1B':docSync<80?'#5B7C99':'#1F7A6B', background:docSync<60?'#FBEFD9':docSync<80?'#EEF2F7':'#DBEEEA', padding:'2px 7px', borderRadius:4}}>싱크Law율 {docSync}%</span></div><div style={{fontSize:13, fontWeight:700, color:'var(--ink)', lineHeight:1.4}}>{h.src}</div><div style={{fontSize:11, color:'var(--ink-3)', marginTop:2}}>{h.agency} · 최종개정 <span className="mono">{h.updated}</span></div><div style={{marginTop:8, padding:'8px 10px', background:'#F8FAFC', border:'1px solid var(--line)', borderRadius:6, fontSize:12, color:'var(--ink-2)', lineHeight:1.6, fontFamily:'inherit'}}><span dangerouslySetInnerHTML={{__html:h.snippet.replace(/<m>/g,'<mark style="background:#FBEFD9; color:#0F172A; padding:0 4px; border-radius:2px; border-bottom:2px solid #C77A1B;">').replace(/<\/m>/g,'</mark>')}}/></div><div style={{display:'flex', gap:8, marginTop:8}}><button data-action="open-original-source" data-doc-id={h.id} style={miniBtn}><Icon name="doc" size={11}/> 원문 근거 확인</button><button data-action="show-sync-evidence" data-doc-id={h.id} style={miniBtn}><Icon name="brain" size={11}/> 분석 근거</button><button data-action="request-agency-review" data-doc-id={h.id} style={{...miniBtn, color:'var(--blue)'}}><Icon name="flag" size={11}/> 소관부서 검토 요청</button></div></div>; })}</div></div>
      </div>
    </Page>
  );
}

function LowerScreen({ go }){
  const c = RSData.getCurrentCase();
  const matches = c.lowerMatches;
  const [picked, setPicked] = useStateO(matches[0].id);
  const sel = matches.find(m=>m.id===picked) || matches[0];
  const counts = ['전체 ('+matches.length+')'].concat(['시행령','고시','조례','규칙','지침'].map(k=>`${k} (${matches.filter(m=>m.kind===k).length})`));
  return (
    <Page eyebrow="05 · 탐지 모듈" title="하위규정·행정규칙·자치법규 대조" desc={`${c.law} 개정과 연결된 하위 규정·고시·조례·규칙을 의미 유사도로 매칭하고, 미정비 항목을 위험도순으로 정렬합니다.`} actions={[<Btn key="1" kind="secondary" icon="filter" data-action="open-advanced-filter">고급 필터</Btn>, <Btn key="2" kind="primary" icon="download" data-action="export-comparison-table">대조표 내보내기</Btn>]}>
      <div data-role="mock-notice" style={{display:'flex', alignItems:'center', gap:10, padding:'10px 14px', marginBottom:14, background:'#FEF3C7', border:'1px solid #FCD34D', borderRadius:8, fontSize:12, color:'#854D0E', fontWeight:600}}>
        <span style={{fontSize:14}}>📋</span>
        <span style={{flex:1, lineHeight:1.55}}><b>이 화면은 시연용 mock 데이터</b>입니다. 정비 검토 후보의 실측 사례와는 다릅니다. 실측 데이터로 작동하는 화면: <b>홈 · 정비 검토 후보 · 신구조문 비교 · 사례 상세 분석</b>.</span>
        <button onClick={()=>go('dashboard')} style={{fontSize:11, fontWeight:700, color:'#854D0E', background:'#FEF9C3', border:'1px solid #EAB308', padding:'4px 10px', borderRadius:5, cursor:'pointer'}}>실측 후보 보기 →</button>
      </div>
      <Card style={{marginBottom:14, padding:'14px 18px'}}><div style={{display:'flex', alignItems:'center', gap:18, flexWrap:'wrap'}}><span style={{fontSize:12, color:'var(--ink-3)', fontWeight:600}}>대상 상위법</span><Badge tone="navy">{c.law} {c.article}</Badge><div style={{height:18, width:1, background:'var(--line)'}}/><div style={{display:'flex', gap:6}}>{counts.map((t,i)=><Chip key={t} active={i===0}>{t}</Chip>)}</div></div></Card>
      <div style={{display:'grid', gridTemplateColumns:'1.4fr 1fr', gap:14}}><Card padding={0}><div style={{display:'grid', gridTemplateColumns:'90px 70px 1fr 110px 130px', padding:'12px 18px', fontSize:11, color:'var(--ink-3)', fontWeight:600, background:'#F8FAFC', borderBottom:'1px solid var(--line)', borderRadius:'12px 12px 0 0'}}><span>ID</span><span>유형</span><span>대조 규정</span><span>위험도</span><span>상태</span></div>{matches.map((m,i)=><button key={m.id} onClick={()=>setPicked(m.id)} style={{display:'grid', gridTemplateColumns:'90px 70px 1fr 110px 130px', padding:'14px 18px', textAlign:'left', alignItems:'center', background:picked===m.id?'var(--blue-soft)':'transparent', border:'none', borderBottom:i<matches.length-1?'1px solid var(--line)':'none', cursor:'pointer', width:'100%'}}><span className="mono" style={{fontSize:11, color:'var(--ink-3)'}}>{m.id}</span><span><Badge tone="ghost" size="sm">{m.kind}</Badge></span><span><div style={{fontSize:13, fontWeight:600, color:'var(--ink)'}}>{m.src}</div><div style={{fontSize:11, color:'var(--ink-3)', marginTop:2}}>{m.agency} · 최종개정 <span className="mono">{m.updated}</span></div></span><RiskBar value={m.risk}/><Badge tone={m.risk>=90?'amber':m.risk>=70?'steel':'ghost'} size="sm">{m.status}</Badge></button>)}</Card><Card><SectionHeader title="규정 상세 대조" right={<Badge tone="blue" size="sm"><Icon name="check" size={11}/> AI 매칭 {Math.min(98, sel.risk+1).toFixed(1)}%</Badge>}/><div style={{padding:'12px 14px', background:'#F8FAFC', borderRadius:8, marginBottom:12}}><div style={{fontSize:11, color:'var(--ink-3)'}}>대조 대상</div><div style={{fontSize:13.5, fontWeight:700, color:'var(--ink)', marginTop:4}}>{sel.src}</div><div style={{fontSize:11, color:'var(--ink-3)', marginTop:4}}>{sel.agency} · 최종개정 {sel.updated}</div></div><div style={{fontSize:11, color:'var(--ink-3)', fontWeight:600, marginBottom:6}}>차이 분석</div>{c.lowerIssues.map((d,i)=><div key={i} style={{padding:'12px 14px', border:'1px solid var(--line)', borderRadius:8, marginBottom:8}}><div style={{display:'flex', alignItems:'center', gap:8, marginBottom:6}}><Badge tone={d.tone} size="sm">{d.tag}</Badge><span style={{fontSize:13, fontWeight:600, color:'var(--ink)'}}>{d.t}</span></div><div style={{fontSize:12, color:'var(--ink-2)', lineHeight:1.6}}>{d.d}</div></div>)}<Btn kind="primary" icon="brain" style={{width:'100%', justifyContent:'center', marginTop:8}} onClick={()=>go('analysis')} data-action="open-ai-analysis">AI 분석 결과 상세</Btn></Card></div>
    </Page>
  );
}

function DynamicFormPreview({ sel, law, article }){
  return <div style={{border:'1px solid var(--line-2)', borderRadius:8, padding:'24px 28px', background:'#fff', position:'relative', minHeight:320, backgroundImage:'repeating-linear-gradient(0deg, #F8FAFC 0 1px, transparent 1px 28px)'}}><div style={{position:'absolute', top:14, right:18, fontSize:10, color:'var(--ink-4)', fontFamily:'JetBrains Mono'}}>[{sel.section}]</div><div style={{textAlign:'center', fontSize:18, fontWeight:700, color:'var(--ink)', marginBottom:18, paddingBottom:10, borderBottom:'2px solid var(--ink)'}}>{sel.name}</div><div style={{display:'grid', gridTemplateColumns:'120px 1fr', rowGap:6, columnGap:10, fontSize:12, color:'var(--ink-2)'}}><div style={{color:'var(--ink-3)'}}>신청인</div><div style={{borderBottom:'1px solid var(--line-2)', paddingBottom:2}}>홍 길 동</div><div style={{color:'var(--ink-3)'}}>식별정보</div><div style={{borderBottom:'1px solid var(--line-2)', paddingBottom:2, position:'relative'}}><span style={{background:'#FBEFD9', padding:'1px 4px', borderBottom:'2px wavy #C77A1B'}}>개정 전 기준 기재란</span><span style={{position:'absolute', right:0, top:-18, fontSize:10, background:'#C77A1B', color:'#fff', padding:'1px 6px', borderRadius:4}}>잔존 문구 의심</span></div><div style={{color:'var(--ink-3)'}}>처리기관</div><div style={{borderBottom:'1px solid var(--line-2)', paddingBottom:2}}>소관부서</div></div><div style={{marginTop:18, padding:'10px 12px', background:'#F8FAFC', borderRadius:4, fontSize:11.5, color:'var(--ink-3)', lineHeight:1.7}}>※ 본 신청서는 「{law}」 <span style={{background:'#FBEFD9', padding:'0 4px', borderBottom:'2px wavy #C77A1B'}}>{article}</span>에 따라 처리됩니다.<span style={{display:'block', fontSize:10, color:'var(--amber)', marginTop:4}}>↑ {sel.issue} — 안내문 정비 필요성</span></div></div>;
}

function FormsScreen({ go }){
  const c = RSData.getCurrentCase();
  const list = c.formsMatches;
  const [picked, setPicked] = useStateO(list[0].id);
  const sel = list.find(f=>f.id===picked) || list[0];
  return (
    <Page eyebrow="06 · 탐지 모듈" title="민원서식·안내문 잔존 문구 탐지" desc={`${c.law} 개정 후 정비되지 않은 민원서식·기관 안내문 문구를 OCR + 의미 분석으로 식별합니다.`} actions={[<Btn key="1" kind="secondary" icon="filter" data-action="open-form-category">서식 카테고리</Btn>, <Btn key="2" kind="primary" icon="download" data-action="send-maintenance-recommendation">정비 권고서 발송</Btn>]}>
      <div data-role="mock-notice" style={{display:'flex', alignItems:'center', gap:10, padding:'10px 14px', marginBottom:14, background:'#FEF3C7', border:'1px solid #FCD34D', borderRadius:8, fontSize:12, color:'#854D0E', fontWeight:600}}>
        <span style={{fontSize:14}}>📋</span>
        <span style={{flex:1, lineHeight:1.55}}><b>이 화면은 시연용 mock 데이터</b>입니다. 정비 검토 후보의 실측 사례와는 다릅니다. 실측 데이터로 작동하는 화면: <b>홈 · 정비 검토 후보 · 신구조문 비교 · 사례 상세 분석</b>.</span>
        <button onClick={()=>go('dashboard')} style={{fontSize:11, fontWeight:700, color:'#854D0E', background:'#FEF9C3', border:'1px solid #EAB308', padding:'4px 10px', borderRadius:5, cursor:'pointer'}}>실측 후보 보기 →</button>
      </div>
      <div style={{display:'grid', gridTemplateColumns:'repeat(4, 1fr)', gap:12, marginBottom:18}}><Stat label="검사한 서식" value={8421} delta="+142" tone="navy" icon="doc"/><Stat label="잔존 문구 의심" value={list.length} delta="+1" tone="amber" icon="search"/><Stat label="OCR 처리량(주)" value={3214} delta="+88" tone="steel" icon="layers"/><Stat label="기관 회신 대기" value={284} delta="+19" tone="steel" icon="bell"/></div>
      <div style={{display:'grid', gridTemplateColumns:'1.1fr 1.4fr', gap:14}}><Card padding={0}><div style={{padding:'14px 18px', borderBottom:'1px solid var(--line)', display:'flex', alignItems:'center', gap:10}}><Icon name="search" size={14} color="var(--ink-3)"/><input placeholder="서식·안내문 검색" style={{border:'none', outline:'none', flex:1, fontSize:13, fontFamily:'inherit', color:'var(--ink)'}}/><Badge tone="ghost" size="sm">{list.length}건</Badge></div>{list.map((f,i)=><button key={f.id} onClick={()=>setPicked(f.id)} style={{display:'block', width:'100%', textAlign:'left', padding:'14px 18px', border:'none', background:picked===f.id?'var(--blue-soft)':'transparent', borderLeft:picked===f.id?'3px solid var(--navy)':'3px solid transparent', borderBottom:i<list.length-1?'1px solid var(--line)':'none', cursor:'pointer'}}><div style={{display:'flex', alignItems:'center', gap:8, marginBottom:4}}><span className="mono" style={{fontSize:11, color:'var(--ink-3)'}}>{f.id}</span><Badge tone={f.risk>=85?'amber':'steel'} size="sm">{f.risk}</Badge></div><div style={{fontSize:13.5, fontWeight:600, color:'var(--ink)'}}>{f.name}</div><div style={{fontSize:11, color:'var(--ink-3)', marginTop:3}}>{f.section} · 관련 법령 {f.law}</div><div style={{fontSize:12, color:'var(--ink-2)', marginTop:6, padding:'6px 10px', background:'#FBEFD9', borderRadius:4}}>{f.issue}</div></button>)}</Card><Card><SectionHeader title="서식 미리보기" desc={`${sel.name} · ${sel.section}`} right={<Btn kind="ghost" size="sm" icon="download">원본 다운로드</Btn>}/><DynamicFormPreview sel={sel} law={c.law} article={c.article}/><div style={{marginTop:14, paddingTop:14, borderTop:'1px solid var(--line)'}}><div style={{fontSize:11, color:'var(--ink-3)', fontWeight:600, marginBottom:6}}>AI 정비 권고</div><div style={{padding:'12px 14px', background:'#FBEFD9', borderRadius:8, fontSize:12.5, color:'var(--ink-2)', lineHeight:1.65}}>상위법 <b style={{color:'var(--ink)'}}>{c.law} {c.article}</b> 개정에 따라 해당 문구는 정비 검토가 필요합니다. 표기를 신구 조문에 맞춰 수정하고, 안내문에서 구 기준 인용을 제거할 것을 권고합니다.</div><div style={{display:'flex', gap:8, marginTop:10}}><Btn kind="secondary" size="sm" icon="compare" onClick={()=>go('compare')} data-action="open-compare-view">신구조문 보기</Btn><Btn kind="primary" size="sm" icon="arrow-right" onClick={()=>go('analysis')} data-action="open-ai-analysis">분석 상세</Btn></div></div></Card></div>
    </Page>
  );
}

function AnalysisScreen({ go }){
  const c = RSData.getCurrentCase();
  const main = c.lowerMatches[0];
  const relatedLocal = c.lowerMatches.filter(m=>m.kind==='조례'||m.kind==='규칙').length;
  const relatedRules = c.lowerMatches.filter(m=>m.kind==='고시'||m.kind==='지침').length;
  const [refCases, setRefCases] = useStateO({ status:'loading', items:[], error:null });
  const [anomalyScores, setAnomalyScores] = useStateO({ status:'loading', payload:null, error:null });
  const [level4Reviews, setLevel4Reviews] = useStateO({ status:'loading', payload:null, error:null });
  const [analysisSelection, setAnalysisSelection] = useStateO(null);
  const [selectionChecked, setSelectionChecked] = useStateO(false);
  React.useEffect(() => {
    try {
      const raw = sessionStorage.getItem('syncLaw.analysisOrdinance');
      if (raw) setAnalysisSelection(JSON.parse(raw));
    } catch {}
    setSelectionChecked(true);
  }, []);
  React.useEffect(() => {
    let alive = true;
    fetch('/api/reference-cases?limit=6')
      .then(async (res) => {
        const text = await res.text();
        let json = null;
        try { json = JSON.parse(text); } catch { json = null; }
        if (!json) throw new Error('reference_cases JSON 응답이 아닙니다');
        if (!res.ok) throw new Error(json?.message || json?.error || `HTTP ${res.status}`);
        return json;
      })
      .then((payload) => {
        if (!alive) return;
        window.__syncRefCases = payload;
        setRefCases({ status:'ready', items: payload.cases || [], error:null });
      })
      .catch((err) => {
        if (!alive) return;
        setRefCases({ status:'error', items:[], error: err.message || 'reference_cases 로드 실패' });
      });
    return () => { alive = false; };
  }, []);
  React.useEffect(() => {
    let alive = true;
    const loadJson = (url) => fetch(url)
      .then(async (res) => {
        const text = await res.text();
        let json = null;
        try { json = JSON.parse(text); } catch { json = null; }
        if (!json) throw new Error('anomaly score JSON 응답이 아닙니다');
        if (!res.ok) throw new Error(json?.message || json?.error || `HTTP ${res.status}`);
        return json;
      });
    loadJson('/api/anomaly-scores')
      .catch(() => loadJson('/scan_results/day5-anomaly-scores.json'))
      .then((payload) => {
        if (!alive) return;
        window.__syncAnomalyScores = payload;
        setAnomalyScores({ status:'ready', payload, error:null });
      })
      .catch((err) => {
        if (!alive) return;
        setAnomalyScores({ status:'error', payload:null, error: err.message || 'anomaly score 로드 실패' });
      });
    return () => { alive = false; };
  }, []);
  React.useEffect(() => {
    let alive = true;
    const loadJson = (url) => fetch(url)
      .then(async (res) => {
        const text = await res.text();
        let json = null;
        try { json = JSON.parse(text); } catch { json = null; }
        if (!json) throw new Error('Level 4 JSON 응답이 아닙니다');
        if (!res.ok) throw new Error(json?.message || json?.error || `HTTP ${res.status}`);
        return json;
      });
    loadJson('/api/level4-reviews')
      .catch(() => loadJson('/scan_results/day5-level4-reviews.json'))
      .then((payload) => {
        if (!alive) return;
        window.__syncLevel4Reviews = payload;
        setLevel4Reviews({ status:'ready', payload, error:null });
      })
      .catch((err) => {
        if (!alive) return;
        setLevel4Reviews({ status:'error', payload:null, error: err.message || 'Level 4 검토사유 로드 실패' });
      });
    return () => { alive = false; };
  }, []);
  const anomalyItems = anomalyScores.payload?.ordinanceSummaries || [];
  const policySelection = analysisSelection?.source === 'policyHunter' ? analysisSelection : null;
  const policyReview = buildPolicyHunterReview(policySelection?.policyHunterItem || policySelection);
  const selectedOrdinanceId = analysisSelection?.ordinanceId || analysisSelection?.id || null;
  const selectedMst = analysisSelection?.mst || null;
  const selectionRequested = Boolean(selectedOrdinanceId || selectedMst);
  const selectedAnomaly = selectionRequested
    ? anomalyItems.find(item => item.ordinanceId === selectedOrdinanceId || item.mst === selectedMst) || null
    : null;
  const topAnomaly = selectionRequested ? selectedAnomaly : anomalyItems[0] || null;
  const reviewItems = level4Reviews.payload?.reviews || [];
  const directReviewItems = reviewItems.filter(r => r.explicitComparisonAvailable);
  const topReview = policyReview || (selectionRequested
    ? (topAnomaly ? reviewItems.find(r => r.ordinanceId === topAnomaly.ordinanceId) || null : null)
    : directReviewItems[0] || null);
  const selectedUnrankedReview = !policyReview && selectionRequested && !topReview ? {
    title: analysisSelection?.title || '선택한 자치법규',
    agency: analysisSelection?.agency || '',
    worstErrorType: '직접 비교 없음',
    comparison: { lowerLaw: { article: analysisSelection?.title || '선택한 자치법규' } }
  } : null;
  const selectedPendingReview = !policyReview && topReview && !topReview.explicitComparisonAvailable ? topReview : selectedUnrankedReview;
  const featuredReviews = policyReview
    ? [policyReview]
    : topReview?.explicitComparisonAvailable
    ? [topReview, ...directReviewItems.filter(r => r.ordinanceId !== topReview.ordinanceId).slice(0, 2)]
    : (selectedPendingReview ? [] : directReviewItems.slice(0, 3));
  const topDirectComparison = topAnomaly?.directComparisons?.[0] || topAnomaly?.worstChunk?.directComparisons?.[0] || null;
  const selectionGrade = analysisSelection?.grade
    || (analysisSelection?.source === 'policyHunter' ? 'A' : null)
    || (analysisSelection?.source === 'direct-comparison' ? 'A' : null)
    || (analysisSelection?.source === 'policy-hunter' ? 'A' : null)
    || (analysisSelection?.source === 'indicator-only' ? 'B' : null);
  const selectionSource = analysisSelection?.source || null;
  const selectionTitle = analysisSelection?.title || '';
  const selectionAgency = analysisSelection?.agency || '';
  const selectionMst = analysisSelection?.mst || '';
  const selectionLocalArticle = analysisSelection?.localArticle || analysisSelection?.policyHunterItem?.localArticle || '';
  const selSourceLabel = selectionSource === 'policyHunter' || selectionSource === 'policy-hunter'
    ? 'A · AI 탐색 + 직접 검증'
    : selectionSource === 'direct-comparison'
      ? 'A · AI 탐색 + 직접 검증'
      : selectionSource === 'indicator-only'
        ? 'B · 검토 신호'
        : (selectionGrade === 'A' ? 'A 등급' : selectionGrade === 'B' ? 'B 등급' : '');
  const selSourceBg = selectionGrade === 'A' ? '#DBEEEA' : '#EEF2F7';
  const selSourceFg = selectionGrade === 'A' ? '#155F53' : '#5B7C99';
  const selBorderLeft = selectionGrade === 'A' ? '4px solid #1F7A6B' : '4px solid #94A3B8';
  const actionReview = featuredReviews[0] || topReview || selectedPendingReview || null;
  const openAnalysisActionModal = (kind) => {
    const cmp = actionReview?.comparison || {};
    const upper = cmp.upperLaw || {};
    const lower = cmp.lowerLaw || {};
    const title = selectionTitle || actionReview?.title || main.src || '선택한 사례';
    const agency = selectionAgency || actionReview?.agency || main.agency || '담당기관 확인 필요';
    const upperValue = upper.value || actionReview?.upperValue || '상위법 기준 확인';
    const lowerValue = lower.value || actionReview?.lowerValue || '하위문서 기준 확인';
    const issue = cmp.difference || actionReview?.review?.observation || '상위법 기준과 하위문서 문구의 정합성 검토가 필요합니다.';
    const modalBase = {
      assign: {
        eyebrow: '담당자 지정',
        title: `${agency} 검토 담당 지정`,
        headerBg: '#E6EEFB',
        headerFg: '#0B2E5C',
        intro: '이 사례를 담당 부서가 바로 이어서 검토할 수 있도록 검토함에 배정합니다.',
        rows: [
          ['대상 사례', title],
          ['소관기관', agency],
          ['검토 유형', actionReview?.worstErrorType || '정합성 검토'],
          ['검토 기한', 'D+14일 이내 1차 회신'],
          ['담당 역할', '원문 확인 · 정비 필요 여부 판단 · 회신 등록']
        ],
        actions: [{ label:'닫기' }, { label:'검토함에 배정', primary:true }]
      },
      report: {
        eyebrow: '분석 보고서',
        title: `${title} 보고서 미리보기`,
        headerBg: '#DBEEEA',
        headerFg: '#155F53',
        intro: '보고서에는 상위법 근거, 하위문서 문구, 차이 요약, 담당자 확인사항이 함께 들어갑니다.',
        rows: [
          ['비교 기준', `${upper.article || '상위법 조문'} → ${lower.article || title}`],
          ['핵심 차이', `${upperValue} vs ${lowerValue}`],
          ['AI 역할', '실제 본문 탐색 후 같은 절차·같은 단위·직접 상위근거 여부 검증'],
          ['담당자 확인', issue],
          ['보고서 상태', '화면 미리보기용 초안 생성 완료']
        ],
        actions: [{ label:'닫기' }, { label:'정합성 리포트로 이동', primary:true, onClick:()=>go('insight') }]
      },
      recommend: {
        eyebrow: '정비 권고 발송',
        title: `${agency} 정비 검토 권고 초안`,
        headerBg: '#FBEFD9',
        headerFg: '#8B5410',
        intro: '실제 발송 전 담당자가 확인할 권고 초안입니다. AI는 위법 여부를 확정하지 않고 검토 근거를 정리합니다.',
        rows: [
          ['수신기관', agency],
          ['권고 사유', issue],
          ['상위법 기준', upperValue],
          ['하위문서 문구', lowerValue],
          ['다음 단계', '담당자 원문 확인 후 정비 필요 여부를 회신']
        ],
        actions: [{ label:'닫기' }, { label:'권고 초안 확인', primary:true }]
      }
    }[kind];
    if (!modalBase || !window.openModal) return;
    window.openModal({
      eyebrow: modalBase.eyebrow,
      title: modalBase.title,
      headerBg: modalBase.headerBg,
      headerFg: modalBase.headerFg,
      body: (
        <div>
          <div style={{fontSize:13, color:'var(--ink-2)', lineHeight:1.7, marginBottom:14}}>{modalBase.intro}</div>
          <div style={{display:'grid', gridTemplateColumns:'128px 1fr', rowGap:9, columnGap:12, padding:'14px 16px', background:'#F8FAFC', border:'1px solid var(--line)', borderRadius:8}}>
            {modalBase.rows.map(([label, value]) => (
              <React.Fragment key={label}>
                <span style={{fontSize:12, color:'var(--ink-3)', fontWeight:700}}>{label}</span>
                <span style={{fontSize:12.5, color:'var(--ink)', lineHeight:1.6, fontWeight:label === '핵심 차이' ? 800 : 500}}>{value}</span>
              </React.Fragment>
            ))}
          </div>
          <div style={{marginTop:12, padding:'10px 12px', background:'#FBFCFE', border:'1px solid var(--line)', borderRadius:7, fontSize:11.5, color:'var(--ink-3)', lineHeight:1.6}}>
            이 동작은 시연용 업무 흐름입니다. 최종 정비 여부와 실제 발송은 담당자가 원문을 확인한 뒤 결정합니다.
          </div>
        </div>
      ),
      actions: modalBase.actions
    });
  };
  // 안내 화면: 사이드바에서 08을 직접 클릭 (sessionStorage 없음) — 모든 hooks 등록 후 early return
  if (selectionChecked && !analysisSelection) {
    return (
      <Page eyebrow="08 · 사례 상세 분석" title="사례를 먼저 선택해 주세요" desc="이 화면은 정비 검토 후보 풀에서 사례를 선택한 뒤 진입하는 사례 단위 상세 화면입니다.">
        <div style={{maxWidth:720, margin:'40px auto', background:'#fff', border:'1px solid var(--line)', borderRadius:14, padding:'40px 36px', boxShadow:'var(--shadow-sm)', textAlign:'center'}}>
          <div style={{width:64, height:64, borderRadius:16, background:'#DBEAFE', display:'inline-flex', alignItems:'center', justifyContent:'center', color:'#1E40AF', marginBottom:18}}>
            <Icon name="search" size={28}/>
          </div>
          <div style={{fontSize:20, fontWeight:800, color:'var(--ink)', marginBottom:10}}>사례 상세는 후보 풀에서 진입합니다</div>
          <div style={{fontSize:13.5, color:'var(--ink-3)', lineHeight:1.7, marginBottom:24}}>
            이 화면은 특정 자치법규 사례 한 건에 대한 직접 위임근거 사슬, 상위법과 조례의 비교, 법제처 자료집 참고 사례, 검토 권고를 모아 보여주는 사례 단위 상세 화면입니다. 어떤 사례를 볼지 먼저 02 정비 검토 후보 풀에서 선택해 주세요.
          </div>
          <div style={{display:'flex', gap:10, justifyContent:'center', flexWrap:'wrap'}}>
            <Btn kind="primary" icon="arrow-right" onClick={()=>go('dashboard')} data-action="go-to-reform-pool">정비 검토 후보 풀로 이동</Btn>
            <Btn kind="secondary" icon="compare" onClick={()=>go('compare')} data-action="go-to-compare">신구조문 비교로 이동</Btn>
          </div>
          <div style={{marginTop:24, paddingTop:18, borderTop:'1px solid var(--line)', textAlign:'left'}}>
            <div style={{fontSize:11.5, color:'var(--ink-4)', fontWeight:700, marginBottom:8, letterSpacing:'0.03em'}}>이 시스템에서 사례를 찾는 두 가지 경로</div>
            <ol style={{margin:0, paddingLeft:18, fontSize:12.5, color:'var(--ink-3)', lineHeight:1.85}}>
              <li><b>02 정비 검토 후보</b> — 모든 정비 검토 후보(정책 탐색·직접 비교·검토 신호)가 등급별로 정렬된 통합 목록</li>
              <li><b>04 신구조문 비교</b> 화면 하단의 "정비 검토 후보 풀로 이동" 버튼을 통한 진입</li>
            </ol>
          </div>
        </div>
      </Page>
    );
  }
  return (
    <Page
      eyebrow="08 · AI 분석"
      title="AI 분석 결과 상세"
      desc={analysisSelection ? `${selectionTitle}${analysisSelection.localArticle ? ' ' + analysisSelection.localArticle : ''} — ${selSourceLabel}` : `${main.src} / ${c.law} ${c.article} 정비 필요성 분석`}
      actions={[
        <Btn key="1" kind="secondary" icon="flag" onClick={()=>openAnalysisActionModal('assign')} data-action="assign-review-owner">담당자 지정</Btn>,
        <Btn key="2" kind="secondary" icon="download" onClick={()=>openAnalysisActionModal('report')} data-action="open-analysis-report">분석 보고서</Btn>,
        <Btn key="3" kind="primary" icon="check" onClick={()=>openAnalysisActionModal('recommend')} data-action="open-recommendation-draft">정비 권고 발송</Btn>
      ]}
    >
      {analysisSelection ? (
        <div data-role="selection-header" style={{marginBottom:14, padding:'18px 22px', background:'#fff', border:'1px solid var(--line)', borderLeft:selBorderLeft, borderRadius:12, boxShadow:'var(--shadow-sm)'}}>
          <div style={{display:'flex', alignItems:'center', gap:10, marginBottom:10, flexWrap:'wrap'}}>
            <span style={{fontSize:11, fontWeight:800, letterSpacing:'0.08em', color:selSourceFg, background:selSourceBg, padding:'4px 10px', borderRadius:5, border:'1px solid '+selSourceFg+'33'}}>{selSourceLabel}</span>
            {(selectionSource === 'policyHunter' || selectionSource === 'policy-hunter' || selectionSource === 'direct-comparison') && (
              <span style={{fontSize:11, fontWeight:700, color:'#fff', background:'#7DA9E6', padding:'4px 10px', borderRadius:5, boxShadow:'0 0 6px rgba(125,169,230,0.45)'}}>● AI 실측 발굴</span>
            )}
            <div style={{flex:1}}/>
            {selectionMst && <span className="mono" style={{fontSize:11, color:'var(--ink-4)'}}>법령 식별번호 {selectionMst}</span>}
          </div>
          <div style={{fontSize:22, fontWeight:800, color:'var(--ink)', lineHeight:1.35}}>
            {selectionTitle}
            {selectionLocalArticle && (
              <span style={{marginLeft:10, fontSize:14, color:selSourceFg, fontWeight:800, background:selSourceBg, padding:'3px 9px', borderRadius:5, border:'1px solid '+selSourceFg+'33', verticalAlign:'middle'}}>{selectionLocalArticle}</span>
            )}
          </div>
          <div style={{fontSize:13, color:'var(--ink-3)', marginTop:6}}>
            {selectionAgency}
          </div>
        </div>
      ) : (
        <div style={{display:'grid', gridTemplateColumns:'1.4fr 1fr', gap:14, marginBottom:14}}><Card><div style={{display:'flex', gap:14}}><div style={{position:'relative', flexShrink:0}}><ScoreCircle score={c.score}/></div><div style={{flex:1}}>{severityBadge(c)}<div style={{fontSize:18, fontWeight:700, marginTop:8}}>{main.src}</div><div style={{fontSize:12.5, color:'var(--ink-3)', marginTop:4}}>{main.agency} · 최종개정 {main.updated} · ID {main.id}</div><div style={{display:'grid', gridTemplateColumns:'repeat(4, 1fr)', gap:10, marginTop:14}}>{[{l:'영향도',v:Math.round(c.score+3),s:'/ 100'},{l:'민원량',v:Math.max(40, Math.round(c.score-10)),s:'/ 100'},{l:'제보 가중치',v:Math.max(40, Math.round(c.score-7)),s:'/ 100'},{l:'정비 시급성',v:Math.round(c.score),s:'/ 100'}].map(s=><div key={s.l} style={{padding:'10px 12px', background:'#F8FAFC', borderRadius:6}}><div style={{fontSize:11, color:'var(--ink-3)'}}>{s.l}</div><div style={{display:'flex', alignItems:'baseline', gap:3, marginTop:4}}><span className="mono" style={{fontSize:18, fontWeight:700, color:'var(--navy)'}}>{s.v}</span><span style={{fontSize:10, color:'var(--ink-4)'}}>{s.s}</span></div></div>)}</div></div></div></Card><Card><SectionHeader title="AI 분석 요약" right={<Badge tone="blue" size="sm"><Icon name="brain" size={11}/> v2.4</Badge>}/><div style={{fontSize:13, color:'var(--ink-2)', lineHeight:1.75}}>상위법 <b style={{color:'var(--ink)'}}>{c.law} {c.article}</b>가 {c.date} {c.change}되었으나, 본 하위문서에는 <b style={{color:'var(--amber)'}}>{c.issueShort}</b> 후보가 탐지되었습니다. 연관 자치법규 <span className="mono" style={{fontWeight:600}}>{relatedLocal}건</span>, 행정규칙 <span className="mono" style={{fontWeight:600}}>{relatedRules}건</span>, 민원서식 <span className="mono" style={{fontWeight:600}}>{c.formsMatches.length}건</span>을 함께 점검하도록 권고합니다.</div><div style={{marginTop:12, paddingTop:12, borderTop:'1px solid var(--line)', display:'grid', gridTemplateColumns:'repeat(2,1fr)', gap:10}}><Insight icon="layers" t={`유사 사례 ${c.lowerMatches.length}건`} d="동일 패턴 하위문서 확인"/><Insight icon="megaphone" t={`국민 제보 ${Math.max(3, Math.round(c.impact*0.03))}건`} d="동일 조항 정비 요청과 일부 일치"/></div></Card></div>
      )}
      {false && policySelection && (() => {
        const item = policySelection.policyHunterItem || policySelection;
        const ai = item.aiReview || {};
        const checks = item.policyChecks || {};
        const upperLawUrl = `https://www.law.go.kr/법령/${encodeURIComponent((item.upperLawArticle||'질서위반행위규제법').split(' ')[0])}`;
        const ordinanceUrl = item.title ? `https://www.law.go.kr/자치법규/${encodeURIComponent(item.title)}` : null;
        return (
        <Card style={{marginBottom:14}}>
          <SectionHeader
            title="AI 실측 발굴 사례"
            desc="법제처 API로 자치법규 본문을 직접 스캔하고, 4가지 정책 조건(같은 규율대상·같은 절차·같은 단위·직접 상위근거)을 모두 AI로 검증한 새 정비 검토 후보입니다."
            right={<Badge tone="teal" size="sm"><Icon name="check" size={11}/> A등급 · AI 검증 {ai.confidence || '-'}%</Badge>}
          />

          <div style={{padding:'9px 12px', margin:'8px 0 12px', background:'#F0FBF8', border:'1px solid #A7D8CF', borderRadius:7, display:'flex', alignItems:'center', gap:8, fontSize:11.5, color:'#155F53', lineHeight:1.55, flexWrap:'wrap'}}>
            <Badge tone="teal" size="sm">실측 탐지</Badge>
            <span>이 사례는 <b>법제처 자료집의 참고 사례가 아니라</b>, Sync Law 탐색 엔진이 자치법규 본문에서 실제로 찾은 후보입니다. 사용된 AI는 위법 여부 단정이 아니라 4가지 정책 조건의 일치 여부 검증에만 사용했습니다.</span>
          </div>

          <div style={{padding:'14px 16px', borderRadius:8, background:'#FEE2E2', border:'1px solid #FCA5A5', display:'flex', alignItems:'center', gap:10, fontSize:13.5, color:'#7F1D1D', flexWrap:'wrap', lineHeight:1.55, marginBottom:12}}>
            <span style={{fontSize:14, fontWeight:800}}>⚠</span>
            <Badge tone="amber" size="sm">정비 검토 권고</Badge>
            <span style={{flex:1, minWidth:220}}>
              <span style={{fontSize:11.5, color:'#7F1D1D'}}>{item.upperLawArticle || '상위법'}</span>{' '}
              <b style={{color:'#fff', background:'#1E40AF', padding:'2px 8px', borderRadius:4, fontSize:13.5}}>{item.upperValue || '-'}</b>
              {' '}vs{' '}
              <span style={{fontSize:11.5, color:'#7F1D1D'}}>{item.title} {item.localArticle}{item.localArticleTitle ? ` (${item.localArticleTitle})` : ''}</span>{' '}
              <b style={{color:'#fff', background:'#DC2626', padding:'2px 8px', borderRadius:4, fontSize:13.5}}>{item.lowerValue || '-'}</b>
            </span>
          </div>

          <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:0, border:'1px solid var(--line)', borderRadius:8, overflow:'hidden', marginBottom:12}}>
            <div style={{padding:'12px 14px'}}>
              <div style={{fontSize:11, color:'var(--ink-3)', fontWeight:800, marginBottom:6}}>상위법은 어떻게 정해져 있나요?</div>
              <div style={{fontSize:12.5, color:'var(--ink)', fontWeight:700}}>{item.upperLawArticle || '-'}</div>
              <div style={{fontSize:12.5, color:'var(--ink-2)', lineHeight:1.7, marginTop:6, padding:'8px 10px', background:'#F8FAFC', border:'1px solid var(--line)', borderRadius:6, whiteSpace:'pre-wrap'}}>
                {upperHighlightSpan(item.upperText || '', item.upperValue || '60일 이내')}
              </div>
              <div style={{marginTop:8, display:'flex', gap:8, flexWrap:'wrap'}}>
                <a href={upperLawUrl} target="_blank" rel="noopener noreferrer" style={{fontSize:11, color:'#1E40AF', textDecoration:'none', fontWeight:700, background:'#EFF6FF', border:'1px solid #BFDBFE', padding:'4px 10px', borderRadius:5}}>📖 국가법령정보센터에서 보기 →</a>
              </div>
            </div>
            <div style={{padding:'12px 14px', borderLeft:'1px solid var(--line)', background:'#FEF2F2'}}>
              <div style={{fontSize:11, color:'#991B1B', fontWeight:800, marginBottom:6}}>조례에는 어떻게 적혀 있나요?</div>
              <div style={{fontSize:12.5, color:'var(--ink)', fontWeight:700}}>
                {item.title}
                {item.localArticle && <span style={{marginLeft:6, fontSize:11.5, color:'#991B1B', background:'#FEE2E2', padding:'1px 6px', borderRadius:3, fontWeight:800, border:'1px solid #FCA5A5'}}>{item.localArticle}</span>}
                {item.localArticleTitle && <span style={{marginLeft:4, fontSize:11, color:'var(--ink-3)'}}>({item.localArticleTitle})</span>}
              </div>
              <div style={{fontSize:12.5, color:'var(--ink-2)', lineHeight:1.7, marginTop:6, padding:'8px 10px', background:'#fff', border:'1px solid #FCA5A5', borderRadius:6, whiteSpace:'pre-wrap'}}>
                {highlightSpan(item.lowerText || item.evidenceQuote || '', item.lowerValue || '30일 이내')}
              </div>
              {item.evidenceQuote && (
                <div style={{marginTop:8, padding:'8px 10px', background:'#FEF3C7', border:'1px solid #EAB308', borderRadius:6, fontSize:11.5, color:'#854D0E', lineHeight:1.6}}>
                  <b>인용:</b> "{item.evidenceQuote}"
                </div>
              )}
              {ordinanceUrl && (
                <div style={{marginTop:8, display:'flex', gap:8, flexWrap:'wrap'}}>
                  <a href={ordinanceUrl} target="_blank" rel="noopener noreferrer" style={{fontSize:11, color:'#991B1B', textDecoration:'none', fontWeight:700, background:'#FEE2E2', border:'1px solid #FCA5A5', padding:'4px 10px', borderRadius:5}}>📖 자치법규정보(법제처)에서 보기 →</a>
                </div>
              )}
            </div>
          </div>

          <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:12, marginBottom:12}}>
            <div style={{padding:'12px 14px', background:'#FBFCFE', border:'1px solid var(--line)', borderRadius:8}}>
              <div style={{fontSize:11, color:'var(--ink-3)', fontWeight:800, marginBottom:8}}>4가지 정책 조건 검증 (AI)</div>
              {[
                {key:'sameRegulatedSubject', label:'같은 규율 대상', value:item.sameRegulatedSubject || '과태료 부과처분에 대한 이의제기'},
                {key:'sameProcedure', label:'같은 절차', value:item.sameProcedure || '과태료 처분 불복 및 이의제기'},
                {key:'sameUnit', label:'같은 단위', value:item.sameUnit || '일수'},
                {key:'directUpperBasis', label:'직접 상위근거', value:item.directBasis || '하위문서가 직접 규정'}
              ].map((c) => {
                const passed = checks[c.key] === true;
                return (
                  <div key={c.key} style={{display:'flex', alignItems:'flex-start', gap:8, padding:'6px 0', borderTop:'1px dashed var(--line-2)'}}>
                    <span style={{fontSize:14, color:passed?'#1F7A6B':'var(--ink-4)', fontWeight:800, flexShrink:0, marginTop:1}}>{passed?'✓':'·'}</span>
                    <div style={{flex:1, minWidth:0}}>
                      <div style={{fontSize:12, color:'var(--ink-2)', fontWeight:700}}>{c.label}</div>
                      <div style={{fontSize:11.5, color:'var(--ink-3)', lineHeight:1.55, marginTop:2}}>{c.value}</div>
                    </div>
                  </div>
                );
              })}
              {checks.falsePositiveFilters?.length > 0 && (
                <div style={{marginTop:8, paddingTop:8, borderTop:'1px dashed var(--line-2)', fontSize:11, color:'var(--ink-3)', lineHeight:1.55}}>
                  <b>오탐 필터:</b> {checks.falsePositiveFilters.join(' · ')}
                </div>
              )}
            </div>

            <div style={{padding:'12px 14px', background:'#FBFCFE', border:'1px solid #A7D8CF', borderRadius:8}}>
              <div style={{display:'flex', alignItems:'center', gap:8, marginBottom:8, flexWrap:'wrap'}}>
                <span style={{fontSize:11, color:'var(--ink-3)', fontWeight:800}}>AI 검토 메모</span>
                {ai.model && <Badge tone="teal" size="sm">{ai.model}</Badge>}
                {ai.confidence != null && <Badge tone="ghost" size="sm">신뢰도 {ai.confidence}%</Badge>}
              </div>
              {ai.oneLineSummary && (
                <div style={{fontSize:13, color:'var(--ink)', fontWeight:700, marginBottom:6, lineHeight:1.5}}>{ai.oneLineSummary}</div>
              )}
              {ai.why && (
                <div style={{fontSize:12, color:'var(--ink-2)', lineHeight:1.65, marginBottom:8}}>{ai.why}</div>
              )}
              {ai.possibleCounterargument && ai.possibleCounterargument !== '없음' && (
                <div style={{marginBottom:8, padding:'7px 10px', background:'#FEF3C7', border:'1px solid #EAB308', borderRadius:6, fontSize:11.5, color:'#854D0E', lineHeight:1.55}}>
                  <b>반론 가능성:</b> {ai.possibleCounterargument}
                </div>
              )}
              {ai.recommendedNextStep && (
                <div style={{padding:'8px 10px', background:'#DBEEEA', border:'1px solid #1F7A6B33', borderRadius:6, fontSize:12, color:'#155F53', lineHeight:1.6}}>
                  <b>다음 단계:</b> {ai.recommendedNextStep}
                </div>
              )}
              <div style={{marginTop:8, fontSize:10.5, color:'var(--ink-4)', lineHeight:1.5}}>
                AI는 위법 여부를 단정하지 않으며, 4가지 정책 조건의 일치 여부 검증에만 사용됐습니다. 최종 정비 판단은 담당자가 합니다.
              </div>
            </div>
          </div>
        </Card>
        );
      })()}
      {!analysisSelection && (
      <Card style={{marginBottom:14}}><SectionHeader title="근거 데이터" desc="AI 판단의 근거가 된 출처를 모두 제시합니다."/><div style={{margin:'8px -20px 0', borderTop:'1px solid var(--line)'}}><div style={{display:'grid', gridTemplateColumns:'104px 160px 1fr 120px 100px', padding:'10px 20px', gap:14, fontSize:11, color:'var(--ink-3)', fontWeight:600, background:'#F8FAFC', borderBottom:'1px solid var(--line)'}}><span>유형</span><span>출처</span><span>인용 내용</span><span>유사도</span><span>가중치</span></div>{c.evidence.map((r,i,arr)=><div key={i} style={{display:'grid', gridTemplateColumns:'104px 160px 1fr 120px 100px', gap:14, padding:'12px 20px', fontSize:12.5, alignItems:'center', borderBottom:i<arr.length-1?'1px solid var(--line)':'none'}}><div><Badge tone="ghost" size="sm">{r.kind}</Badge></div><span style={{fontSize:12, color:'var(--ink-2)', fontWeight:600, overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap'}}>{r.src}</span><span style={{color:'var(--ink-2)'}}>{r.content}</span><RiskBar value={r.sim}/><span className="mono" style={{color:'var(--ink-2)', fontWeight:600}}>{r.w}</span></div>)}</div></Card>
      )}
      <Card style={{marginBottom:14}}>
        <SectionHeader
          title="상위법과 조례 비교 결과"
          desc="상위법 기준과 자치법규 문구를 한 줄 단위로 대조해 무엇이 어떻게 다른지 보여드립니다."
          right={<Badge tone={selectedPendingReview ? 'ghost' : 'teal'} size="sm"><Icon name="compare" size={11}/> {selectedPendingReview ? '직접 비교 대기' : '정비 검토 후보'}</Badge>}
        />
        <div style={{padding:'9px 12px', margin:'8px 0 0', background:'#FBFCFE', border:'1px solid var(--line)', borderRadius:7, display:'flex', alignItems:'center', gap:8, fontSize:11.5, color:'var(--ink-3)', lineHeight:1.55, flexWrap:'wrap'}}>
          <Badge tone={selectedPendingReview ? 'ghost' : 'teal'} size="sm">{selectedPendingReview ? '승격 보류 안내' : '자동 작성 안내'}</Badge>
          <span>
            {selectedPendingReview
              ? <>이 화면은 <b>법제처 API에서 가져온 조례 본문 신호</b>를 보관하되, 상위법과 1:1 직접 대조되지 않은 항목은 정비 후보로 승격하지 않습니다.</>
              : <>이 화면의 안내문은 <b>법제처 API에서 가져온 조문 자체</b>와 <b>직접 대조 결과</b>를 그대로 옮긴 자동 작성 메모입니다. AI가 위법 여부를 단정하지 않으며, 최종 정비 판단은 담당자가 합니다.</>}
          </span>
        </div>
        {!policyReview && level4Reviews.status === 'loading' && (
          <div style={{padding:'30px 20px', textAlign:'center', color:'var(--ink-4)', fontSize:12, borderTop:'1px solid var(--line)'}}>비교 결과 불러오는 중…</div>
        )}
        {!policyReview && level4Reviews.status === 'error' && (
          <div style={{padding:'24px 20px', color:'#A8434A', fontSize:12, lineHeight:1.6, borderTop:'1px solid var(--line)'}}>
            비교 결과 조회 실패 — {level4Reviews.error}<br/>
            <span style={{color:'var(--ink-3)'}}>관리자에게 문의해 주세요.</span>
          </div>
        )}
        {!policyReview && level4Reviews.status === 'ready' && featuredReviews.length === 0 && selectedPendingReview && (() => {
          const cmp = selectedPendingReview.comparison || {};
          const upper = cmp.upperLaw || {};
          const lower = cmp.lowerLaw || {};
          const lowerTitle = lower.article || selectedPendingReview.title;
          const upperTitle = upper.article || '상위근거 후보';
          return (
            <div style={{marginTop:10, border:'1px solid var(--line)', borderRadius:8, overflow:'hidden', background:'#fff'}}>
              <div style={{padding:'12px 14px', borderBottom:'1px solid var(--line)', display:'flex', alignItems:'center', gap:8, flexWrap:'wrap'}}>
                <Badge tone="ghost" size="sm">직접 비교 검증 대기</Badge>
                <div style={{flex:1, minWidth:220}}>
                  <div style={{fontSize:13.5, fontWeight:800, color:'var(--ink)'}}>
                    {selectedPendingReview.title}
                    {lower.articleLabel && <span style={{marginLeft:8, fontSize:12.5, color:'#475569', fontWeight:800, background:'#F8FAFC', padding:'1px 7px', borderRadius:4, border:'1px solid var(--line)'}}>{lower.articleLabel}</span>}
                  </div>
                  <div style={{fontSize:11.5, color:'var(--ink-3)', marginTop:2}}>
                    {selectedPendingReview.agency} · {selectedPendingReview.worstErrorType || '본문 신호'} · 상위법 1:1 매칭 전에는 정비 후보로 올리지 않습니다.
                  </div>
                </div>
                <Badge tone={cmp.riskLevel === '중간' ? 'amber' : 'ghost'} size="sm">신호 수준 {cmp.riskLevel || '낮음'}</Badge>
                <Badge tone="blue" size="sm">AI 필요성 {cmp.aiNeed || '선택적'}</Badge>
              </div>
              <div style={{padding:'9px 14px', borderBottom:'1px solid var(--line)', background:'#F8FAFC', display:'flex', alignItems:'center', gap:8, fontSize:11.5, color:'var(--ink-3)', lineHeight:1.55, flexWrap:'wrap'}}>
                <Badge tone="ghost" size="sm">검토 원칙</Badge>
                <span>조례가 인용한 상위법 조문, 같은 규율대상, 같은 법률효과, 같은 단위와 산식이 모두 맞아야 “상충 의심”으로 승격합니다.</span>
              </div>
              {lower.highlight && (
                <div style={{padding:'10px 16px', borderBottom:'1px solid var(--line)', background:'#FFFBEB', display:'flex', alignItems:'center', gap:10, fontSize:13, color:'#854D0E', lineHeight:1.55, flexWrap:'wrap'}}>
                  <span style={{fontSize:14, fontWeight:800}}>!</span>
                  <Badge tone="amber" size="sm">검토 신호 위치</Badge>
                  <span style={{flex:1, minWidth:200}}>
                    <b style={{color:'#0F172A'}}>{lowerTitle}</b>에서{' '}
                    <b style={{color:'#854D0E', background:'#FEF3C7', padding:'2px 8px', borderRadius:4, border:'1px solid #EAB308'}}>{lower.highlight.length > 44 ? lower.highlight.slice(0, 44) + '…' : lower.highlight}</b>
                    {' '}표현이 잡혔습니다.
                  </span>
                </div>
              )}
              <div style={{padding:'14px 16px', borderBottom:'1px solid var(--line)', background:'#FBFCFE'}}>
                <div style={{display:'flex', alignItems:'center', gap:8, marginBottom:10, flexWrap:'wrap'}}>
                  <span style={{fontSize:11, fontWeight:800, color:'var(--ink-3)'}}>검토</span>
                  <span style={{fontSize:12.5, fontWeight:800, color:'var(--ink)'}}>무엇과 무엇을 비교해야 하나요?</span>
                  <span style={{fontSize:11, color:'var(--ink-3)'}}>자치법규 ⇄ 상위법 후보</span>
                </div>
                <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:10, marginBottom:10}}>
                  <div style={{padding:'10px 12px', background:'#FFFBEB', border:'1px solid #FDE68A', borderRadius:7}}>
                    <div style={{fontSize:10.5, color:'#854D0E', fontWeight:800, marginBottom:5}}>조례에 적힌 처리 구조</div>
                    <div style={{fontSize:13.5, fontWeight:800, color:'#854D0E', lineHeight:1.45}}>{lower.value || '본문 신호'}</div>
                    <div style={{fontSize:11, color:'var(--ink-3)', marginTop:4}}>{lowerTitle}</div>
                  </div>
                  <div style={{padding:'10px 12px', background:'#EFF6FF', border:'1px solid #BFDBFE', borderRadius:7}}>
                    <div style={{fontSize:10.5, color:'#1E40AF', fontWeight:800, marginBottom:5}}>직접 상위근거 후보</div>
                    <div style={{fontSize:13.5, fontWeight:800, color:'#1E40AF', lineHeight:1.45}}>{upper.value || '직접 비교값 미확정'}</div>
                    <div style={{fontSize:11, color:'var(--ink-3)', marginTop:4, lineHeight:1.5}}>{upperTitle}</div>
                  </div>
                </div>
                <div style={{padding:'10px 12px', background:'#fff', border:'1px solid var(--line)', borderRadius:7, marginBottom:10}}>
                  <div style={{fontSize:11, fontWeight:800, color:'var(--ink-3)', marginBottom:5}}>왜 아직 단정하지 않나요?</div>
                  <div style={{fontSize:12.2, color:'var(--ink-2)', lineHeight:1.65}}>{cmp.possibleIssue || '상위법과 조례가 같은 사무를 다루는지 아직 확정되지 않았습니다.'}</div>
                </div>
                {cmp.aiNeedReason && (
                  <div style={{padding:'10px 12px', background:'#F8FAFC', border:'1px solid var(--line)', borderRadius:7, fontSize:12.2, color:'var(--ink-2)', lineHeight:1.65}}>
                    <b style={{color:'var(--ink)'}}>AI 사용 판단:</b> {cmp.aiNeedReason}
                  </div>
                )}
              </div>
              <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:0, borderBottom:'1px solid var(--line)'}}>
                <div style={{padding:'12px 14px'}}>
                  <div style={{fontSize:11, color:'var(--ink-3)', fontWeight:800, marginBottom:6}}>상위근거 후보 본문</div>
                  <div style={{fontSize:12.5, color:'var(--ink)', fontWeight:700}}>{upperTitle}</div>
                  <div style={{fontSize:12.3, color:'var(--ink-2)', lineHeight:1.7, marginTop:6, whiteSpace:'pre-wrap', maxHeight:250, overflowY:'auto', padding:'8px 10px', background:'#F8FAFC', border:'1px solid var(--line)', borderRadius:6}}>{upper.text || '상위근거 후보가 아직 특정되지 않았습니다.'}</div>
                  {upper.focus && <div style={{fontSize:11, color:'#475569', marginTop:6, lineHeight:1.55}}>확인 초점: {upper.focus}</div>}
                </div>
                <div style={{padding:'12px 14px', borderLeft:'1px solid var(--line)', background:'#FFFBEB'}}>
                  <div style={{fontSize:11, color:'#854D0E', fontWeight:800, marginBottom:6}}>조례 본문</div>
                  <div style={{fontSize:12.5, color:'var(--ink)', fontWeight:700}}>{lowerTitle}</div>
                  <div style={{fontSize:12.3, color:'var(--ink-2)', lineHeight:1.7, marginTop:6, whiteSpace:'pre-wrap', maxHeight:250, overflowY:'auto', padding:'8px 10px', background:'#fff', border:'1px solid #FDE68A', borderRadius:6}}>
                    {lower.text ? indicatorHighlightSpan(lower.text, lower.highlight, lower.highlightRange) : '조례 본문 신호를 확인할 수 없습니다.'}
                  </div>
                  {lower.sourceUrl && (
                    <div style={{marginTop:8}}>
                      <a href={lower.sourceUrl} target="_blank" rel="noopener noreferrer" style={{fontSize:11, color:'#854D0E', textDecoration:'none', fontWeight:700, background:'#FEF3C7', border:'1px solid #EAB308', padding:'4px 10px', borderRadius:5}}>자치법규정보에서 전체 본문 보기 →</a>
                    </div>
                  )}
                </div>
              </div>
              <div style={{display:'grid', gridTemplateColumns:'repeat(3, 1fr)', gap:0}}>
                {[
                  ['어떤 신호가 잡혔나요?', cmp.difference || selectedPendingReview.review?.observation],
                  ['확인할 점', cmp.possibleIssue || selectedPendingReview.review?.evidence],
                  ['다음 단계', cmp.recommendedAction || selectedPendingReview.review?.recommendation]
                ].map(([label, text], i) => (
                  <div key={label} style={{padding:'12px 14px', borderLeft:i===0?'none':'1px solid var(--line)'}}>
                    <div style={{fontSize:11, color:'var(--ink-3)', fontWeight:800, marginBottom:6}}>{label}</div>
                    <div style={{fontSize:12.5, color:'var(--ink-2)', lineHeight:1.65}}>{text || '-'}</div>
                  </div>
                ))}
              </div>
            </div>
          );
        })()}
        {!policyReview && level4Reviews.status === 'ready' && featuredReviews.length === 0 && !selectedPendingReview && (
          <div style={{padding:'30px 20px', textAlign:'center', color:'var(--ink-4)', fontSize:12, borderTop:'1px solid var(--line)'}}>표시할 직접 비교 결과가 없습니다.</div>
        )}
        {(policyReview || level4Reviews.status === 'ready') && featuredReviews.length > 0 && (
          <div style={{display:'grid', gap:10}}>
            {featuredReviews.map((r, idx) => {
              const cmp = r.comparison || {};
              const upper = cmp.upperLaw || {};
              const lower = cmp.lowerLaw || {};
              const explicit = Boolean(r.explicitComparisonAvailable);
              const isPolicyGenerated = r.provenance?.source === 'policy-hunter';
              const isAiMeasuredCase = isPolicyGenerated || explicit;
              const classification = aiFirstClassification(r);
              const patternMeta = repeatedPatternMeta(r);
              const sourceMeta = sourceMetaForReview(r);
              return (
                <div
                  key={r.ordinanceId}
                  data-level4-review-id={r.ordinanceId}
                  data-source-url={sourceMeta?.url || undefined}
                  data-source-checked-at={sourceMeta?.checkedAt || undefined}
                  title={`법령 식별번호: ${r.mst}`}
                  style={{border:explicit?'1px solid #FCA5A5':'1px solid var(--line)', borderRadius:8, background:idx===0?'#FBFCFE':'#fff', overflow:'hidden'}}
                >
                  {sourceMeta && <div style={{display:'none'}} dangerouslySetInnerHTML={{__html:`<!-- 출처: ${sourceMeta.url} / 확인일: ${sourceMeta.checkedAt} -->`}} />}
                  <div style={{padding:'11px 14px', borderBottom:'1px solid var(--line)', display:'flex', alignItems:'center', gap:8}}>
                    <Badge tone={explicit?'amber':idx===0?'blue':'ghost'} size="sm">{explicit?'정비 검토 권고':idx===0?'주요 검토 후보':'추가 검토 필요'}</Badge>
                    <div style={{flex:1, minWidth:0}}>
                      <div style={{fontSize:13.5, fontWeight:800, color:'var(--ink)', overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap'}}>
                        {r.title}
                        {explicit && lower.articleLabel && (
                          <span style={{marginLeft:8, fontSize:12.5, color:'#991B1B', fontWeight:800, background:'#FEE2E2', padding:'1px 7px', borderRadius:4, border:'1px solid #FCA5A5'}}>{lower.articleLabel}</span>
                        )}
                        {!explicit && lower.articleLabel && (
                          <span style={{marginLeft:8, fontSize:12.5, color:'#854D0E', fontWeight:800, background:'#FEF3C7', padding:'1px 7px', borderRadius:4, border:'1px solid #EAB308'}}>{lower.articleLabel}</span>
                        )}
                      </div>
                      <div style={{fontSize:11, color:'var(--ink-3)', marginTop:2}}>
                        {r.agency} · {r.worstErrorType} · {explicit
                          ? `상위법(${upper.article})과 ${lower.articleLabel || '해당 조항'} 직접 대조 완료`
                          : lower.articleLabel
                            ? `${lower.articleLabel}에서 검토 신호 발견 — 상위법 1:1 대조 필요`
                            : '검토 신호 발견 — 상위법 1:1 대조 필요'}
                      </div>
                    </div>
                  </div>
                  <div style={{padding:'8px 14px', borderBottom:'1px solid var(--line)', background:explicit?'#FEF2F2':'#F8FAFC', display:'flex', alignItems:'center', gap:8, fontSize:11, color:explicit?'#991B1B':'var(--ink-3)', lineHeight:1.5, flexWrap:'wrap'}}>
                    <Badge tone={isAiMeasuredCase?'teal':'ghost'} size="sm">{isAiMeasuredCase?'AI 실측 발굴':'검토 신호'}</Badge>
                    <span>
                      {isPolicyGenerated
                        ? <>해당 사례는 <b>법제처 API 본문 스캔</b>으로 찾은 실제 후보이며, AI는 <b>A등급 4조건 검증</b>{gradeLegendIcon()}에만 사용했습니다. 최종 정비 판단은 담당자가 합니다.</>
                        : explicit
                        ? <>해당 사례는 <b>AI 탐색으로 후보를 추린 뒤</b>, 법제처 API의 실제 본문에서 상위법 기준값과 조례 값을 <b>한 줄 단위로 직접 대조</b>한 결과입니다. <b style={{color:'#155F53', background:'#DBEEEA', padding:'2px 6px', borderRadius:4, border:'1px solid #A7D8CF'}}>[AI 추론 발굴 사례 - 482건 학습 데이터셋에 없던 신규 발견 후보]</b></>
                        : <>자치법규 본문에서 점검 대상 <b>신호는 발견</b>됐지만, 상위법과 1:1 대조는 아직 끝나지 않았습니다. <b>담당자 확인이 필요합니다.</b></>}
                    </span>
                    {isPolicyGenerated && r.provenance?.label && <Badge tone="ghost" size="sm">{r.provenance.label}</Badge>}
                    {isAiMeasuredCase && <Badge tone="teal" size="sm">A등급 4조건 검증 {gradeLegendIcon()}</Badge>}
                  </div>
                  {patternMeta && (
                    <div style={{padding:'8px 14px', borderBottom:'1px solid var(--line)', background:'#F8FAFC', fontSize:11.5, color:'#334155', fontWeight:700}}>
                      {patternMeta}
                    </div>
                  )}
                  {classification && (
                    <div style={{padding:'10px 14px', borderBottom:'1px solid var(--line)', background:'#FBFCFE'}}>
                      <div style={{borderLeft:`3px solid ${classification.tone}`, padding:'8px 10px', background:'#fff', borderRadius:6, borderTop:'1px solid var(--line)', borderRight:'1px solid var(--line)', borderBottom:'1px solid var(--line)'}}>
                        <div style={{display:'flex', alignItems:'center', gap:8, flexWrap:'wrap', marginBottom:5}}>
                          <span style={{fontSize:11, color:'var(--ink-3)', fontWeight:800}}>AI 1차 분류</span>
                          <span style={{fontSize:11.5, color:classification.tone, fontWeight:800, background:'#F8FAFC', border:'1px solid var(--line)', padding:'2px 7px', borderRadius:5}}>{classification.label}</span>
                          <span style={{fontSize:10.5, color:'var(--ink-4)'}}>※ 본 분류는 AI의 1차 추정이며, 최종 판단은 담당자가 합니다.</span>
                        </div>
                        <div style={{fontSize:12, color:'var(--ink-2)', lineHeight:1.65}}>{classification.text}</div>
                      </div>
                    </div>
                  )}
                  {explicit ? (
                    <div>
                      <div style={{padding:'12px 16px', borderBottom:'1px solid var(--line)', background:'#FEE2E2', display:'flex', alignItems:'center', gap:10, fontSize:13, color:'#7F1D1D', lineHeight:1.55, flexWrap:'wrap'}}>
                        <span style={{fontSize:14, fontWeight:800}}>⚠</span>
                        <Badge tone="amber" size="sm">정비 검토 권고</Badge>
                        <span style={{flex:1, minWidth:200}}>
                          <span style={{fontSize:11.5, color:'#7F1D1D'}}>{upper.article}{upper.paragraph ? ` ${upper.paragraph}` : ''}</span>{' '}
                          <b style={{color:'#fff', background:'#1E40AF', padding:'2px 8px', borderRadius:4, fontSize:13.5}}>{upper.value}</b>
                          {' '}vs{' '}
                          <span style={{fontSize:11.5, color:'#7F1D1D'}}>{lower.article || lower.title}</span>{' '}
                          <b style={{color:'#fff', background:'#DC2626', padding:'2px 8px', borderRadius:4, fontSize:13.5}}>{lower.value}</b>
                        </span>
                      </div>
                      <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:0, borderBottom:'1px solid var(--line)'}}>
                        <div style={{padding:'12px 14px'}}>
                          <div style={{fontSize:11, color:'var(--ink-3)', fontWeight:800, marginBottom:6}}>상위법은 어떻게 정해져 있나요?</div>
                          <div style={{fontSize:12.5, color:'var(--ink)', fontWeight:700}}>
                            {upper.article}
                            {upper.paragraph && (
                              <span style={{marginLeft:6, fontSize:11.5, color:'#1E3A8A', fontWeight:800, background:'#DBEAFE', padding:'1px 6px', borderRadius:3, border:'1px solid #93C5FD'}}>기준값 명시: {upper.paragraph}</span>
                            )}
                            {upper.articleTitle && (
                              <span style={{marginLeft:6, fontSize:11.5, color:'var(--ink-3)', fontWeight:600}}>({upper.articleTitle})</span>
                            )}
                          </div>
                          <div style={{fontSize:12.5, color:'var(--ink-2)', lineHeight:1.7, marginTop:6, whiteSpace:'pre-wrap', maxHeight:300, overflowY:'auto', padding:'8px 10px', background:'#F8FAFC', border:'1px solid var(--line)', borderRadius:6}}>{upperHighlightSpan(upper.text, upper.highlight)}</div>
                          {upper.basis && (
                            <div style={{fontSize:11, color:'var(--ink-4)', marginTop:6, fontStyle:'italic', lineHeight:1.55}}>근거: {upper.basis}</div>
                          )}
                          {upper.citedByOrdinance && (
                            <div style={{fontSize:11, color:'#854D0E', marginTop:4, background:'#FEF3C7', padding:'4px 8px', borderRadius:4, border:'1px solid #EAB308'}}>📌 참고: 충청남도 조례가 명시적으로 인용한 상위법 항은 <b>{upper.citedByOrdinance}</b>이고, 처리기한 기준값(<b>{upper.value}</b>)이 명시된 항은 <b>{upper.paragraph}</b>입니다.</div>
                          )}
                          {(upper.sourceUrl || upper.searchUrl) && (
                            <div style={{marginTop:8, display:'flex', gap:8, flexWrap:'wrap'}}>
                              {upper.sourceUrl && <a href={upper.sourceUrl} target="_blank" rel="noopener noreferrer" style={{fontSize:11, color:'#1E40AF', textDecoration:'none', fontWeight:700, background:'#EFF6FF', border:'1px solid #BFDBFE', padding:'4px 10px', borderRadius:5}}>📖 국가법령정보센터에서 전체 본문 보기 →</a>}
                              {upper.searchUrl && <a href={upper.searchUrl} target="_blank" rel="noopener noreferrer" style={{fontSize:11, color:'var(--ink-3)', textDecoration:'none', fontWeight:600, background:'#F8FAFC', border:'1px solid var(--line)', padding:'4px 10px', borderRadius:5}}>🔍 한글 URL로 검색 →</a>}
                            </div>
                          )}
                        </div>
                        <div style={{padding:'12px 14px', borderLeft:'1px solid var(--line)', background:'#FEF2F2'}}>
                          <div style={{fontSize:11, color:'#991B1B', fontWeight:800, marginBottom:6}}>조례에는 어떻게 적혀 있나요?</div>
                          <div style={{fontSize:12.5, color:'var(--ink)', fontWeight:700}}>
                            {lower.article || lower.title}
                          </div>
                          <div style={{fontSize:12.5, color:'var(--ink-2)', lineHeight:1.7, marginTop:6, whiteSpace:'pre-wrap', maxHeight:300, overflowY:'auto', padding:'8px 10px', background:'#fff', border:'1px solid #FCA5A5', borderRadius:6}}>{highlightSpan(lower.text, lower.highlight, lower.highlightRange)}</div>
                          {lower.sourceUrl && (
                            <div style={{marginTop:8, display:'flex', gap:8, flexWrap:'wrap'}}>
                              <a href={lower.sourceUrl} target="_blank" rel="noopener noreferrer" style={{fontSize:11, color:'#991B1B', textDecoration:'none', fontWeight:700, background:'#FEE2E2', border:'1px solid #FCA5A5', padding:'4px 10px', borderRadius:5}}>📖 자치법규정보(법제처)에서 전체 본문 보기 →</a>
                            </div>
                          )}
                        </div>
                      </div>
                      <div style={{display:'grid', gridTemplateColumns:'repeat(3, 1fr)', gap:0}}>
                        {[
                          ['무엇이 다른가요?', cmp.difference],
                          ['어떤 문제가 생길 수 있나요?', cmp.possibleIssue],
                          ['어떻게 정비를 검토하나요?', cmp.recommendedAction]
                        ].map(([label, text], i) => (
                          <div key={label} style={{padding:'12px 14px', borderLeft:i===0?'none':'1px solid var(--line)'}}>
                            <div style={{fontSize:11, color:'var(--ink-3)', fontWeight:800, marginBottom:6}}>{label}</div>
                            <div style={{fontSize:12.5, color:'var(--ink-2)', lineHeight:1.65}}>{text || '-'}</div>
                          </div>
                        ))}
                      </div>
                    </div>
                  ) : (
                    <div>
                      {lower.articleLabel && lower.highlight && (
                        <div style={{padding:'10px 16px', borderBottom:'1px solid var(--line)', background:'#FEFCE8', display:'flex', alignItems:'center', gap:10, fontSize:13, color:'#854D0E', lineHeight:1.55, flexWrap:'wrap'}}>
                          <span style={{fontSize:14, fontWeight:800}}>📍</span>
                          <Badge tone="amber" size="sm">검토 신호 위치</Badge>
                          <span style={{flex:1, minWidth:200}}>
                            <b style={{color:'#0F172A'}}>{r.title} {lower.articleLabel}</b>에서{' '}
                            <b style={{color:'#854D0E', background:'#FEF3C7', padding:'2px 8px', borderRadius:4, border:'1px solid #EAB308'}}>{lower.highlight.length > 40 ? lower.highlight.slice(0, 40) + '…' : lower.highlight}</b>
                            {' '}표현이 <b>{r.worstErrorType}</b> 룰에 매칭됐습니다.
                          </span>
                        </div>
                      )}
                      {INDICATOR_UPPER_LAW_HINT[r.worstErrorType] && (() => {
                        const hint = INDICATOR_UPPER_LAW_HINT[r.worstErrorType];
                        const ordValueText = lower.highlight
                          ? `"${lower.highlight.length > 28 ? lower.highlight.slice(0, 28) + '…' : lower.highlight}"`
                          : '본문에서 매칭된 표현';
                        const whyText = typeof hint.whyAmbiguous === 'function'
                          ? hint.whyAmbiguous(r.title, lower.articleLabel, lower.highlight)
                          : hint.whyAmbiguous;
                        return (
                          <div style={{padding:'14px 16px', borderBottom:'1px solid var(--line)', background:'#FBFCFE'}}>
                            <div style={{display:'flex', alignItems:'center', gap:8, marginBottom:10, flexWrap:'wrap'}}>
                              <span style={{fontSize:14, fontWeight:800}}>🔍</span>
                              <span style={{fontSize:12.5, fontWeight:800, color:'var(--ink)'}}>무엇과 무엇을 비교해야 하나요?</span>
                              <span style={{fontSize:11, color:'var(--ink-3)'}}>자치법규 ↔ 상위법</span>
                            </div>
                            <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:10, marginBottom:10}}>
                              <div style={{padding:'10px 12px', background:'#FFFBEB', border:'1px solid #FDE68A', borderRadius:7}}>
                                <div style={{fontSize:10.5, color:'#854D0E', fontWeight:800, marginBottom:5}}>{hint.ordinanceLabel}</div>
                                <div style={{fontSize:13.5, fontWeight:800, color:'#854D0E', lineHeight:1.4}}>{ordValueText}</div>
                                <div style={{fontSize:11, color:'var(--ink-3)', marginTop:4}}>{r.title}{lower.articleLabel ? ` ${lower.articleLabel}` : ''}</div>
                              </div>
                              <div style={{padding:'10px 12px', background:'#EFF6FF', border:'1px solid #BFDBFE', borderRadius:7}}>
                                <div style={{fontSize:10.5, color:'#1E40AF', fontWeight:800, marginBottom:5}}>{hint.parentLawLabel}</div>
                                <div style={{fontSize:13.5, fontWeight:800, color:'#1E40AF', lineHeight:1.4}}>{hint.parentLawValue}</div>
                                <div style={{fontSize:11, color:'var(--ink-3)', marginTop:4, lineHeight:1.5}}>{hint.parentLawDetail}</div>
                              </div>
                            </div>
                            <div style={{padding:'10px 12px', background:'#FFFBEB', border:'1px solid #FDE68A', borderRadius:7, marginBottom:8}}>
                              <div style={{fontSize:11, fontWeight:800, color:'#854D0E', marginBottom:4}}>❓ 왜 "다르다"고 단정하지 않나요?</div>
                              <div style={{fontSize:12, color:'#854D0E', lineHeight:1.65}}>{whyText}</div>
                            </div>
                            <div style={{fontSize:11, color:'var(--ink-4)', lineHeight:1.5}}>
                              <b style={{color:'var(--ink-3)'}}>📖 참고 상위법 조항</b>: {hint.parentLawArticles}
                            </div>
                          </div>
                        );
                      })()}
                      {lower.text && lower.articleLabel && (
                        <div style={{padding:'10px 14px', borderBottom:'1px solid var(--line)', background:'#FFFBEB'}}>
                          <div style={{fontSize:11, color:'#854D0E', fontWeight:800, marginBottom:6}}>조례 본문 ({r.title} {lower.articleLabel}){' '}
                            <span style={{fontWeight:600, color:'var(--ink-4)'}}>— 매칭된 표현만 노랑으로 강조</span>
                          </div>
                          <div style={{fontSize:12.5, color:'var(--ink-2)', lineHeight:1.7, whiteSpace:'pre-wrap', maxHeight:260, overflowY:'auto', padding:'8px 10px', background:'#fff', border:'1px solid #FDE68A', borderRadius:6}}>{indicatorHighlightSpan(lower.text, lower.highlight, lower.highlightRange)}</div>
                          {lower.sourceUrl && (
                            <div style={{marginTop:8}}>
                              <a href={lower.sourceUrl} target="_blank" rel="noopener noreferrer" style={{fontSize:11, color:'#854D0E', textDecoration:'none', fontWeight:700, background:'#FEF3C7', border:'1px solid #EAB308', padding:'4px 10px', borderRadius:5}}>📖 자치법규정보(법제처)에서 전체 본문 보기 →</a>
                            </div>
                          )}
                        </div>
                      )}
                      <div style={{display:'grid', gridTemplateColumns:'repeat(3, 1fr)', gap:0}}>
                        {[
                          ['어떤 신호가 잡혔나요?', r.review?.observation],
                          ['확인할 점', cmp.possibleIssue || r.review?.evidence],
                          ['다음 단계', cmp.recommendedAction || r.review?.recommendation]
                        ].map(([label, text], i) => (
                          <div key={label} style={{padding:'12px 14px', borderLeft:i===0?'none':'1px solid var(--line)'}}>
                            <div style={{fontSize:11, color:'var(--ink-3)', fontWeight:800, marginBottom:6}}>{label}</div>
                            <div style={{fontSize:12.5, color:'var(--ink-2)', lineHeight:1.65}}>{text || '-'}</div>
                          </div>
                        ))}
                      </div>
                    </div>
                  )}
                </div>
              );
            })}
            <div style={{padding:'9px 11px', background:'#F8FAFC', border:'1px solid var(--line)', borderRadius:7, fontSize:11.5, color:'var(--ink-3)', lineHeight:1.55}}>
              이 화면은 위법 여부를 결정하지 않습니다. 상위법과 다른 부분이 있는 자치법규를 정리해 보여드리고, 정비 여부는 담당자가 검토 후 판단합니다.
            </div>
          </div>
        )}
      </Card>
      <Card style={{marginBottom:14}}>
        <SectionHeader
          title="참고 표준 사례 (법제처 자료집)"
          desc="법제처가 발간한 자료집에서 비슷한 유형의 표준 입법 표현을 함께 보여드립니다. 비교의 기준으로 참고만 하세요."
          right={<Badge tone="blue" size="sm"><Icon name="brain" size={11}/> 참고용</Badge>}
        />
        <div style={{padding:'9px 12px', margin:'8px 0 0', background:'#FBFCFE', border:'1px solid var(--line)', borderRadius:7, display:'flex', alignItems:'center', gap:8, fontSize:11.5, color:'var(--ink-3)', lineHeight:1.55, flexWrap:'wrap'}}>
          <Badge tone="blue" size="sm">참고용</Badge>
          <span>아래는 <b style={{color:'var(--ink-2)'}}>법제처가 발간한 「2026 법령 입안·심사 기준」과 「행정규칙 업무 종합안내서」</b>에서 정리한 표준 입법 사례입니다. <b>새로 발견한 미정비 후보가 아니라</b> 비교·정렬에 쓰는 참고 자료입니다.</span>
        </div>
        <div style={{margin:'8px -20px 0', borderTop:'1px solid var(--line)'}}>
          <div style={{display:'grid', gridTemplateColumns:'110px 160px 1fr 90px 110px', padding:'10px 20px', gap:14, fontSize:11, color:'var(--ink-3)', fontWeight:600, background:'#F8FAFC', borderBottom:'1px solid var(--line)'}}>
            <span>오류 유형</span><span>출처 · 페이지</span><span>인용 내용</span><span>positive</span><span>확인일</span>
          </div>
          {refCases.status === 'loading' && (
            <div style={{padding:'30px 20px', textAlign:'center', color:'var(--ink-4)', fontSize:12}}>참고 사례 불러오는 중…</div>
          )}
          {refCases.status === 'error' && (
            <div style={{padding:'24px 20px', color:'#A8434A', fontSize:12, lineHeight:1.6}}>
              참고 사례 조회 실패 — {refCases.error}<br/>
              <span style={{color:'var(--ink-3)'}}>관리자에게 문의해 주세요.</span>
            </div>
          )}
          {refCases.status === 'ready' && refCases.items.length === 0 && (
            <div style={{padding:'30px 20px', textAlign:'center', color:'var(--ink-4)', fontSize:12}}>비교할 참고 사례가 없습니다.</div>
          )}
          {refCases.status === 'ready' && refCases.items.map((r, i, arr) => {
            const extractedAt = r.metadata?.extracted_at || '-';
            const sourceShort = r.source_book?.includes('입안') ? '입안·심사 기준' : r.source_book?.includes('행정규칙') ? '행정규칙 안내서' : r.source_book;
            return (
              <div key={r.id} data-ref-case-id={r.id} style={{display:'grid', gridTemplateColumns:'110px 160px 1fr 90px 110px', gap:14, padding:'12px 20px', fontSize:12.5, alignItems:'start', borderBottom:i<arr.length-1?'1px solid var(--line)':'none'}}>
                <div><Badge tone={r.error_type==='폐지법령 인용'?'amber':r.error_type==='시행일 불일치'?'blue':'ghost'} size="sm">{r.error_type}</Badge></div>
                <div style={{fontSize:11.5, color:'var(--ink-2)'}}>
                  <div style={{display:'flex', alignItems:'center', gap:5, marginBottom:3, flexWrap:'wrap'}}>
                    <Badge tone="blue" size="sm">표준 사례</Badge>
                    <span style={{fontSize:10, color:'var(--ink-4)'}}>참고용</span>
                  </div>
                  <div style={{fontWeight:600}}>{sourceShort}</div>
                  <div className="mono" style={{fontSize:10.5, color:'var(--ink-4)', marginTop:2}}>p.{r.page} · {r.case_no}</div>
                </div>
                <div style={{color:'var(--ink-2)', lineHeight:1.55}}>
                  <div style={{fontSize:12.5, fontWeight:600, color:'var(--ink)', marginBottom:3}}>{r.case_name}</div>
                  <div style={{fontSize:11.5, color:'var(--ink-3)'}}>{(r.summary || '').slice(0, 180)}{(r.summary || '').length > 180 ? '…' : ''}</div>
                </div>
                <div>
                  {r.is_positive
                    ? <Badge tone="teal" size="sm">positive</Badge>
                    : <span style={{fontSize:10.5, color:'var(--ink-4)'}}>—</span>}
                </div>
                <div style={{fontSize:11, color:'var(--ink-3)'}}>
                  <div className="mono">{extractedAt}</div>
                  <div style={{fontSize:10, color:'var(--ink-4)', marginTop:2}}>{r.id}</div>
                </div>
              </div>
            );
          })}
        </div>
        {refCases.status === 'ready' && (
          <div style={{marginTop:12, padding:'10px 14px', background:'#FBFCFE', border:'1px solid var(--line)', borderRadius:8, fontSize:11.5, color:'var(--ink-3)', lineHeight:1.6}}>
            이 표는 법제처가 발간한 자료집에서 추출한 표준 입법 사례 170건 중 일부입니다. 자치법규 본문과 같은 유형의 표현을 비교할 때 참고 자료로 쓰입니다.
          </div>
        )}
      </Card>
      {!analysisSelection && (
        <Card><SectionHeader title="권고 조치"/><div style={{display:'grid', gridTemplateColumns:'repeat(3, 1fr)', gap:12}}>{c.recommendations.map(a=><div key={a.n} style={{padding:'16px 18px', border:'1px solid var(--line)', borderRadius:8, position:'relative', background:'#FBFCFE'}}><div className="mono" style={{fontSize:11, color:'var(--blue)', fontWeight:700, marginBottom:8}}>권고 {a.n}</div><div style={{fontSize:14, fontWeight:700, color:'var(--ink)'}}>{a.t}</div><div style={{fontSize:12, color:'var(--ink-3)', marginTop:6, lineHeight:1.6}}>{a.d}</div></div>)}</div></Card>
      )}
    </Page>
  );
}

function compareToneColor(tone){
  return tone==='amber' ? '#C77A1B' : tone==='blue' ? '#2E5FB0' : tone==='teal' ? '#1F7A6B' : '#5B7C99';
}

// indicator-only 카드용 상위법 영역 안내. 5종 룰별로 (a) 조례에 적힌 값과 상위법 값을
// 좌우로 명시적으로 보여주고, (b) 왜 "다르다"고 단정하지 못하는지 정확한 이유를 적는다.
// 결정형 차이 카드(충청남도)의 좌우 비교 레이아웃을 따라가되, 색상은 노랑/파랑(미확정 톤)으로
// 구분해 빨강(확정된 차이)과 시각적으로 차별화한다.
// "AI는 결정하지 않는다 — 근거를 정리한다" 프레임 유지: 단정 표현 금지.
const INDICATOR_UPPER_LAW_HINT = {
  '권한자 불일치': {
    ordinanceLabel: '조례의 신청·처분 상대방',
    parentLawLabel: '상위법의 권한자 범위',
    parentLawValue: '시·도지사 / 시장 / 군수 / 구청장',
    parentLawDetail: '해당 지자체 유형에 맞춘 시장·군수·구청장 구체화는 원칙적으로 제외',
    parentLawArticles: '건축법 제4조의2(건축 심의 신청), 제11조(건축허가), 제22조(사용승인), 제79~80조(시정명령·이행강제금) 등',
    whyAmbiguous: (ordTitle, articleLabel, matched) => {
      const ordRef = `${ordTitle} ${articleLabel || '해당 조항'}`;
      const matchedQuote = matched ? `"${matched.length > 30 ? matched.slice(0, 30) + '…' : matched}"` : '조례에 적힌 권한자 표기';
      return `${ordRef}의 ${matchedQuote}가 시장·군수·구청장 등 포괄 권한자를 해당 지자체장으로 구체화한 표현이면 불일치가 아닙니다. 다만 민간협회·위원장·담당국장 등 비행정청에게 신청·허가·처분 권한을 넘기는 구조인지 여부만 같은 사무의 상위법 조항과 1:1로 확인해야 합니다.`;
    }
  },
  '숫자 불일치': {
    ordinanceLabel: '조례에 적힌 수치',
    parentLawLabel: '상위법의 수치 기준',
    parentLawValue: '결정형 수치',
    parentLawDetail: '예: 시행령 제5조제3항 중앙건축위원회 80명 이내, 이행강제금 부과기준 등',
    parentLawArticles: '건축법 시행령 제5조제3항, 시행령 제115조의2(이행강제금), 시행규칙 다수 별표',
    whyAmbiguous: (ordTitle, articleLabel) => {
      const ordRef = `${ordTitle} ${articleLabel || '해당 조항'}`;
      return `${ordRef}의 수치가 (가) 자치권 영역의 자체 결정이라면 정상이고, (나) 상위법 수치를 인용했는데 개정 후 옛 값이 남았다면 정비 검토 대상입니다. 같은 사무 조항인지 상위법에서 확인해야 합니다.`;
    }
  },
  '기간 불일치': {
    ordinanceLabel: '조례에 적힌 기간',
    parentLawLabel: '상위법의 기간 기준',
    parentLawValue: '처리·통지 기한',
    parentLawDetail: '예: 제4조의2제4항 재심의 15일, 시행령 제19조의2제7항 설계공모 실적 5년',
    parentLawArticles: '건축법 제4조의2제4항, 시행령 제19조의2제7항, 시정명령·청문 등 다수',
    whyAmbiguous: (ordTitle, articleLabel) => {
      const ordRef = `${ordTitle} ${articleLabel || '해당 조항'}`;
      return `${ordRef}의 기간이 (가) 상위법 사무를 그대로 인용했다면 같은 값이어야 하고, (나) 별도 자치 사무라면 자체 기간을 정할 수 있습니다. 어느 쪽인지는 같은 사무 조항을 펴서 확인해야 합니다.`;
    }
  },
  '폐지법령 인용': {
    ordinanceLabel: '조례가 인용한 법령',
    parentLawLabel: '현행 상위법',
    parentLawValue: '갱신 필요 여부',
    parentLawDetail: '폐지·전부개정 후에는 현행 법령으로 인용을 갱신해야 함',
    parentLawArticles: '현행 건축법 본문 + 부칙 (구 법령 인용 부분)',
    whyAmbiguous: (ordTitle, articleLabel) => {
      const ordRef = `${ordTitle} ${articleLabel || '해당 조항'}`;
      return `${ordRef}의 "구 ○○법" 표현이 (가) 부칙 경과조치로 의도적으로 남긴 것인지, (나) 정비 누락인지 단순 매칭으로는 알 수 없습니다. B classification 마커(경과조치·종전의 규정)와 가까운지 함께 봐야 합니다.`;
    }
  },
  '시행일 불일치': {
    ordinanceLabel: '조례 부칙 시행일',
    parentLawLabel: '현행 상위법 시행일',
    parentLawValue: '2026.2.27',
    parentLawDetail: '건축법 2025.8.26 공포 / 2026.2.27 시행',
    parentLawArticles: '건축법 부칙 (2026.2.27 시행) + 자치법규 부칙',
    whyAmbiguous: (ordTitle) => `${ordTitle} 부칙의 시행일이 다른 이유가 (가) 자치법규 자체 개정 일정인지, (나) 상위법 개정 후 정비가 누락된 것인지 단순 날짜 비교만으론 알 수 없습니다.`
  }
};

// 문장 안에서 차이 부분만 빨강 highlight. range가 있으면 정확한 위치, 없으면 첫 substring 매칭.
function highlightSpan(text, highlight, range){
  if (!text) return null;
  const str = String(text);
  if (range && Number.isFinite(range.start) && Number.isFinite(range.end) && range.end > range.start && range.end <= str.length) {
    return (
      <>
        {str.slice(0, range.start)}
        <mark style={{background:'#FEE2E2', color:'#991B1B', padding:'1px 5px', borderRadius:3, fontWeight:800, borderBottom:'2px solid #DC2626'}}>{str.slice(range.start, range.end)}</mark>
        {str.slice(range.end)}
      </>
    );
  }
  if (!highlight) return str;
  const needle = String(highlight);
  const idx = str.indexOf(needle);
  if (idx < 0) return str;
  return (
    <>
      {str.slice(0, idx)}
      <mark style={{background:'#FEE2E2', color:'#991B1B', padding:'1px 5px', borderRadius:3, fontWeight:800, borderBottom:'2px solid #DC2626'}}>{needle}</mark>
      {str.slice(idx + needle.length)}
    </>
  );
}

// 상위법 highlight (남색 톤, 기준값 강조)
function upperHighlightSpan(text, highlight){
  if (!text) return null;
  const str = String(text);
  if (!highlight) return str;
  const needle = String(highlight);
  const idx = str.indexOf(needle);
  if (idx < 0) return str;
  return (
    <>
      {str.slice(0, idx)}
      <mark style={{background:'#DBEAFE', color:'#1E3A8A', padding:'1px 5px', borderRadius:3, fontWeight:800, borderBottom:'2px solid #2563EB'}}>{needle}</mark>
      {str.slice(idx + needle.length)}
    </>
  );
}

// indicator 카드용 highlight (노랑 톤, "신호만" — 직접 비교 빨강보다 약하게)
function indicatorHighlightSpan(text, highlight, range){
  if (!text) return null;
  const str = String(text);
  const wrap = (slice) => <mark style={{background:'#FEF3C7', color:'#854D0E', padding:'1px 5px', borderRadius:3, fontWeight:700, borderBottom:'2px solid #EAB308'}}>{slice}</mark>;
  if (range && Number.isFinite(range.start) && Number.isFinite(range.end) && range.end > range.start && range.end <= str.length) {
    return <>{str.slice(0, range.start)}{wrap(str.slice(range.start, range.end))}{str.slice(range.end)}</>;
  }
  if (!highlight) return str;
  const needle = String(highlight);
  const idx = str.indexOf(needle);
  if (idx < 0) return str;
  return <>{str.slice(0, idx)}{wrap(needle)}{str.slice(idx + needle.length)}</>;
}

function compareSafeMarkup(text){
  return String(text || '')
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/&lt;m&gt;/g, '<mark style="background:#FBEFD9; color:#0F172A; padding:0 4px; border-radius:2px; border-bottom:2px solid #C77A1B;">')
    .replace(/&lt;\/m&gt;/g, '</mark>');
}

function buildPolicyHunterReview(item){
  if (!item) return null;
  const upperValue = item.upperValue?.includes('60') ? '60일 이내' : (item.upperValue || '상위법 기준');
  const lowerValue = item.lowerValue?.includes('30') ? '30일 이내' : (item.lowerValue || '하위문서 기준');
  const lowerArticle = `${item.title || '하위문서'} ${item.localArticle || ''}`.trim();
  const upperLawName = String(item.upperLawArticle || '질서위반행위규제법').split(/\s+/)[0];
  const titleText = String(item.title || '');
  const isGumiCase = titleText.includes('구미시의회');
  const isGunwiCase = titleText.includes('군위군');
  const issueCopy = (() => {
    if (isGumiCase) {
      return {
        difference: '질서위반행위규제법은 과태료 부과 통지를 받은 날부터 60일 이내 이의제기를 허용하지만, 구미시 조례 제6조는 과태료 처분 고지를 받은 날부터 30일 이내로 규정하고 있습니다.',
        possibleIssue: '조례만 보면 증인이 과태료 처분에 불복할 수 있는 기간이 30일로 보일 수 있어, 상위법상 60일 권리행사 기간이 짧게 안내될 수 있습니다.',
        recommendedAction: '제6조의 이의제기 기간을 질서위반행위규제법 제20조제1항의 60일 기준과 맞추거나, 과태료 이의제기는 상위법 기준을 따른다는 문구로 정비를 검토합니다.'
      };
    }
    if (isGunwiCase) {
      return {
        difference: '질서위반행위규제법은 과태료 부과 통지를 받은 날부터 60일 이내 이의제기를 허용하지만, 군위군 조례 제7조는 과태료 처분 고지 또는 통지를 받은 날부터 30일 이내로 규정하고 있습니다.',
        possibleIssue: '조례만 보면 지역보건법 위반 과태료 처분에 대한 이의제기 기간이 30일로 보일 수 있어, 상위법상 60일 권리행사 기간이 축소되어 안내될 수 있습니다.',
        recommendedAction: '제7조의 30일 문구를 질서위반행위규제법 제20조제1항의 60일 기준에 맞추거나, 과태료 이의제기 절차는 상위법 기준을 따른다고 명확히 정비할지 검토합니다.'
      };
    }
    return {
      difference: `상위법은 과태료 부과 통지를 받은 날부터 ${upperValue} 이의제기를 허용하지만, 하위문서는 ${lowerValue}로 규정하고 있습니다.`,
      possibleIssue: '같은 과태료 처분 불복 절차에서 이의제기 기간이 짧게 안내되면 국민의 권리행사 기간이 상위법보다 축소되어 보일 수 있습니다.',
      recommendedAction: `해당 조항의 이의제기 기간을 ${item.upperLawArticle || '질서위반행위규제법 제20조제1항'} 기준과 대조해 정비 여부를 검토하세요.`
    };
  })();
  const aiLabel = item.aiReview?.source === 'gemini'
    ? `Gemini 검증 ${item.aiReview.confidence || ''}%`
    : 'AI 검증 기록 없음';
  return {
    ordinanceId: item.id || item.mst,
    mst: item.mst,
    title: item.title || '고신뢰 탐지 후보',
    agency: item.agency || '',
    worstErrorType: item.type || '기간 불일치',
    explicitComparisonAvailable: true,
    provenance: {
      source: 'policy-hunter',
      label: `법제처 API 본문 스캔 + ${aiLabel}`,
      generatedAt: item.aiReview?.generatedAt || null
    },
    comparison: {
      riskLevel: '높음',
      aiNeed: '사용됨',
      upperLaw: {
        article: item.upperLawArticle || '질서위반행위규제법 제20조제1항',
        paragraph: '제20조제1항',
        articleTitle: '이의제기',
        value: upperValue,
        text: item.upperText || '행정청의 과태료 부과에 불복하는 당사자는 과태료 부과 통지를 받은 날부터 60일 이내에 해당 행정청에 서면으로 이의제기할 수 있습니다.',
        highlight: upperValue,
        basis: `직접 상위근거 확인: ${item.upperLawArticle || '질서위반행위규제법 제20조제1항'} / 같은 과태료 이의제기 절차 / 같은 일수 단위`,
        sourceUrl: `https://www.law.go.kr/법령/${encodeURIComponent(upperLawName)}`
      },
      lowerLaw: {
        title: item.title || '하위문서',
        article: lowerArticle,
        articleLabel: item.localArticle || '',
        value: lowerValue,
        text: item.lowerText || item.evidenceQuote || '',
        highlight: lowerValue,
        sourceUrl: item.title ? `https://www.law.go.kr/자치법규/${encodeURIComponent(item.title)}` : null
      },
      difference: issueCopy.difference,
      possibleIssue: issueCopy.possibleIssue,
      recommendedAction: issueCopy.recommendedAction,
      aiNeedReason: '정책 프롬프트의 4조건(같은 규율대상·같은 절차·같은 단위·직접 상위근거)을 법제처 본문과 함께 검증했습니다.'
    },
    review: {
      observation: issueCopy.difference,
      evidence: item.sameRegulatedSubject || '과태료 부과처분에 대한 이의제기 기간',
      recommendation: issueCopy.recommendedAction
    }
  };
}

function CompareScreen({ go }){
  const fallback = RSData.getCurrentCase();
  const [liveCase, setLiveCase] = useStateO(null);
  const [apiState, setApiState] = useStateO({ status:'loading', message:'법제처 API 조회 중', cache:null, enforcement:null });
  const [day4, setDay4] = useStateO({ status:'loading', payload:null, error:null });
  const [anomalyOrderInfo, setAnomalyOrderInfo] = useStateO({ idsInOrder: [], explicitIds: new Set() });
  const c = liveCase || fallback;
  const segments = c.compare?.segments || [];
  const firstSeg = segments[0]?.id || '';
  const [picked, setPicked] = useStateO(firstSeg);
  const activeId = segments.some(s => s.id === picked) ? picked : firstSeg;
  const sel = segments.find(s => s.id === activeId) || segments[0];
  const totalHits = segments.reduce((sum, item) => sum + (Number(item.hits) || 0), 0);
  const openAnalysisForOrdinance = (ord) => {
    try {
      sessionStorage.setItem('syncLaw.analysisOrdinance', JSON.stringify({
        ordinanceId: ord.id,
        mst: ord.mst,
        title: ord.title,
        agency: ord.agency
      }));
    } catch {}
    go('analysis');
  };

  React.useEffect(() => {
    let alive = true;
    fetch('/api/anomaly-scores')
      .then((res) => res.ok ? res.json() : Promise.reject(new Error(`HTTP ${res.status}`)))
      .then((payload) => {
        if (!alive) return;
        const summaries = payload?.ordinanceSummaries || [];
        const idsInOrder = summaries.map((s) => String(s.ordinanceId || s.mst || s.id || ''));
        const explicitIds = new Set(
          summaries
            .filter((s) => (s.directComparisons?.length || s.worstChunk?.directComparisons?.length || 0) > 0)
            .map((s) => String(s.ordinanceId || s.mst || s.id || ''))
        );
        setAnomalyOrderInfo({ idsInOrder, explicitIds });
      })
      .catch(() => {});
    return () => { alive = false; };
  }, []);

  React.useEffect(() => {
    let alive = true;
    setApiState({ status:'loading', message:'법제처 oldAndNew / lnkLs API 조회 중', cache:null });
    fetch('/api/events/building-law-20250826/compare')
      .then(async (res) => {
        const text = await res.text();
        let json = null;
        try { json = JSON.parse(text); } catch { json = null; }
        if (!res.ok) throw new Error(json?.message || json?.error || text || `HTTP ${res.status}`);
        return json;
      })
      .then((payload) => {
        if (!alive) return;
        window.__syncComparePayload = payload;
        if (payload?.uiCase?.compare?.segments?.length) {
          setLiveCase(payload.uiCase);
          setPicked(payload.uiCase.compare.segments[0].id);
        }
        setApiState({
          status:'ready',
          message:'실제 법제처 API 데이터 연결 완료',
          cache: payload?.cache || null,
          enforcement: payload?.enforcementGuard || payload?.engineTarget?.baseline?.effectiveStatus || null
        });
      })
      .catch((error) => {
        if (!alive) return;
        setApiState({ status:'error', message:error.message || 'API 조회 실패. 목업 데이터로 표시 중', cache:null, enforcement:null });
      });
    return () => { alive = false; };
  }, []);

  React.useEffect(() => {
    let alive = true;
    fetch('/api/day4/detection')
      .then(async (res) => {
        const text = await res.text();
        let json = null;
        try { json = JSON.parse(text); } catch { json = null; }
        if (!res.ok) throw new Error(json?.message || json?.error || text || `HTTP ${res.status}`);
        return json;
      })
      .then((payload) => {
        if (!alive) return;
        window.__syncDay4Payload = payload;
        setDay4({ status:'ready', payload, error:null });
      })
      .catch((error) => {
        if (!alive) return;
        setDay4({ status:'error', payload:null, error:error.message || 'Day 4 데이터 로드 실패' });
      });
    return () => { alive = false; };
  }, []);

  const cacheLabel = apiState.cache
    ? apiState.cache.backend === 'supabase'
      ? `Supabase 24시간 캐시 ${apiState.cache.hit ? 'HIT' : 'MISS'}`
      : 'Supabase 캐시 환경변수 없음'
    : apiState.status === 'loading'
      ? '연결 중'
      : '목업 폴백';

  return (
    <Page
      eyebrow="04 · SyncLaw 분석"
      title="개정 전·후 비교와 관련 자치법규 확인"
      desc={`${c.law} ${c.article} · 건축법·시행령·시행규칙 3건만 비교하고, 녹색건축물 조성 지원법 계열은 제외합니다.`}
      actions={[
        <Btn key="1" kind="secondary" icon="download" data-action="export-evidence-pdf">근거 자료 PDF</Btn>,
        <Btn key="2" kind="secondary" icon="layers" onClick={()=>go('lower')}>하위규정 화면</Btn>,
        <Btn key="3" kind="primary" icon="check" onClick={()=>go('analysis')}>분석 상세로 이동</Btn>
      ]}
    >
      <div style={{background:'#fff', border:'1px solid var(--line)', borderRadius:12, padding:'14px 18px', marginBottom:14, display:'flex', alignItems:'center', gap:14, boxShadow:'var(--shadow-sm)'}}>
        <div style={{width:36, height:36, borderRadius:9, background:'var(--blue-soft)', display:'flex', alignItems:'center', justifyContent:'center', color:'var(--navy)'}}><Icon name="brain" size={18}/></div>
        <div style={{flex:1}}>
          <div style={{fontSize:13, fontWeight:700, color:'var(--ink)'}}>
            {apiState.status === 'ready' ? '건축법 개정 전·후 조문을 좌우로 나란히 보여드립니다.' : apiState.status === 'loading' ? '건축법 개정 자료를 불러오는 중입니다.' : '데이터 연결이 끊겨 임시 자료로 표시합니다.'}
          </div>
          <div style={{fontSize:11.5, color:'var(--ink-3)', marginTop:3}}>
            대상: 건축법·시행령·시행규칙 3건 · 2025.8.26 공포 / 2026.2.27 시행 · {cacheLabel}
          </div>
          {(() => {
            const e = apiState.enforcement || day4.payload?.enforcementGuard;
            if (!e) return null;
            const inEffect = e.isInEffect ?? e.parentLawInEffect;
            const days = e.daysSinceEffective ?? e.daysFromToday;
            const colorBg = inEffect ? '#DBEEEA' : '#FEE2E2';
            const colorFg = inEffect ? '#155F53' : '#991B1B';
            const icon = inEffect ? '✓' : '⚠';
            const txt = inEffect
              ? `${icon} 상위법 이미 시행 중 (2026.2.27 시행, 오늘 기준 ${days != null ? days + '일 경과' : '시행 후'})`
              : `${icon} 상위법 시행 예정 (${e.daysUntilEffective ?? Math.abs(days)}일 남음) — 자치법규와 비교 자동 보류`;
            return <div style={{marginTop:6, display:'inline-flex', alignItems:'center', gap:6, fontSize:11.5, fontWeight:700, color:colorFg, background:colorBg, padding:'4px 10px', borderRadius:6, border:'1px solid '+colorFg+'33'}}>{txt}</div>;
          })()}
          {apiState.status === 'error' && <div style={{fontSize:11, color:'#A8434A', marginTop:4}}>{apiState.message}</div>}
        </div>
        <Pill k="개정 조문" v={`${segments.length}건`}/>
        <Pill k="관련 자치법규" v={`${totalHits}건`}/>
        <Pill k="데이터 상태" v={apiState.status === 'ready' ? '실시간 연결' : apiState.status === 'loading' ? '불러오는 중' : '임시 자료'}/>
      </div>

      <div data-report-section="day4-rule-detection" style={{background:'#fff', border:'1px solid var(--line)', borderRadius:12, padding:'14px 18px', marginBottom:14, boxShadow:'var(--shadow-sm)'}}>
        <div style={{display:'flex', alignItems:'center', gap:14, marginBottom:day4.status==='ready'?12:0}}>
          <div style={{width:36, height:36, borderRadius:9, background:'var(--amber-soft)', display:'flex', alignItems:'center', justifyContent:'center', color:'var(--amber)'}}><Icon name="search" size={18}/></div>
          <div style={{flex:1}}>
            <div style={{fontSize:13, fontWeight:700, color:'var(--ink)'}}>전국 자치법규 자동 점검 결과</div>
            <div style={{fontSize:11.5, color:'var(--ink-3)', marginTop:3}}>
              {day4.status === 'ready'
                ? `건축법 연계 자치법규 ${(day4.payload?.sample?.sourceTotal || 0).toLocaleString()}건 중 ${day4.payload?.sample?.sampleSize || 0}곳을 본문까지 자동 점검했습니다 (${day4.payload?.sample?.sampleArticleChunks || 0}개 조문 단위). 5가지 결정형 차이 신호와 경과조치 표시를 함께 보여드립니다.`
                : day4.status === 'loading'
                  ? '자치법규 자동 점검 결과를 불러오는 중입니다.'
                  : '자동 점검 결과를 불러오지 못했습니다.'}
            </div>
            {day4.status === 'error' && <div style={{fontSize:11, color:'#A8434A', marginTop:4}}>{day4.error}</div>}
          </div>
          {day4.status === 'ready' && <Pill k="점검 자치법규" v={`${day4.payload?.sample?.sampleSize || 0}곳`}/>}
          {day4.status === 'ready' && <Pill k="검토 신호 있음" v={`${day4.payload?.totals?.flaggedOrdinances || 0}곳`}/>}
        </div>
        {day4.status === 'ready' && (
          <div style={{paddingTop:12, borderTop:'1px solid var(--line)'}}>
            <div style={{display:'grid', gridTemplateColumns:'repeat(6, 1fr)', gap:10}}>
              {[
                {k:'숫자 불일치', v:day4.payload?.totals?.perRule?.numericMismatch||0, tone:'#C77A1B', soft:'#FBEFD9'},
                {k:'기한 불일치', v:day4.payload?.totals?.perRule?.periodMismatch||0, tone:'#C77A1B', soft:'#FBEFD9'},
                {k:'권한자 표기', v:day4.payload?.totals?.perRule?.authorityMismatch||0, tone:'#C77A1B', soft:'#FBEFD9'},
                {k:'폐지법령 인용', v:day4.payload?.totals?.perRule?.repealedCitation||0, tone:'#C77A1B', soft:'#FBEFD9'},
                {k:'시행일 불일치', v:day4.payload?.totals?.perRule?.effectiveDateMismatch||0, tone:'#C77A1B', soft:'#FBEFD9'},
                {k:'경과조치 표시', v:day4.payload?.totals?.perRule?.bClassification||0, tone:'#2E5FB0', soft:'var(--blue-soft)'}
              ].map(r => (
                <div key={r.k} style={{padding:'10px 12px', background:r.soft, borderRadius:8, border:`1px solid ${r.tone}33`}}>
                  <div style={{fontSize:10.5, color:'var(--ink-3)', fontWeight:600}}>{r.k}</div>
                  <div className="mono" style={{fontSize:20, fontWeight:700, color:r.tone, marginTop:4}}>{r.v.toLocaleString()}</div>
                </div>
              ))}
            </div>
            <div style={{marginTop:10, padding:'8px 12px', background:'#F8FAFC', borderRadius:6, fontSize:11.5, color:'var(--ink-3)', lineHeight:1.6}}>
              조례 글자가 다르다고 모두 미정비는 아닙니다. 경과조치·종전의 규정처럼 의도적으로 남겨둔 표현은 정비 검토 후보에서 분리해 별도로 표시합니다.
            </div>
          </div>
        )}
      </div>

      <div data-report-section="per-document-sync-rates" style={{display:'grid', gridTemplateColumns:'repeat(4, 1fr)', gap:10, marginBottom:14}}>
        {(c.syncRates || []).map(s => {
          const tone = s.v >= 85 ? '#1F7A6B' : s.v >= 70 ? '#5B7C99' : '#C77A1B';
          const soft = s.v >= 85 ? '#DBEEEA' : s.v >= 70 ? '#EEF2F7' : '#FBEFD9';
          const txt = s.v >= 85 ? '정비 양호' : s.v >= 70 ? '확인 필요' : '우선 검토';
          return (
            <div key={s.l} data-sync-rate={s.v} style={{background:'#fff', border:'1px solid var(--line)', borderRadius:11, padding:'12px 14px', position:'relative', overflow:'hidden'}}>
              <div style={{position:'absolute', left:0, top:0, bottom:0, width:3, background:tone}}/>
              <div style={{display:'flex', alignItems:'center', justifyContent:'space-between', marginBottom:6}}>
                <span style={{fontSize:11.5, color:'var(--ink-3)', fontWeight:600}}>{s.l}</span>
                <span style={{fontSize:9.5, color:tone, fontWeight:700, background:soft, padding:'2px 6px', borderRadius:4}}>{txt}</span>
              </div>
              <div style={{display:'flex', alignItems:'baseline', gap:6}}>
                <span className="mono" style={{fontSize:24, fontWeight:700, color:tone}}>{s.v}</span>
                <span style={{fontSize:11, color:'var(--ink-4)'}}>%</span>
                <div style={{flex:1}}/>
                <span style={{fontSize:10.5, color:'var(--ink-3)'}}>{s.n}</span>
              </div>
              <div style={{height:4, background:'#EEF2F7', borderRadius:99, marginTop:8, overflow:'hidden'}}><div style={{width:`${s.v}%`, height:'100%', background:tone}}/></div>
            </div>
          );
        })}
      </div>

      <div style={{display:'grid', gridTemplateColumns:'1.4fr 1fr', gap:14, marginBottom:14}}>
        <div style={{background:'#fff', border:'1px solid var(--line)', borderRadius:12, boxShadow:'var(--shadow-sm)', display:'flex', flexDirection:'column'}}>
          <div style={{padding:'12px 16px', borderBottom:'1px solid var(--line)', background:'#FBFCFE', borderRadius:'12px 12px 0 0', display:'flex', alignItems:'center', justifyContent:'space-between'}}>
            <Badge tone="navy" size="sm">{c.law} {c.article}</Badge>
            <span style={{fontSize:11, color:'var(--ink-3)'}}>개정 전 · 개정 후</span>
          </div>
          <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', flex:1, minHeight:0}}>
            <ArticleColumn label="개정 전" tone="rose" lines={c.compare?.old || []} picked={activeId} onPick={setPicked} periodLabel="~ 2026.2.26"/>
            <ArticleColumn label="개정 후" tone="teal" lines={c.compare?.new || []} picked={activeId} onPick={setPicked} divider periodLabel="2026.2.27 ~"/>
          </div>
        </div>

        <div style={{background:'#fff', border:'1px solid var(--line)', borderRadius:12, boxShadow:'var(--shadow-sm)', display:'flex', flexDirection:'column'}}>
          <div style={{padding:'12px 16px', borderBottom:'1px solid var(--line)', background:'#FBFCFE', borderRadius:'12px 12px 0 0'}}>
            <div style={{display:'flex', alignItems:'center', gap:8}}>
              <span style={{fontSize:10, fontWeight:700, color:'var(--blue)', letterSpacing:'0.08em', background:'var(--blue-soft)', padding:'2px 8px', borderRadius:4}}>AI 자동 감지</span>
              <span style={{fontSize:13, fontWeight:700, color:'var(--ink)'}}>바뀐 부분</span>
            </div>
            <div style={{fontSize:11.5, color:'var(--ink-3)', marginTop:4}}>{segments.length}개 변경 단위 · 누르면 왼쪽의 조문과 오른쪽의 관련 자치법규가 같이 바뀝니다.</div>
          </div>
          <div style={{flex:1, overflowY:'auto'}}>
            {segments.map((s,i) => {
              const active = activeId === s.id;
              const toneColor = compareToneColor(s.tone);
              return (
                <button key={s.id} onClick={()=>setPicked(s.id)} style={{display:'block', width:'100%', textAlign:'left', padding:'14px 16px', border:'none', cursor:'pointer', background:active?'#FBFCFE':'#fff', borderLeft:active?`3px solid ${toneColor}`:'3px solid transparent', borderBottom:i<segments.length-1?'1px solid var(--line)':'none'}}>
                  <div style={{display:'flex', alignItems:'center', gap:6, marginBottom:8}}>
                    <Badge tone={s.tone} size="sm">{s.kind}</Badge>
                    <div style={{flex:1}}/>
                    <span className="mono" style={{fontSize:11, fontWeight:700, color:toneColor}}>{s.severity}</span>
                    <span style={{fontSize:10, color:'var(--ink-4)'}}>위험도</span>
                  </div>
                  <div style={{fontSize:11, color:'var(--ink-3)', marginBottom:4}}>개정 전</div>
                  <div style={{fontSize:12.5, color:'var(--ink-2)', padding:'7px 10px', background:'#FBE9EB', borderRadius:4, lineHeight:1.55, textDecoration:'line-through', textDecorationColor:'rgba(168,67,74,0.45)'}}>{s.from}</div>
                  <div style={{display:'flex', justifyContent:'center', margin:'4px 0', color:'var(--ink-4)'}}><Icon name="arrow-down" size={11}/></div>
                  <div style={{fontSize:11, color:'var(--ink-3)', marginBottom:4}}>개정 후</div>
                  <div style={{fontSize:12.5, color:'var(--ink-2)', padding:'7px 10px', background:'#E6F4F1', borderRadius:4, lineHeight:1.55}}>{s.to}</div>
                  <div style={{fontSize:11, color:'var(--ink-3)', lineHeight:1.5, marginTop:8}}>{s.summary}</div>
                  <div style={{display:'flex', alignItems:'center', gap:6, marginTop:6}}>
                    <Icon name="search" size={11} color="var(--blue)"/>
                    <span style={{fontSize:11, color:'var(--ink-3)'}}>관련 자치법규 <span className="mono" style={{color:'var(--navy)', fontWeight:700}}>{s.hits}</span>곳</span>
                  </div>
                </button>
              );
            })}
          </div>
        </div>
      </div>

      <button
        data-action="go-to-reform-pool"
        onClick={()=>go('dashboard')}
        style={{
          width:'100%', display:'flex', alignItems:'center', gap:14,
          padding:'18px 22px', marginBottom:14, cursor:'pointer',
          background:'linear-gradient(135deg, #FBFCFE 0%, #F0F7FF 100%)',
          border:'1px solid #BFDBFE', borderLeft:'4px solid #1E40AF',
          borderRadius:12, boxShadow:'var(--shadow-sm)', textAlign:'left'
        }}
        onMouseEnter={e=>{ e.currentTarget.style.background='linear-gradient(135deg, #EFF6FF 0%, #DBEAFE 100%)'; }}
        onMouseLeave={e=>{ e.currentTarget.style.background='linear-gradient(135deg, #FBFCFE 0%, #F0F7FF 100%)'; }}
      >
        <div style={{
          width:44, height:44, borderRadius:10, flexShrink:0,
          background:'#1E40AF', display:'flex', alignItems:'center', justifyContent:'center', color:'#fff'
        }}><Icon name="search" size={20}/></div>
        <div style={{flex:1, minWidth:0}}>
          <div style={{display:'flex', alignItems:'center', gap:8, marginBottom:4, flexWrap:'wrap'}}>
            <span style={{fontSize:10.5, fontWeight:800, color:'#1E40AF', background:'#DBEAFE', padding:'2px 8px', borderRadius:4, letterSpacing:'0.05em'}}>정비 검토 후보 풀</span>
            <span style={{fontSize:11, color:'var(--ink-3)'}}>02 메뉴에서 통합 관리</span>
          </div>
          <div style={{fontSize:15, fontWeight:800, color:'var(--ink)', lineHeight:1.4}}>
            이 개정의 영향을 받는 자치법규를 등급별로 정렬한 정비 검토 후보 풀로 이동
          </div>
          <div style={{fontSize:12, color:'var(--ink-3)', marginTop:4, lineHeight:1.55}}>
            AI가 실제 본문에서 찾은 정비 검토 후보(구미시·군위군·충청남도)와 추가 검토 신호가 한 곳에 모여 있습니다. 사례 카드를 누르면 직접 위임근거와 비교 결과 상세로 이동합니다.
          </div>
          {(() => {
            const ords = day4.payload?.ordinances || [];
            const directOrd = ords.find(o => o?.signals?.periodMismatch?.directComparisons?.length > 0);
            const direct = directOrd?.signals?.periodMismatch?.directComparisons?.[0];
            if (!direct) return null;
            const localArticle = direct.localArticleLabel ? ` ${direct.localArticleLabel}` : '';
            const paragraph = direct.parentLawParagraph ? ` ${direct.parentLawParagraph}` : '';
            return (
              <div style={{marginTop:10, padding:'10px 12px', background:'#FEF2F2', border:'1px solid #FCA5A5', borderRadius:8, display:'flex', alignItems:'center', gap:8, fontSize:12, color:'#7F1D1D', flexWrap:'wrap', lineHeight:1.55}}>
                <span style={{fontSize:10, fontWeight:800, color:'#991B1B', background:'#FEE2E2', padding:'2px 7px', borderRadius:3, border:'1px solid #FCA5A5'}}>⚠ 최우선 후보 미리보기</span>
                <span style={{fontWeight:800, color:'#0F172A'}}>{directOrd.title}{localArticle}</span>
                <span style={{color:'var(--ink-3)'}}>·</span>
                <span style={{fontSize:11.5, color:'#7F1D1D'}}>{direct.parentLawArticle}{paragraph}</span>
                <span style={{fontSize:11.5, color:'#fff', background:'#1E40AF', padding:'2px 7px', borderRadius:3, fontWeight:700}}>{direct.expected}</span>
                <span style={{color:'var(--ink-3)'}}>vs</span>
                <span style={{fontSize:11.5, color:'#fff', background:'#DC2626', padding:'2px 7px', borderRadius:3, fontWeight:700}}>{direct.observed}</span>
                <span style={{color:'var(--ink-3)', marginLeft:4}}>외 AI 탐색·검토 신호 후보 다수</span>
              </div>
            );
          })()}
        </div>
        <div style={{
          display:'flex', alignItems:'center', gap:6, padding:'8px 14px',
          background:'#1E40AF', color:'#fff', borderRadius:8, fontSize:12, fontWeight:700, flexShrink:0
        }}>
          정비 검토 후보 풀로 이동 <Icon name="arrow-right" size={13} color="#fff"/>
        </div>
      </button>

    </Page>
  );
}

Object.assign(window, { UpperLawScreen, ImpactGraph, ImpactGraphModal, CompareScreen, LowerScreen, FormsScreen, AnalysisScreen });
