// Consumer-facing mobile screens
const { newDrops, announcements, events, stores, brand, categories } = WU_DATA;

// ────────────────────────────────────────────────────
// Consumer PRODUCT DETAIL — published product page (role-aware)
// ────────────────────────────────────────────────────
function ConsumerProductDetail({ product, onBack }) {
  const [imgIdx, setImgIdx] = React.useState(0);
  const [lbOpen, setLbOpen] = React.useState(false);
  const [lbIdx, setLbIdx] = React.useState(0);
  const [isFav, setIsFav] = React.useState(false);
  const touchRef = React.useRef(null);
  const lbTouchRef = React.useRef(null);
  const user = typeof getAuth === 'function' ? getAuth() : null;
  const isOwner = user && user.role === 'owner';

  // 즐겨찾기 초기값 세팅
  const productId = (product && (product.id || (product.parsed && product.parsed.code) || product.title)) || '';
  const getFavs = () => { try { return JSON.parse(localStorage.getItem('wu-favorites') || '[]'); } catch { return []; } };
  React.useEffect(() => { setIsFav(getFavs().includes(productId)); }, [productId]);

  const toggleFav = () => {
    const favs = getFavs();
    let next;
    if (favs.includes(productId)) {
      next = favs.filter(id => id !== productId);
    } else {
      next = [...favs, productId];
    }
    localStorage.setItem('wu-favorites', JSON.stringify(next));
    setIsFav(!isFav);
  };
  // product가 없으면 빈 껍데기로 대체
  const _p = product || {};

  // 미디어 통합: media 배열 > videos+photos 개별 배열 > photos만
  const _buildMedia = () => {
    if (_p.media && _p.media.length > 0) return _p.media;
    const arr = [];
    if (_p.videos) _p.videos.forEach(v => arr.push({ src: v, type: 'video' }));
    if (_p.photos) _p.photos.forEach(p => arr.push({ src: p, type: 'image' }));
    return arr;
  };
  const allMedia = _buildMedia();
  const mediaItems = [...allMedia].sort((a, b) => (b.type === 'video' ? 1 : 0) - (a.type === 'video' ? 1 : 0));
  const photos = mediaItems.length > 0 ? mediaItems.map(m => m.src) : (_p.photos || []);
  const total = mediaItems.length || photos.length;

  const p = _p.parsed || {};
  const highlights = _p.highlights || [];
  const body = _p.body || _p.caption || '';
  const title = _p.title || p.name || p.kr || _p.kr || _p.name || '상품';
  const prodBrand = p.brand || _p.brand || '';
  const code = p.code || _p.code || '';
  const _parseNum = (v) => typeof v === 'number' ? v : parseInt(String(v).replace(/[,\s원]/g, ''), 10) || 0;
  const retail = _parseNum(p.retail || _p.retail);
  const wholesale = _parseNum(p.wholesale || _p.wholesale);
  const _toArr = (v) => Array.isArray(v) ? v : (v ? String(v).split(/[,/]/).map(s => s.trim()).filter(Boolean) : []);
  const sizes = _toArr(p.sizes || _p.sizes);
  const colors = _toArr(p.colors_kr || p.colors || _p.colors_kr || _p.colors);
  const moq = p.moq || _p.moq || (p.qty ? p.qty : null);
  const season = p.season_tag || _p.season_tag || '';
  const parts = Array.isArray(p.parts) ? p.parts.join(' · ') : Array.isArray(_p.parts) ? _p.parts.join(' · ') : (p.parts || _p.parts || '');

  // 라이트박스 열기
  const openLightbox = (idx) => { setLbIdx(idx); setLbOpen(true); };

  // 터치 스와이프 (메인 갤러리)
  const onTouchStart = (e) => { touchRef.current = e.touches[0].clientX; };
  const onTouchEnd = (e) => {
    if (touchRef.current === null) return;
    const diff = touchRef.current - e.changedTouches[0].clientX;
    if (Math.abs(diff) > 40) {
      if (diff > 0 && imgIdx < total - 1) setImgIdx(imgIdx + 1);
      if (diff < 0 && imgIdx > 0) setImgIdx(imgIdx - 1);
    }
    touchRef.current = null;
  };

  // 라이트박스 터치 스와이프
  const onLbTouchStart = (e) => { lbTouchRef.current = e.touches[0].clientX; };
  const onLbTouchEnd = (e) => {
    if (lbTouchRef.current === null) return;
    const diff = lbTouchRef.current - e.changedTouches[0].clientX;
    if (Math.abs(diff) > 40) {
      if (diff > 0) setLbIdx(i => (i + 1) % total);
      if (diff < 0) setLbIdx(i => (i - 1 + total) % total);
    }
    lbTouchRef.current = null;
  };

  return (
    <div className="wu wu-scroll wu-consumer-wrap" style={{ height: '100%', overflow: 'auto', background: 'var(--wu-bg)', paddingBottom: 70 }}>

      {/* ── 풀스크린 라이트박스 ── */}
      {lbOpen && total > 0 && (
        <div onClick={() => setLbOpen(false)} style={{ position: 'fixed', inset: 0, zIndex: 9999, background: 'rgba(0,0,0,0.95)', display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center' }}>
          {/* 닫기 */}
          <button onClick={() => setLbOpen(false)} style={{ position: 'absolute', top: 14, right: 14, width: 40, height: 40, borderRadius: 999, background: 'rgba(255,255,255,0.12)', color: '#fff', border: 'none', fontSize: 22, cursor: 'pointer', zIndex: 3, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>×</button>
          {/* 카운터 */}
          <div className="mono" style={{ position: 'absolute', top: 20, left: '50%', transform: 'translateX(-50%)', color: 'rgba(255,255,255,0.7)', fontSize: 13, zIndex: 3 }}>{lbIdx + 1} / {total}</div>

          {/* 메인 미디어 */}
          <div onClick={e => e.stopPropagation()} onTouchStart={onLbTouchStart} onTouchEnd={onLbTouchEnd} style={{ position: 'relative', width: '100%', maxWidth: '92vw', maxHeight: '80vh', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
            {total > 1 && (
              <button onClick={() => setLbIdx(i => (i - 1 + total) % total)} style={{ position: 'absolute', left: 6, top: '50%', transform: 'translateY(-50%)', width: 40, height: 40, borderRadius: 999, background: 'rgba(0,0,0,0.5)', color: '#fff', border: 'none', fontSize: 20, cursor: 'pointer', zIndex: 2, display: 'flex', alignItems: 'center', justifyContent: 'center', backdropFilter: 'blur(4px)' }}>‹</button>
            )}
            {(mediaItems[lbIdx] || {}).type === 'video' ? (
              <video src={(mediaItems[lbIdx] || {}).src} style={{ maxWidth: '92vw', maxHeight: '80vh', objectFit: 'contain' }} autoPlay muted loop playsInline controls />
            ) : (
              <img src={(mediaItems[lbIdx] || {}).src || photos[lbIdx]} style={{ maxWidth: '92vw', maxHeight: '80vh', objectFit: 'contain' }} />
            )}
            {total > 1 && (
              <button onClick={() => setLbIdx(i => (i + 1) % total)} style={{ position: 'absolute', right: 6, top: '50%', transform: 'translateY(-50%)', width: 40, height: 40, borderRadius: 999, background: 'rgba(0,0,0,0.5)', color: '#fff', border: 'none', fontSize: 20, cursor: 'pointer', zIndex: 2, display: 'flex', alignItems: 'center', justifyContent: 'center', backdropFilter: 'blur(4px)' }}>›</button>
            )}
          </div>

          {/* 하단 썸네일 */}
          {total > 1 && (
            <div onClick={e => e.stopPropagation()} style={{ display: 'flex', gap: 6, marginTop: 14, overflowX: 'auto', maxWidth: '92vw', padding: '4px 8px' }}>
              {(mediaItems.length > 0 ? mediaItems : photos.map(s => ({ src: s, type: 'image' }))).map((m, i) => (
                <div key={i} onClick={() => setLbIdx(i)} style={{ width: 50, height: 50, flexShrink: 0, cursor: 'pointer', border: i === lbIdx ? '2px solid var(--wu-orange)' : '2px solid transparent', opacity: i === lbIdx ? 1 : 0.5, transition: 'all 0.15s', position: 'relative', borderRadius: 4, overflow: 'hidden' }}>
                  {m.type === 'video' ? (
                    <React.Fragment>
                      <video src={m.src} style={{ width: '100%', height: '100%', objectFit: 'cover' }} muted />
                      <div style={{ position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'rgba(0,0,0,0.3)' }}><span style={{ color: '#fff', fontSize: 16 }}>▶</span></div>
                    </React.Fragment>
                  ) : (
                    <img src={typeof m === 'string' ? m : m.src} style={{ width: '100%', height: '100%', objectFit: 'cover' }} />
                  )}
                </div>
              ))}
            </div>
          )}
        </div>
      )}

      {/* Top bar */}
      <div style={{ position: 'sticky', top: 0, zIndex: 30, background: 'var(--wu-bg)', padding: 'calc(env(safe-area-inset-top, 20px) + 12px) 16px 8px', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
        <button onClick={onBack} style={{ width: 36, height: 36, borderRadius: 999, background: '#fff', border: '1px solid var(--wu-line)', display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer', fontSize: 16 }}>←</button>
        <div style={{ display: 'flex', gap: 6 }}>
          <button onClick={toggleFav} style={{ width: 36, height: 36, borderRadius: 999, background: isFav ? 'var(--wu-orange)' : '#fff', border: '1px solid ' + (isFav ? 'var(--wu-orange)' : 'var(--wu-line)'), display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer', transition: 'all 0.2s' }}>
            <svg width="16" height="16" viewBox="0 0 20 20" fill={isFav ? '#fff' : 'none'} stroke={isFav ? '#fff' : 'currentColor'} strokeWidth="1.6"><path d="M10 4L12.5 9H17L13 12.5L14.5 18L10 14.5L5.5 18L7 12.5L3 9H7.5L10 4Z"/></svg>
          </button>
          <button style={{ width: 36, height: 36, borderRadius: 999, background: '#fff', border: '1px solid var(--wu-line)', display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer' }}>
            <svg width="16" height="16" viewBox="0 0 20 20" fill="none" stroke="currentColor" strokeWidth="1.6"><path d="M15 11l-5-5-5 5"/><path d="M4 4h12"/></svg>
          </button>
        </div>
      </div>

      {/* Main media gallery — 터치 스와이프 + 탭으로 라이트박스 */}
      <div style={{ margin: '0 16px', position: 'relative', background: '#E9E5DC', borderRadius: 6, overflow: 'hidden' }} onTouchStart={onTouchStart} onTouchEnd={onTouchEnd}>
        {mediaItems.length > 0 ? (
          <div onClick={() => openLightbox(imgIdx)} style={{ cursor: 'pointer' }}>
            {mediaItems[imgIdx]?.type === 'video' ? (
              <video src={mediaItems[imgIdx].src} autoPlay muted loop playsInline style={{ width: '100%', aspectRatio: '4/5', objectFit: 'cover', display: 'block', background: '#000' }} />
            ) : (
              <img src={mediaItems[imgIdx]?.src || photos[imgIdx]} style={{ width: '100%', aspectRatio: '4/5', objectFit: 'cover', display: 'block' }} />
            )}
          </div>
        ) : photos.length > 0 ? (
          <div onClick={() => openLightbox(imgIdx)} style={{ cursor: 'pointer' }}>
            <img src={photos[imgIdx]} style={{ width: '100%', aspectRatio: '4/5', objectFit: 'cover', display: 'block' }} />
          </div>
        ) : (
          <div style={{ width: '100%', aspectRatio: '4/5', display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'linear-gradient(160deg, #E9E5DC, #DCD7CC)' }}>
            <span className="display" style={{ fontSize: 18, color: 'var(--wu-mute)' }}>NO IMAGE</span>
          </div>
        )}
        {total > 1 && (
          <React.Fragment>
            {imgIdx > 0 && <button onClick={(e) => { e.stopPropagation(); setImgIdx(i => i - 1); }} style={{ position: 'absolute', left: 8, top: '50%', transform: 'translateY(-50%)', width: 34, height: 34, borderRadius: 999, background: 'rgba(0,0,0,0.45)', color: '#fff', border: 0, cursor: 'pointer', fontSize: 16, display: 'flex', alignItems: 'center', justifyContent: 'center', backdropFilter: 'blur(4px)' }}>‹</button>}
            {imgIdx < total - 1 && <button onClick={(e) => { e.stopPropagation(); setImgIdx(i => i + 1); }} style={{ position: 'absolute', right: 8, top: '50%', transform: 'translateY(-50%)', width: 34, height: 34, borderRadius: 999, background: 'rgba(0,0,0,0.45)', color: '#fff', border: 0, cursor: 'pointer', fontSize: 16, display: 'flex', alignItems: 'center', justifyContent: 'center', backdropFilter: 'blur(4px)' }}>›</button>}
            {/* 도트 인디케이터 (최대 10개 표시) */}
            <div style={{ position: 'absolute', bottom: 12, left: '50%', transform: 'translateX(-50%)', display: 'flex', gap: 5, alignItems: 'center' }}>
              {total <= 10 ? (
                Array.from({ length: total }).map((_, i) => <div key={i} onClick={(e) => { e.stopPropagation(); setImgIdx(i); }} style={{ width: i === imgIdx ? 18 : 7, height: 7, borderRadius: 999, background: i === imgIdx ? '#fff' : 'rgba(255,255,255,0.45)', transition: 'all 0.2s', cursor: 'pointer' }} />)
              ) : (
                <div className="mono" style={{ fontSize: 11, color: '#fff', background: 'rgba(0,0,0,0.4)', padding: '2px 10px', borderRadius: 10 }}>{imgIdx + 1} / {total}</div>
              )}
            </div>
          </React.Fragment>
        )}
        {/* 영상 배지 */}
        {mediaItems.length > 0 && mediaItems[imgIdx]?.type === 'video' && (
          <div className="mono" style={{ position: 'absolute', top: 10, left: 10, padding: '3px 10px', background: 'var(--wu-orange)', color: '#fff', fontSize: 10, fontWeight: 700, borderRadius: 4 }}>VIDEO</div>
        )}
        {/* 카운터 */}
        <div className="mono" style={{ position: 'absolute', top: 10, right: 10, fontSize: 10, padding: '3px 10px', background: 'rgba(0,0,0,0.5)', color: '#fff', borderRadius: 4 }}>
          {imgIdx + 1}/{Math.max(total, 1)}
        </div>
      </div>

      {/* Thumbnail strip */}
      {total > 1 && (
        <div className="wu-scroll" style={{ display: 'flex', gap: 6, padding: '10px 16px', overflowX: 'auto' }}>
          {(mediaItems.length > 0 ? mediaItems : photos.map(s => ({ src: s, type: 'image' }))).map((m, i) => (
            <button key={i} onClick={() => setImgIdx(i)} style={{ width: 56, height: 56, flexShrink: 0, border: i === imgIdx ? '2px solid var(--wu-orange)' : '1px solid var(--wu-line)', padding: 0, cursor: 'pointer', overflow: 'hidden', position: 'relative', borderRadius: 4, transition: 'border-color 0.15s' }}>
              {m.type === 'video' ? (
                <React.Fragment>
                  <video src={m.src} style={{ width: '100%', height: '100%', objectFit: 'cover' }} muted />
                  <div style={{ position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'rgba(0,0,0,0.3)' }}>
                    <span style={{ color: '#fff', fontSize: 14 }}>▶</span>
                  </div>
                </React.Fragment>
              ) : (
                <img src={typeof m === 'string' ? m : m.src} style={{ width: '100%', height: '100%', objectFit: 'cover' }} />
              )}
            </button>
          ))}
        </div>
      )}

      {/* Product info */}
      <div style={{ padding: '20px 16px 0' }}>
        {/* Brand + tags */}
        <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap', alignItems: 'center' }}>
          {prodBrand && <span className="mono" style={{ fontSize: 10, padding: '4px 10px', background: 'var(--wu-ink)', color: 'var(--wu-orange)', fontWeight: 700, borderRadius: 3 }}>{prodBrand}</span>}
          {season && <span className="mono" style={{ fontSize: 10, padding: '4px 10px', background: 'var(--wu-bg)', border: '1px solid var(--wu-line)', borderRadius: 3 }}>{season}</span>}
          {parts && <span className="mono" style={{ fontSize: 10, padding: '4px 10px', background: 'var(--wu-bg)', border: '1px solid var(--wu-line)', borderRadius: 3 }}>{parts}</span>}
        </div>

        {/* Title */}
        <div className="kr" style={{ fontSize: 22, fontWeight: 800, marginTop: 12, lineHeight: 1.35 }}>{title}</div>
        {code && <div className="mono" style={{ fontSize: 11, color: 'var(--wu-mute)', marginTop: 4 }}>{code}</div>}

        {/* PRICING — role-aware */}
        <div style={{ marginTop: 18, padding: 18, background: isOwner ? 'var(--wu-ink)' : 'var(--wu-paper)', color: isOwner ? 'var(--wu-paper)' : 'var(--wu-ink)', border: '1px solid var(--wu-line)', borderRadius: 6 }}>
          {isOwner ? (
            <React.Fragment>
              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                <div className="mono" style={{ fontSize: 10, color: 'var(--wu-lime)', fontWeight: 700 }}>공급가 · WHOLESALE</div>
                <div className="display" style={{ fontSize: 26, color: 'var(--wu-lime)' }}>₩{wholesale.toLocaleString()}</div>
              </div>
              <div style={{ height: 1, background: '#2A2A26', margin: '10px 0' }} />
              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                <div className="mono" style={{ fontSize: 10, color: 'var(--wu-mute)' }}>판매가 · RETAIL</div>
                <div className="mono" style={{ fontSize: 18, fontWeight: 700 }}>₩{retail.toLocaleString()}</div>
              </div>
              {wholesale > 0 && retail > 0 && (
                <div style={{ marginTop: 12, paddingTop: 10, borderTop: '1px dashed #3A3A36', display: 'flex', justifyContent: 'space-between' }}>
                  <span className="mono" style={{ fontSize: 10, color: 'var(--wu-mute)' }}>마진율</span>
                  <span className="mono" style={{ fontSize: 13, color: 'var(--wu-orange)', fontWeight: 700 }}>{Math.round(((retail - wholesale) / retail) * 100)}% · ₩{(retail - wholesale).toLocaleString()}</span>
                </div>
              )}
              {moq && (
                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginTop: 10, paddingTop: 10, borderTop: '1px dashed #3A3A36' }}>
                  <div className="mono" style={{ fontSize: 10, color: 'var(--wu-mute)' }}>입수량 · MOQ</div>
                  <div className="mono" style={{ fontSize: 14, fontWeight: 700 }}>{moq}</div>
                </div>
              )}
            </React.Fragment>
          ) : (
            <React.Fragment>
              <div className="mono" style={{ fontSize: 10, color: 'var(--wu-mute)', fontWeight: 600 }}>판매가</div>
              <div className="display" style={{ fontSize: 30, marginTop: 4 }}>₩{retail.toLocaleString()}</div>
            </React.Fragment>
          )}
        </div>

        {/* 사이즈 + 색상 통합 카드 (입수량은 점주 가격 카드에서만 표시) */}
        {(sizes.length > 0 || colors.length > 0) && (
          <div style={{ marginTop: 14, padding: 16, background: 'var(--wu-paper)', border: '1px solid var(--wu-line)', borderRadius: 6 }}>
            {sizes.length > 0 && (
              <div style={{ marginBottom: colors.length > 0 ? 14 : 0 }}>
                <div className="mono" style={{ fontSize: 10, color: 'var(--wu-mute)', marginBottom: 8, fontWeight: 600 }}>사이즈</div>
                <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap' }}>
                  {sizes.map(s => <span key={s} style={{ padding: '8px 16px', border: '1px solid var(--wu-ink)', fontSize: 13, fontFamily: 'JetBrains Mono', fontWeight: 600, borderRadius: 4 }}>{s}</span>)}
                </div>
              </div>
            )}
            {colors.length > 0 && (
              <div>
                <div className="mono" style={{ fontSize: 10, color: 'var(--wu-mute)', marginBottom: 8, fontWeight: 600 }}>색상</div>
                <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap' }}>
                  {colors.map(c => <span key={c} className="kr" style={{ padding: '8px 16px', border: '1px solid var(--wu-line)', fontSize: 13, fontWeight: 600, borderRadius: 4, background: 'var(--wu-bg)' }}>{c}</span>)}
                </div>
              </div>
            )}
          </div>
        )}

        {/* 상세 설명 */}
        {body && (
          <div style={{ marginTop: 14, padding: 18, background: 'var(--wu-paper)', border: '1px solid var(--wu-line)', borderRadius: 6 }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 12 }}>
              <div style={{ width: 3, height: 16, background: 'var(--wu-orange)', borderRadius: 2 }} />
              <div className="display" style={{ fontSize: 15 }}>상품 설명</div>
            </div>
            <div className="kr" style={{ fontSize: 14, lineHeight: 1.9, color: 'var(--wu-ink)', whiteSpace: 'pre-wrap' }}>{body}</div>
          </div>
        )}

        {/* 주요 특징 */}
        {highlights.length > 0 && (
          <div style={{ marginTop: 14, padding: 18, background: 'var(--wu-paper)', border: '1px solid var(--wu-line)', borderRadius: 6 }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 12 }}>
              <div style={{ width: 3, height: 16, background: 'var(--wu-lime)', borderRadius: 2 }} />
              <div className="display" style={{ fontSize: 15 }}>주요 특징</div>
            </div>
            {highlights.map((h, i) => (
              <div key={i} className="kr" style={{ display: 'flex', gap: 10, padding: '10px 0', borderBottom: i < highlights.length - 1 ? '1px solid var(--wu-line)' : 'none', fontSize: 14, lineHeight: 1.6 }}>
                <span style={{ color: 'var(--wu-lime)', fontWeight: 700, flexShrink: 0, fontSize: 15 }}>✔</span>
                <span>{h}</span>
              </div>
            ))}
          </div>
        )}

        {/* 발행 정보 */}
        {_p.publishedAt && (
          <div className="mono" style={{ fontSize: 10, color: 'var(--wu-mute)', marginTop: 14, textAlign: 'center', paddingBottom: 8 }}>
            발행일: {new Date(_p.publishedAt).toLocaleString('ko-KR')} · 미디어 {total}개
          </div>
        )}
      </div>

      {/* Bottom CTA */}
      <div style={{ position: 'fixed', bottom: 0, left: 0, right: 0, padding: '12px 16px', background: 'var(--wu-bg)', borderTop: '1px solid var(--wu-line)', display: 'flex', gap: 8, zIndex: 40 }}>
        <button onClick={toggleFav} style={{ width: 48, height: 48, border: '1.5px solid ' + (isFav ? 'var(--wu-orange)' : 'var(--wu-ink)'), display: 'flex', alignItems: 'center', justifyContent: 'center', background: isFav ? 'var(--wu-orange)' : 'var(--wu-paper)', cursor: 'pointer', transition: 'all 0.2s', borderRadius: 4 }}>
          <svg width="20" height="20" viewBox="0 0 20 20" fill={isFav ? '#fff' : 'none'} stroke={isFav ? '#fff' : 'currentColor'} strokeWidth="1.6"><path d="M10 4L12.5 9H17L13 12.5L14.5 18L10 14.5L5.5 18L7 12.5L3 9H7.5L10 4Z"/></svg>
        </button>
        {isOwner && (
          <button className="wu-btn lime" style={{ flex: 1, padding: '14px', fontSize: 15, fontWeight: 700, borderRadius: 4 }}>발주하기</button>
        )}
      </div>
    </div>
  );
}

// ────────────────────────────────────────────────────
// Consumer HOME — editorial feed with hero, drops, events
// ────────────────────────────────────────────────────
function ConsumerHome({ variant = 'pill' }) {
  const [pubProducts, setPubProducts] = useState([]);
  const [homeCfg, setHomeCfg] = useState(null);
  const [visibleCount, setVisibleCount] = useState(20);
  const [heroIdx, setHeroIdx] = useState(0);
  const [favIds, setFavIds] = useState(() => { try { return JSON.parse(localStorage.getItem('wu-favorites') || '[]'); } catch { return []; } });
  const loadMoreRef = React.useRef(null);
  const heroTouchRef = React.useRef(null);

  // 즐겨찾기 토글
  const toggleFav = (pid, e) => {
    e.stopPropagation();
    e.preventDefault();
    const next = favIds.includes(pid) ? favIds.filter(id => id !== pid) : [...favIds, pid];
    localStorage.setItem('wu-favorites', JSON.stringify(next));
    setFavIds(next);
  };

  useEffect(() => {
    // 발행상품 + 홈 설정 로드
    if (typeof getPublished === 'function') {
      getPublished().then(list => setPubProducts(list || [])).catch(() => {});
    }
    if (typeof getSettingFromCloud === 'function') {
      getSettingFromCloud('home-config').then(cfg => { if (cfg) setHomeCfg(cfg); }).catch(() => {});
    }
  }, []);

  // 무한 스크롤 — IntersectionObserver
  useEffect(() => {
    if (!loadMoreRef.current) return;
    const obs = new IntersectionObserver(entries => {
      if (entries[0].isIntersecting && visibleCount < pubProducts.length) {
        setVisibleCount(prev => Math.min(prev + 20, pubProducts.length));
      }
    }, { rootMargin: '200px' });
    obs.observe(loadMoreRef.current);
    return () => obs.disconnect();
  }, [visibleCount, pubProducts.length]);

  // 히어로 슬라이드 (구 hero 단일 → heroSlides 배열 호환)
  const heroSlides = React.useMemo(() => {
    if (homeCfg?.heroSlides && homeCfg.heroSlides.length > 0) return homeCfg.heroSlides;
    if (homeCfg?.hero) return [homeCfg.hero];
    // home-config 없을 때 실제 상품 사진으로 자동 배너 생성
    if (pubProducts.length > 0) {
      const withPhotos = pubProducts.filter(p => p.photos && p.photos.length > 0).slice(0, 3);
      if (withPhotos.length > 0) {
        return withPhotos.map(p => ({
          image: p.photos[0],
          title: (p.parsed?.brand || p.brand || 'WORKUP') + '\n' + (p.parsed?.name || p.parsed?.kr || p.title || ''),
          subtitle: p.parsed?.retail ? '₩' + Number(p.parsed.retail).toLocaleString() : '',
          productId: p.id
        }));
      }
    }
    return [{ image: '', title: 'WORK\nWEAR\nUP.', subtitle: '워크업 프리미엄 워크웨어', productId: '' }];
  }, [homeCfg, pubProducts]);

  // 자동 슬라이드 (4초)
  useEffect(() => {
    if (heroSlides.length <= 1) return;
    const timer = setInterval(() => setHeroIdx(prev => (prev + 1) % heroSlides.length), 4000);
    return () => clearInterval(timer);
  }, [heroSlides.length]);

  const onHeroTouchStart = (e) => { heroTouchRef.current = e.touches[0].clientX; };
  const onHeroTouchEnd = (e) => {
    if (heroTouchRef.current === null) return;
    const diff = heroTouchRef.current - e.changedTouches[0].clientX;
    if (Math.abs(diff) > 40) {
      if (diff > 0) setHeroIdx(prev => (prev + 1) % heroSlides.length);
      else setHeroIdx(prev => (prev - 1 + heroSlides.length) % heroSlides.length);
    }
    heroTouchRef.current = null;
  };

  const ticker = homeCfg?.ticker || '★ WORKUP PREMIUM WORKWEAR ★ NEW DROP';

  // 동적 카테고리 칩: home-config 설정이 있으면 사용, 없으면 실제 상품에서 브랜드+카테고리 자동 추출
  const topMenus = React.useMemo(() => {
    if (homeCfg?.topMenus && homeCfg.topMenus.length > 0) return homeCfg.topMenus;
    const chips = ['전체', '신상'];
    const brandCount = {};
    const catCount = {};
    pubProducts.forEach(p => {
      const parsed = p.parsed || {};
      const brand = parsed.brand || p.brand || '';
      if (brand) brandCount[brand] = (brandCount[brand] || 0) + 1;
      const cats = parsed.category || p.category || '';
      const catArr = Array.isArray(cats) ? cats : cats ? [cats] : [];
      catArr.forEach(c => { if (c) catCount[c] = (catCount[c] || 0) + 1; });
      const parts = parsed.parts || p.parts || [];
      const partsArr = Array.isArray(parts) ? parts : parts ? [parts] : [];
      partsArr.forEach(pt => { if (pt) catCount[pt] = (catCount[pt] || 0) + 1; });
    });
    // 카테고리 상위 항목 추가
    Object.entries(catCount).sort((a, b) => b[1] - a[1]).forEach(([c]) => { if (!chips.includes(c) && chips.length < 14) chips.push(c); });
    // 인기 브랜드 추가
    Object.entries(brandCount).sort((a, b) => b[1] - a[1]).forEach(([b]) => { if (!chips.includes(b) && chips.length < 14) chips.push(b); });
    return chips.length > 2 ? chips : categories;
  }, [pubProducts, homeCfg]);

  // NEW DROPS / BEST: home-config에 설정되어 있으면 사용, 없으면 실제 상품에서 자동 생성
  const newProds = React.useMemo(() => {
    if (homeCfg?.newProducts && homeCfg.newProducts.length > 0) return homeCfg.newProducts;
    // 최신 발행상품에서 자동 생성
    return pubProducts.slice(0, 6).map(p => ({
      id: p.id,
      title: p.parsed?.name || p.parsed?.kr || p.title || '상품',
      brand: p.parsed?.brand || p.brand || '',
      retail: p.parsed?.retail || p.retail || 0,
      photo: p.photos?.[0] || '',
    }));
  }, [homeCfg, pubProducts]);

  const bestProds = React.useMemo(() => {
    if (homeCfg?.bestProducts && homeCfg.bestProducts.length > 0) return homeCfg.bestProducts;
    // 즐겨찾기 많은 상품 또는 뒤에서부터
    const favs = (() => { try { return JSON.parse(localStorage.getItem('wu-favorites') || '[]'); } catch { return []; } })();
    const scored = pubProducts.map(p => ({ ...p, _score: favs.includes(p.id) ? 1 : 0 }));
    scored.sort((a, b) => b._score - a._score);
    return scored.slice(0, 6).map(p => ({
      id: p.id,
      title: p.parsed?.name || p.parsed?.kr || p.title || '상품',
      brand: p.parsed?.brand || p.brand || '',
      retail: p.parsed?.retail || p.retail || 0,
      photo: p.photos?.[0] || '',
    }));
  }, [homeCfg, pubProducts]);

  const evts = homeCfg?.events || [];
  const newStores = homeCfg?.newStores || [];

  // 발행상품 ID → 실제 데이터 매핑 (클릭 시 상세로 이동하기 위해)
  const prodMap = {};
  pubProducts.forEach(p => { prodMap[p.id] = p; });

  const goProduct = (item) => {
    const real = prodMap[item.id];
    if (real && window.__showProductDetail) window.__showProductDetail(real);
    else if (window.__switchTab) window.__switchTab('shop');
  };

  // 신제품/베스트 카드 렌더링 헬퍼
  const renderProductCard = (item, tag) => {
    const isFav = favIds.includes(item.id);
    return (
      <div key={item.id} style={{ position: 'relative', width: '100%' }}>
        <button onClick={() => goProduct(item)} style={{ flexShrink: 0, textAlign: 'left', cursor: 'pointer', background: 'none', border: 'none', padding: 0, width: '100%' }}>
          <div style={{ width: '100%', aspectRatio: '4/5', background: item.photo ? 'none' : 'linear-gradient(160deg, #E9E5DC, #DCD7CC)', overflow: 'hidden', position: 'relative' }}>
            {item.photo && <img src={item.photo} style={{ width: '100%', height: '100%', objectFit: 'cover' }} />}
            {tag && <span className="wu-tag" style={{ position: 'absolute', top: 8, left: 8, background: tag === 'NEW' ? 'var(--wu-lime)' : 'var(--wu-orange)', color: tag === 'NEW' ? 'var(--wu-ink)' : '#fff', fontSize: 9, padding: '3px 6px', fontFamily: 'var(--wu-mono)', fontWeight: 700 }}>{tag}</span>}
          </div>
          <div style={{ padding: '8px 0' }}>
            {item.brand && <div className="mono" style={{ fontSize: 9, color: 'var(--wu-mute)', letterSpacing: '0.06em' }}>{item.brand}</div>}
            <div className="kr" style={{ fontSize: 13, fontWeight: 700, marginTop: 2, lineHeight: 1.3, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{item.title}</div>
            {item.retail > 0 && <div className="display" style={{ fontSize: 14, marginTop: 2 }}>₩{Number(item.retail).toLocaleString()}</div>}
          </div>
        </button>
        <button onClick={(e) => toggleFav(item.id, e)} style={{ position: 'absolute', top: 8, right: 8, width: 30, height: 30, borderRadius: 999, background: 'rgba(0,0,0,0.25)', border: 'none', cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 2 }}>
          <svg width="16" height="16" viewBox="0 0 24 24" fill={isFav ? '#FF6600' : 'none'} stroke={isFav ? '#FF6600' : '#fff'} strokeWidth="2"><path d="M12 21C12 21 3 13.5 3 8.5 3 5.42 5.42 3 8.5 3c1.74 0 3.41.81 4.5 2.09C14.09 3.81 15.76 3 17.5 3 20.58 3 23 5.42 23 8.5 23 13.5 12 21 12 21z"/></svg>
        </button>
      </div>
    );
  };

  return (
    <div className="wu wu-scroll wu-consumer-wrap" style={{ height: '100%', overflow: 'auto', overflowX: 'hidden', background: 'var(--wu-bg)', paddingBottom: 70, WebkitOverflowScrolling: 'touch' }}>
      {/* Top bar + 카테고리 고정 */}
      <div style={{ position: 'sticky', top: 0, zIndex: 30, background: 'var(--wu-bg)' }}>
        <div style={{ padding: 'calc(env(safe-area-inset-top, 20px) + 12px) 16px 8px', display: 'flex', alignItems: 'center', justifyContent: 'center', position: 'relative' }}>
          {/* 중앙 로고 — 클릭 시 홈 */}
          <button onClick={() => { if (window.__switchTab) window.__switchTab('home'); }} style={{ background: 'none', border: 'none', cursor: 'pointer', padding: 0 }}>
            <WuLogo size={32} />
          </button>
          {/* 우측 아이콘 */}
          <div style={{ position: 'absolute', right: 16, display: 'flex', gap: 6 }}>
            <button onClick={() => { if (window.__switchTab) window.__switchTab('shop'); }} style={{ width: 36, height: 36, borderRadius: 999, background: '#fff', border: '1px solid var(--wu-line)', display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer' }}>
              <svg width="16" height="16" viewBox="0 0 20 20" fill="none" stroke="currentColor" strokeWidth="1.8"><circle cx="9" cy="9" r="6"/><path d="M14 14l4 4"/></svg>
            </button>
            <button onClick={() => { if (window.__switchTab) window.__switchTab('alerts'); }} style={{ width: 36, height: 36, borderRadius: 999, background: 'var(--wu-ink)', color: 'var(--wu-lime)', position: 'relative', display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer' }}>
              <svg width="16" height="16" viewBox="0 0 20 20" fill="none" stroke="currentColor" strokeWidth="1.8"><path d="M4 8a6 6 0 0112 0v3l2 3H2l2-3V8z"/><path d="M8 16a2 2 0 004 0"/></svg>
              <span style={{ position: 'absolute', top: 6, right: 6, width: 6, height: 6, borderRadius: 999, background: 'var(--wu-orange)' }} />
            </button>
          </div>
        </div>
        {/* Category chips — 로고 바로 아래 고정 (홈관리에서 설정) */}
        <div className="wu-scroll" style={{ display: 'flex', gap: 6, padding: '0 16px 10px', overflowX: 'auto', borderBottom: '1px solid var(--wu-line)' }}>
          {topMenus.map(c => <WuChip key={c} active={false} onClick={() => { window.__pendingShopCategory = c; if (window.__switchTab) window.__switchTab('shop'); }}>{c}</WuChip>)}
        </div>
      </div>

      {/* ═══ HERO BANNER CAROUSEL ═══ */}
      <div style={{ margin: '8px 16px 20px', position: 'relative', overflow: 'hidden' }}
        onTouchStart={onHeroTouchStart} onTouchEnd={onHeroTouchEnd}>
        <div style={{ display: 'flex', transition: 'transform 0.45s cubic-bezier(.4,0,.2,1)', transform: `translateX(-${heroIdx * 100}%)` }}>
          {heroSlides.map((slide, i) => (
            <div key={i} onClick={() => { if (slide.productId && prodMap[slide.productId] && window.__showProductDetail) window.__showProductDetail(prodMap[slide.productId]); else if (window.__switchTab) window.__switchTab('shop'); }}
              style={{ minWidth: '100%', position: 'relative', background: 'var(--wu-ink)', color: 'var(--wu-paper)', cursor: 'pointer' }}>
              {slide.image ? (
                <img src={slide.image} className="wu-hero-img" style={{ width: '100%', aspectRatio: '4/5', objectFit: 'cover', display: 'block' }} />
              ) : (
                <div className="wu-hero-img wu-placeholder dark" style={{ width: '100%', aspectRatio: '4/5' }}><span className="label">HERO</span></div>
              )}
              <div style={{ position: 'absolute', inset: 0, display: 'flex', flexDirection: 'column', justifyContent: 'space-between', padding: 18, background: 'linear-gradient(transparent 30%, rgba(0,0,0,0.6))' }}>
                <div>
                  <div className="display" style={{ fontSize: 38, lineHeight: 0.95, color: '#fff', whiteSpace: 'pre-wrap', textShadow: '0 2px 12px rgba(0,0,0,0.5)' }}>{slide.title || ''}</div>
                </div>
                <div>
                  <div className="kr" style={{ fontSize: 13, opacity: 0.9, lineHeight: 1.5, whiteSpace: 'pre-wrap' }}>{slide.subtitle || ''}</div>
                  <button className="wu-btn lime" style={{ marginTop: 10 }}>지금 보기 →</button>
                </div>
              </div>
            </div>
          ))}
        </div>
        {/* 슬라이드 카운터 + 도트 */}
        {heroSlides.length > 1 && (
          <div style={{ position: 'absolute', bottom: 14, left: 0, right: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 12 }}>
            <div style={{ display: 'flex', gap: 5 }}>
              {heroSlides.map((_, i) => (
                <button key={i} onClick={(e) => { e.stopPropagation(); setHeroIdx(i); }}
                  style={{ width: i === heroIdx ? 18 : 6, height: 6, borderRadius: 999, background: i === heroIdx ? '#fff' : 'rgba(255,255,255,0.45)', border: 'none', cursor: 'pointer', padding: 0, transition: 'all 0.3s' }} />
              ))}
            </div>
            <div className="mono" style={{ fontSize: 11, color: 'rgba(255,255,255,0.8)', background: 'rgba(0,0,0,0.35)', padding: '2px 8px', borderRadius: 999 }}>{heroIdx + 1} / {heroSlides.length}</div>
          </div>
        )}
      </div>

      {/* Ticker */}
      <div style={{ background: 'var(--wu-lime)', overflow: 'hidden', padding: '7px 0', marginBottom: 20 }}>
        <div className="wu-ticker-track display" style={{ fontSize: 13 }}>
          {[...Array(3)].map((_, i) => (
            <span key={i} style={{ display: 'inline-flex', gap: 24, paddingRight: 24 }}>
              {ticker.split('★').filter(Boolean).map((t, j) => <span key={j}>★ {t.trim()}</span>)}
            </span>
          ))}
        </div>
      </div>

      {/* ═══ NEW DROPS — 관리자 선택 신제품 ═══ */}
      {newProds.length > 0 && (
        <>
          <div style={{ padding: '28px 16px 8px', display: 'flex', alignItems: 'baseline', justifyContent: 'space-between' }}>
            <div>
              <div className="display" style={{ fontSize: 22 }}>NEW DROPS</div>
              <div className="kr mono" style={{ fontSize: 11, color: 'var(--wu-mute)' }}>신상품 추천</div>
            </div>
            <button onClick={() => { if (window.__switchTab) window.__switchTab('shop'); }} className="mono" style={{ fontSize: 11, color: 'var(--wu-mute)', cursor: 'pointer', background: 'none', border: 'none' }}>ALL →</button>
          </div>
          <div className="wu-grid-new" style={{ display: 'flex', flexWrap: 'wrap', gap: 8, padding: '0 16px' }}>
            {newProds.slice(0, 10).map(p => <div key={p.id} style={{ width: 'calc(33.333% - 6px)' }}>{renderProductCard(p, 'NEW')}</div>)}
          </div>
        </>
      )}

      {/* ═══ BEST — 관리자 선택 베스트 ═══ */}
      {bestProds.length > 0 && (
        <>
          <div style={{ padding: '28px 16px 8px', display: 'flex', alignItems: 'baseline', justifyContent: 'space-between' }}>
            <div>
              <div className="display" style={{ fontSize: 22 }}>BEST</div>
              <div className="kr mono" style={{ fontSize: 11, color: 'var(--wu-mute)' }}>인기 상품</div>
            </div>
            <button onClick={() => { if (window.__switchTab) window.__switchTab('shop'); }} className="mono" style={{ fontSize: 11, color: 'var(--wu-mute)', cursor: 'pointer', background: 'none', border: 'none' }}>ALL →</button>
          </div>
          <div className="wu-grid-new" style={{ display: 'flex', flexWrap: 'wrap', gap: 8, padding: '0 16px' }}>
            {bestProds.slice(0, 10).map(p => <div key={p.id} style={{ width: 'calc(33.333% - 6px)' }}>{renderProductCard(p, 'BEST')}</div>)}
          </div>
        </>
      )}

      {/* ═══ EVENTS ═══ */}
      {evts.length > 0 && (
        <>
          <div style={{ padding: '28px 16px 8px' }}>
            <div className="display" style={{ fontSize: 22 }}>EVENTS</div>
            <div className="kr mono" style={{ fontSize: 11, color: 'var(--wu-mute)' }}>이번 달 이벤트</div>
          </div>
          <div className="wu-scroll" style={{ display: 'flex', gap: 10, padding: '0 16px', overflowX: 'auto' }}>
            {evts.map((e, i) => (
              <div key={i} style={{ minWidth: 200, flexShrink: 0, background: 'var(--wu-paper)', border: '1px solid var(--wu-line)', overflow: 'hidden' }}>
                {e.image ? (
                  <img src={e.image} style={{ width: '100%', height: 120, objectFit: 'cover' }} />
                ) : (
                  <div style={{ width: '100%', height: 60, background: e.color || '#FF6B35' }} />
                )}
                <div style={{ padding: 14 }}>
                  <div className="kr" style={{ fontSize: 15, fontWeight: 700 }}>{e.title}</div>
                  <div className="kr" style={{ fontSize: 12, color: 'var(--wu-mute)', marginTop: 4, lineHeight: 1.5 }}>{e.body}</div>
                </div>
              </div>
            ))}
          </div>
        </>
      )}

      {/* ═══ NEW STORES ═══ */}
      {newStores.length > 0 && (
        <>
          <div style={{ padding: '28px 16px 8px' }}>
            <div className="display" style={{ fontSize: 22 }}>NEW STORES</div>
            <div className="kr mono" style={{ fontSize: 11, color: 'var(--wu-mute)' }}>신규 매장 안내</div>
          </div>
          <div style={{ padding: '0 16px' }}>
            {newStores.map((s, i) => (
              <button key={i} onClick={() => { window.__pendingMapStore = s.name; if (window.__switchTab) window.__switchTab('map'); }} style={{ display: 'flex', width: '100%', padding: '16px 14px', background: 'var(--wu-paper)', border: '1px solid var(--wu-line)', marginBottom: 8, cursor: 'pointer', textAlign: 'left', alignItems: 'center', justifyContent: 'space-between', transition: 'box-shadow 0.2s' }}>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div className="display" style={{ fontSize: 18, lineHeight: 1.2 }}>{s.name}</div>
                  <div className="kr" style={{ fontSize: 11, color: 'var(--wu-mute)', marginTop: 4, lineHeight: 1.4, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{s.address}</div>
                </div>
                <div style={{ width: 40, height: 40, borderRadius: 999, background: 'var(--wu-orange)', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0, marginLeft: 12 }}>
                  <svg width="16" height="16" viewBox="0 0 20 20" fill="none" stroke="#fff" strokeWidth="2"><path d="M10 2a6 6 0 00-6 6c0 5 6 10 6 10s6-5 6-10a6 6 0 00-6-6zm0 8a2 2 0 100-4 2 2 0 000 4z"/></svg>
                </div>
              </button>
            ))}
          </div>
        </>
      )}

      {/* 하단 매장 CTA (기본) */}
      {newStores.length === 0 && (
        <button onClick={() => { if (window.__switchTab) window.__switchTab('map'); }} style={{ display: 'block', width: 'calc(100% - 32px)', margin: '28px 16px 0', border: '1.5px solid var(--wu-ink)', padding: 16, background: 'none', cursor: 'pointer', textAlign: 'left' }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
            <div>
              <div className="mono" style={{ fontSize: 10, color: 'var(--wu-mute)' }}>STORE MAP</div>
              <div className="display" style={{ fontSize: 22, marginTop: 6 }}>매장 찾기</div>
              <div className="kr" style={{ fontSize: 11, color: 'var(--wu-mute)', marginTop: 2 }}>가까운 매장을 찾아보세요</div>
            </div>
            <div style={{ width: 44, height: 44, borderRadius: 999, background: 'var(--wu-lime)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
              <svg width="18" height="18" viewBox="0 0 20 20" fill="none" stroke="var(--wu-ink)" strokeWidth="2"><path d="M10 2a6 6 0 00-6 6c0 5 6 10 6 10s6-5 6-10a6 6 0 00-6-6zm0 8a2 2 0 100-4 2 2 0 000 4z"/></svg>
            </div>
          </div>
        </button>
      )}

      {/* ═══ ALL PRODUCTS — 전체 상품 무한 스크롤 ═══ */}
      {pubProducts.length > 0 && (
        <>
          <div style={{ padding: '32px 16px 8px', display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', borderTop: '1px solid var(--wu-line)', marginTop: 28 }}>
            <div>
              <div className="display" style={{ fontSize: 22 }}>ALL PRODUCTS</div>
              <div className="kr mono" style={{ fontSize: 11, color: 'var(--wu-mute)' }}>전체 상품 {pubProducts.length}개</div>
            </div>
          </div>
          <div className="wu-grid-products" style={{ display: 'flex', flexWrap: 'wrap', padding: '0 16px', gap: 10 }}>
            {pubProducts.slice(0, visibleCount).map(p => {
              const pid = p.id || (p.parsed && p.parsed.code) || p.title || '';
              const isFav = favIds.includes(pid);
              return (
                <div key={p.id} style={{ width: 'calc(50% - 5px)', position: 'relative', boxSizing: 'border-box' }}>
                  <button onClick={() => { if (window.__showProductDetail) window.__showProductDetail(p); }} style={{ textAlign: 'left', cursor: 'pointer', background: 'none', border: 'none', padding: 0, width: '100%' }}>
                    <div style={{ width: '100%', height: 0, paddingBottom: '125%', position: 'relative', background: p.photos?.[0] ? '#f0f0f0' : 'linear-gradient(160deg, #E9E5DC, #DCD7CC)', overflow: 'hidden', borderRadius: 4 }}>
                      {p.photos?.[0] && <img src={p.photos[0]} loading="lazy" style={{ position: 'absolute', top: 0, left: 0, width: '100%', height: '100%', objectFit: 'cover', display: 'block' }} />}
                    </div>
                    <div style={{ padding: '8px 2px 4px' }}>
                      {(p.parsed?.brand || p.brand) && <div className="mono" style={{ fontSize: 9, color: 'var(--wu-mute)', letterSpacing: '0.06em' }}>{p.parsed?.brand || p.brand}</div>}
                      <div className="kr" style={{ fontSize: 13, fontWeight: 700, marginTop: 2, lineHeight: 1.3, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{p.parsed?.name || p.parsed?.kr || p.kr || p.title || '상품'}</div>
                      {(p.parsed?.retail || p.retail) && <div className="display" style={{ fontSize: 14, marginTop: 2 }}>₩{Number(p.parsed?.retail || p.retail).toLocaleString()}</div>}
                    </div>
                  </button>
                  <button onClick={(e) => toggleFav(pid, e)} style={{ position: 'absolute', top: 8, right: 8, width: 30, height: 30, borderRadius: 999, background: 'rgba(0,0,0,0.25)', border: 'none', cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 2 }}>
                    <svg width="16" height="16" viewBox="0 0 24 24" fill={isFav ? '#FF6600' : 'none'} stroke={isFav ? '#FF6600' : '#fff'} strokeWidth="2"><path d="M12 21C12 21 3 13.5 3 8.5 3 5.42 5.42 3 8.5 3c1.74 0 3.41.81 4.5 2.09C14.09 3.81 15.76 3 17.5 3 20.58 3 23 5.42 23 8.5 23 13.5 12 21 12 21z"/></svg>
                  </button>
                </div>
              );
            })}
          </div>
          {visibleCount < pubProducts.length && (
            <div ref={loadMoreRef} style={{ textAlign: 'center', padding: '20px 0' }}>
              <div className="kr" style={{ fontSize: 12, color: 'var(--wu-mute)' }}>더 불러오는 중...</div>
            </div>
          )}
          {visibleCount >= pubProducts.length && pubProducts.length > 0 && (
            <div style={{ textAlign: 'center', padding: '24px 0 8px' }}>
              <div className="mono" style={{ fontSize: 10, color: 'var(--wu-mute)' }}>— END —</div>
            </div>
          )}
        </>
      )}
    </div>
  );
}

// ────────────────────────────────────────────────────
// Consumer STORE MAP
// ────────────────────────────────────────────────────
function ConsumerMap({ variant = 'pill' }) {
  const mapRef = React.useRef(null);
  const mapObjRef = React.useRef(null);
  const markersRef = React.useRef([]);
  const [realStores, setRealStores] = useState([]);
  const [selected, setSelected] = useState(null);
  const [storeInfo, setStoreInfo] = useState(null);
  const [mapReady, setMapReady] = useState(false);
  const [search, setSearch] = useState('');
  const [activeRegion, setActiveRegion] = useState('전체');
  const [markersReady, setMarkersReady] = useState(0);
  const [lightboxIdx, setLightboxIdx] = useState(null);
  const [selectedPos, setSelectedPos] = useState(null); // { lat, lng }

  const REGIONS = ['전체', '서울', '경기', '인천', '부산', '대구', '대전', '광주', '울산', '충북', '충남', '전북', '전남', '경북', '경남', '강원', '제주'];

  // 매장 검색 매칭 함수 (이름, 주소, 매장ID, 담당자 전체 검색)
  const matchStore = (store, query, region) => {
    const fields = [store.name, store.address, store.storeId, store.manager, store.email].map(f => (f || '').toLowerCase());
    const regionMatch = region === '전체' || fields.some(f => f.includes(region.toLowerCase()));
    const searchMatch = !query || fields.some(f => f.includes(query.toLowerCase()));
    return regionMatch && searchMatch;
  };

  // IndexedDB에서 실제 매장 로드
  useEffect(() => {
    if (typeof getAllStores === 'function') {
      getAllStores().then(s => setRealStores(s)).catch(() => {});
    }
  }, []);

  // 매장 선택 시 점주 저장 정보 로드
  useEffect(() => {
    if (!selected) { setStoreInfo(null); return; }
    if (typeof getStoreInfo === 'function' || window.getStoreInfo) {
      const fn = window.getStoreInfo || getStoreInfo;
      fn(selected.name).then(info => setStoreInfo(info)).catch(() => setStoreInfo(null));
    }
  }, [selected]);

  // 카카오맵 SDK 로드 + 지도 생성
  useEffect(() => {
    const apiKey = localStorage.getItem('wu-kakao-key');
    if (!apiKey || !mapRef.current) return;
    const initMap = () => {
      try {
        if (!window.kakao || !window.kakao.maps) return;
        window.kakao.maps.load(() => { setMapReady(true); });
      } catch(e) {}
    };
    if (window.kakao && window.kakao.maps) { initMap(); return; }
    if (document.getElementById('kakao-map-script')) { initMap(); return; }
    const script = document.createElement('script');
    script.id = 'kakao-map-script';
    script.src = 'https://dapi.kakao.com/v2/maps/sdk.js?appkey=' + apiKey + '&libraries=services&autoload=false';
    script.onload = initMap;
    script.onerror = () => {};
    document.head.appendChild(script);
  }, []);

  // 마커 생성
  useEffect(() => {
    if (!mapReady || !mapRef.current || realStores.length === 0) return;
    try {
      const map = new kakao.maps.Map(mapRef.current, {
        center: new kakao.maps.LatLng(36.5, 127.0),
        level: 13,
      });
      map.addControl(new kakao.maps.ZoomControl(), kakao.maps.ControlPosition.RIGHT);
      mapObjRef.current = map;
      const geocoder = new kakao.maps.services.Geocoder();
      const places = new kakao.maps.services.Places();
      const newMarkers = [];

      // 주소 정제 — 상세주소(층, 호, 건물명 등) 제거하여 지오코딩 성공률 향상
      const cleanAddress = (addr) => {
        if (!addr) return '';
        let cleaned = addr.trim();
        // 괄호 안 내용 제거 (건물명 등)
        cleaned = cleaned.replace(/\([^)]*\)/g, '').trim();
        // 상세주소 패턴 제거: "3층", "B1F", "102호", "201동" 등
        cleaned = cleaned.replace(/\s+(?:\d+층|\d+F|B\d+F?|\d+호|\d+동\s*\d*호?|지하\s*\d*층?).*$/i, '').trim();
        // 끝에 붙은 건물명/상세 제거 (숫자-숫자 뒤의 텍스트)
        cleaned = cleaned.replace(/(\d+[-−]\d+)\s+.+$/, '$1').trim();
        // 그래도 남은 끝부분 잡음 제거 (쉼표 이후)
        cleaned = cleaned.replace(/,.*$/, '').trim();
        return cleaned;
      };

      // 3단계 지오코딩: 1) 원본 주소 → 2) 정제 주소 → 3) 키워드 검색
      const geocodeStore = (s) => {
        if (!s.address || !s.address.trim()) return;
        const rawAddr = s.address.trim();
        const cleanAddr = cleanAddress(rawAddr);

        const addMarker = (lat, lng) => {
          const pos = new kakao.maps.LatLng(lat, lng);
          const marker = new kakao.maps.Marker({ map, position: pos, title: s.name });
          kakao.maps.event.addListener(marker, 'click', () => {
            setSelected(s);
            setSelectedPos({ lat, lng });
          });
          newMarkers.push({ marker, store: s });
          markersRef.current = [...newMarkers];
          setMarkersReady(prev => prev + 1);
        };

        // 1단계: 원본 주소로 지오코딩
        try {
          geocoder.addressSearch(rawAddr, (r1, s1) => {
            if (s1 === kakao.maps.services.Status.OK) {
              addMarker(r1[0].y, r1[0].x);
              return;
            }
            // 2단계: 정제된 주소로 재시도
            if (cleanAddr && cleanAddr !== rawAddr) {
              geocoder.addressSearch(cleanAddr, (r2, s2) => {
                if (s2 === kakao.maps.services.Status.OK) {
                  addMarker(r2[0].y, r2[0].x);
                  return;
                }
                // 3단계: 매장명 + 주소로 키워드 검색
                const keyword = s.name + ' ' + cleanAddr;
                places.keywordSearch(keyword, (r3, s3) => {
                  if (s3 === kakao.maps.services.Status.OK && r3.length > 0) {
                    addMarker(r3[0].y, r3[0].x);
                  } else {
                    // 4단계: 주소만으로 키워드 검색
                    places.keywordSearch(cleanAddr, (r4, s4) => {
                      if (s4 === kakao.maps.services.Status.OK && r4.length > 0) {
                        addMarker(r4[0].y, r4[0].x);
                      } else {
                        console.warn('[MAP] 모든 지오코딩 실패:', s.name, rawAddr);
                      }
                    });
                  }
                });
              });
            } else {
              // 정제 주소가 같으면 바로 키워드 검색
              const keyword = s.name + ' ' + rawAddr;
              places.keywordSearch(keyword, (r3, s3) => {
                if (s3 === kakao.maps.services.Status.OK && r3.length > 0) {
                  addMarker(r3[0].y, r3[0].x);
                } else {
                  places.keywordSearch(rawAddr, (r4, s4) => {
                    if (s4 === kakao.maps.services.Status.OK && r4.length > 0) {
                      addMarker(r4[0].y, r4[0].x);
                    } else {
                      console.warn('[MAP] 모든 지오코딩 실패:', s.name, rawAddr);
                    }
                  });
                }
              });
            }
          });
        } catch(e) {
          console.warn('[MAP] 지오코딩 오류:', s.name, e.message);
        }
      };

      realStores.forEach(s => geocodeStore(s));
    } catch(e) {}
  }, [mapReady, realStores]);

  // 검색/필터 변경 시 마커 show/hide
  useEffect(() => {
    if (!markersRef.current.length || !mapObjRef.current) return;
    const q = search.trim();
    let visibleBounds = null;
    try { visibleBounds = new kakao.maps.LatLngBounds(); } catch(e) {}
    let visCount = 0;

    markersRef.current.forEach(({ marker, store }) => {
      const visible = matchStore(store, q, activeRegion);
      if (visible) {
        marker.setMap(mapObjRef.current);
        if (visibleBounds) { try { visibleBounds.extend(marker.getPosition()); } catch(e) {} }
        visCount++;
      } else {
        marker.setMap(null);
      }
    });

    if (visCount > 0 && visibleBounds && mapObjRef.current) {
      try {
        if (visCount === 1) {
          mapObjRef.current.setCenter(visibleBounds.getSouthWest());
          mapObjRef.current.setLevel(5);
        } else {
          mapObjRef.current.setBounds(visibleBounds);
        }
      } catch(e) {}
    }
  }, [search, activeRegion, markersReady]);

  // ── pendingMapStore 수신: 특정 매장으로 자동 이동 ──
  useEffect(() => {
    const checkPending = () => {
      if (!window.__pendingMapStore) return;
      // 마커가 아직 안 만들어졌으면 대기
      if (!markersRef.current.length || !mapObjRef.current) return;
      const targetName = window.__pendingMapStore;
      delete window.__pendingMapStore;
      // 매장 찾기
      const found = markersRef.current.find(({ store }) =>
        store.name && store.name.trim() === targetName.trim()
      );
      if (found) {
        const pos = found.marker.getPosition();
        setSelected(found.store);
        setSelectedPos({ lat: pos.getLat(), lng: pos.getLng() });
        mapObjRef.current.setCenter(pos);
        mapObjRef.current.setLevel(3);
        // 필터 초기화
        setSearch('');
        setActiveRegion('전체');
      }
    };
    checkPending();
    const timer = setInterval(checkPending, 300);
    return () => clearInterval(timer);
  }, [markersReady]);

  const handleRegion = (r) => {
    setActiveRegion(r);
    setSearch('');
    setSelected(null);
  };

  const filteredCount = realStores.filter(s => matchStore(s, search.trim(), activeRegion)).length;

  // 바텀시트 높이 (탭바 위, 화면 2/3)
  const tabH = variant === 'pill' ? 88 : 68;

  return (
    <div className="wu" style={{ height: '100%', background: 'var(--wu-bg)', position: 'relative', overflow: 'hidden' }}>
      {/* Map */}
      <div ref={mapRef} style={{ position: 'absolute', inset: 0 }} />

      {/* Fallback if no API key */}
      {!localStorage.getItem('wu-kakao-key') && (
        <div style={{ position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', background: '#E9E5DC' }}>
          <div className="kr" style={{ fontSize: 14, color: 'var(--wu-mute)', textAlign: 'center' }}>카카오맵 API 키가 설정되지 않았습니다<br/><span className="mono" style={{ fontSize: 11 }}>HQ 관리자에서 설정하세요</span></div>
        </div>
      )}

      {/* Top bar — search */}
      <div style={{ position: 'absolute', top: 'calc(env(safe-area-inset-top, 20px) + 12px)', left: 16, right: 16, display: 'flex', gap: 8, zIndex: 20 }}>
        <div style={{ flex: 1, background: '#fff', borderRadius: 999, padding: '10px 16px', display: 'flex', alignItems: 'center', gap: 8, boxShadow: '0 4px 12px rgba(0,0,0,0.08)' }}>
          <svg width="14" height="14" viewBox="0 0 20 20" fill="none" stroke="currentColor" strokeWidth="2"><circle cx="9" cy="9" r="6"/><path d="M14 14l4 4"/></svg>
          <input value={search} onChange={e => { setSearch(e.target.value); setActiveRegion('전체'); }} placeholder="지역·매장 검색" className="kr" style={{ border: 'none', outline: 'none', fontSize: 13, flex: 1, background: 'transparent' }} />
          {search && <button onClick={() => { setSearch(''); setActiveRegion('전체'); }} style={{ background: 'none', border: 'none', cursor: 'pointer', fontSize: 14, color: 'var(--wu-mute)', padding: 0 }}>✕</button>}
        </div>
      </div>

      {/* Region filter buttons */}
      <div style={{ position: 'absolute', top: 'calc(env(safe-area-inset-top, 20px) + 88px)', left: 16, right: 16, display: 'flex', gap: 6, flexWrap: 'nowrap', overflowX: 'auto', zIndex: 20, paddingBottom: 4 }} className="wu-scroll">
        {REGIONS.map(r => {
          const isActive = activeRegion === r && !search;
          const label = r === '전체' ? '전체 ' + filteredCount : r;
          return (
            <button key={r} onClick={() => handleRegion(r)} style={{ background: isActive ? 'var(--wu-ink)' : '#fff', color: isActive ? 'var(--wu-paper)' : 'var(--wu-ink)', padding: '6px 12px', borderRadius: 999, fontSize: 11, fontWeight: 600, boxShadow: '0 2px 6px rgba(0,0,0,0.06)', border: 'none', cursor: 'pointer', whiteSpace: 'nowrap', flexShrink: 0 }} className="kr">{label}</button>
          );
        })}
      </div>

      {/* Result count badge */}
      {(search || activeRegion !== '전체') && (
        <div style={{ position: 'absolute', top: 148, left: 16, zIndex: 20 }}>
          <span className="kr" style={{ background: 'rgba(0,0,0,0.7)', color: '#fff', padding: '4px 10px', borderRadius: 999, fontSize: 11 }}>검색 결과 {filteredCount}개</span>
        </div>
      )}

      {/* ═══ 매장 상세 바텀시트 — 화면 2/3 높이 ═══ */}
      {selected && (
        <div style={{
          position: 'absolute', bottom: tabH, left: 0, right: 0,
          height: 'calc(66vh)',
          background: 'var(--wu-paper)',
          borderRadius: '20px 20px 0 0',
          boxShadow: '0 -12px 48px rgba(0,0,0,0.18)',
          zIndex: 30,
          display: 'flex', flexDirection: 'column',
          overflow: 'hidden',
        }}>
          {/* Handle bar */}
          <div style={{ padding: '10px 0 0', flexShrink: 0 }}>
            <div style={{ width: 36, height: 4, borderRadius: 999, background: '#CDCAC3', margin: '0 auto' }} />
          </div>

          {/* Scrollable content */}
          <div className="wu-scroll" style={{ flex: 1, overflow: 'auto', padding: '12px 20px 20px' }}>

            {/* Header — 매장명 + 닫기 */}
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: 14 }}>
              <div>
                <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
                  <span className="display" style={{ fontSize: 24 }}>{selected.name}</span>
                  {selected.storeId && <span className="mono" style={{ fontSize: 10, color: 'var(--wu-mute)', background: 'var(--wu-bg)', padding: '2px 8px', borderRadius: 4 }}>{selected.storeId}</span>}
                </div>
                {selected.manager && <div className="kr" style={{ fontSize: 12, color: 'var(--wu-mute)', marginTop: 2 }}>담당자: {selected.manager}</div>}
              </div>
              <button onClick={() => setSelected(null)} style={{ width: 32, height: 32, borderRadius: 999, background: 'var(--wu-bg)', border: 'none', cursor: 'pointer', fontSize: 16, display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>✕</button>
            </div>

            {/* 기본 정보 카드 */}
            <div style={{ background: 'var(--wu-bg)', padding: 16, marginBottom: 12 }}>
              {/* 주소 — 클릭 시 카카오맵 길찾기 */}
              {selectedPos ? (
                <a href={'https://map.kakao.com/link/to/' + encodeURIComponent(selected.name) + ',' + selectedPos.lat + ',' + selectedPos.lng} target="_blank" rel="noopener noreferrer" style={{ display: 'flex', gap: 8, marginBottom: 10, textDecoration: 'none', color: 'inherit' }}>
                  <svg width="16" height="16" viewBox="0 0 20 20" fill="none" stroke="var(--wu-orange)" strokeWidth="1.8" style={{ flexShrink: 0, marginTop: 2 }}><path d="M10 2C6.7 2 4 4.7 4 8c0 5 6 10 6 10s6-5 6-10c0-3.3-2.7-6-6-6z"/><circle cx="10" cy="8" r="2"/></svg>
                  <span className="kr" style={{ fontSize: 14, lineHeight: 1.5, color: 'var(--wu-orange)', textDecoration: 'underline', textDecorationColor: 'var(--wu-line)' }}>{selected.address || '주소 없음'}</span>
                </a>
              ) : (
                <div style={{ display: 'flex', gap: 8, marginBottom: 10 }}>
                  <svg width="16" height="16" viewBox="0 0 20 20" fill="none" stroke="var(--wu-orange)" strokeWidth="1.8" style={{ flexShrink: 0, marginTop: 2 }}><path d="M10 2C6.7 2 4 4.7 4 8c0 5 6 10 6 10s6-5 6-10c0-3.3-2.7-6-6-6z"/><circle cx="10" cy="8" r="2"/></svg>
                  <span className="kr" style={{ fontSize: 14, lineHeight: 1.5 }}>{selected.address || '주소 없음'}</span>
                </div>
              )}
              {/* 전화 — 클릭 시 바로 전화 */}
              {(storeInfo?.phone || selected.mobile || selected.phone) ? (
                <a href={'tel:' + (storeInfo?.phone || selected.mobile || selected.phone)} style={{ display: 'flex', gap: 8, marginBottom: storeInfo?.hours ? 10 : 0, textDecoration: 'none', color: 'inherit' }}>
                  <svg width="16" height="16" viewBox="0 0 20 20" fill="none" stroke="var(--wu-orange)" strokeWidth="1.8" style={{ flexShrink: 0, marginTop: 2 }}><path d="M3 4h4l2 3-2.5 2.5a11.4 11.4 0 005 5L14 12l3 2v4a1 1 0 01-1 1A16 16 0 012 5a1 1 0 011-1z"/></svg>
                  <span className="mono" style={{ fontSize: 14, color: 'var(--wu-orange)' }}>{storeInfo?.phone || selected.mobile || selected.phone}</span>
                </a>
              ) : (
                <div style={{ display: 'flex', gap: 8, marginBottom: storeInfo?.hours ? 10 : 0 }}>
                  <svg width="16" height="16" viewBox="0 0 20 20" fill="none" stroke="var(--wu-orange)" strokeWidth="1.8" style={{ flexShrink: 0, marginTop: 2 }}><path d="M3 4h4l2 3-2.5 2.5a11.4 11.4 0 005 5L14 12l3 2v4a1 1 0 01-1 1A16 16 0 012 5a1 1 0 011-1z"/></svg>
                  <span className="mono" style={{ fontSize: 14, color: 'var(--wu-mute)' }}>번호 없음</span>
                </div>
              )}
              {/* 운영시간 (점주 입력) */}
              {storeInfo?.hours && (
                <div style={{ display: 'flex', gap: 8, marginBottom: storeInfo?.holidays ? 10 : 0 }}>
                  <svg width="16" height="16" viewBox="0 0 20 20" fill="none" stroke="var(--wu-orange)" strokeWidth="1.8" style={{ flexShrink: 0, marginTop: 2 }}><circle cx="10" cy="10" r="8"/><path d="M10 6v4l3 2"/></svg>
                  <span className="kr" style={{ fontSize: 14 }}>{storeInfo.hours}</span>
                </div>
              )}
              {/* 휴무일 */}
              {storeInfo?.holidays && (
                <div style={{ display: 'flex', gap: 8 }}>
                  <svg width="16" height="16" viewBox="0 0 20 20" fill="none" stroke="var(--wu-orange)" strokeWidth="1.8" style={{ flexShrink: 0, marginTop: 2 }}><rect x="3" y="4" width="14" height="14" rx="2"/><path d="M3 8h14"/><path d="M7 2v4M13 2v4"/></svg>
                  <span className="kr" style={{ fontSize: 14, color: '#C44' }}>휴무: {storeInfo.holidays}</span>
                </div>
              )}
            </div>

            {/* 주차장 안내 */}
            {storeInfo?.parking && (
              <div style={{ background: 'var(--wu-bg)', padding: 16, marginBottom: 12 }}>
                <div className="mono" style={{ fontSize: 10, color: 'var(--wu-mute)', marginBottom: 6, letterSpacing: '0.06em' }}>PARKING · 주차 안내</div>
                <div className="kr" style={{ fontSize: 14, lineHeight: 1.6 }}>{storeInfo.parking}</div>
              </div>
            )}

            {/* 매장 소개 */}
            {storeInfo?.intro && (
              <div style={{ background: 'var(--wu-bg)', padding: 16, marginBottom: 12 }}>
                <div className="mono" style={{ fontSize: 10, color: 'var(--wu-mute)', marginBottom: 6, letterSpacing: '0.06em' }}>ABOUT · 매장 소개</div>
                <div className="kr" style={{ fontSize: 14, lineHeight: 1.8, whiteSpace: 'pre-wrap' }}>{storeInfo.intro}</div>
              </div>
            )}

            {/* 매장 사진 */}
            {storeInfo?.photos && storeInfo.photos.length > 0 && (
              <div style={{ marginBottom: 12 }}>
                <div className="mono" style={{ fontSize: 10, color: 'var(--wu-mute)', marginBottom: 8, letterSpacing: '0.06em' }}>PHOTOS · 매장 사진</div>
                <div style={{ display: 'flex', gap: 8, overflowX: 'auto' }} className="wu-scroll">
                  {storeInfo.photos.map((src, i) => (
                    <div key={i} style={{ width: 140, height: 140, flexShrink: 0, overflow: 'hidden', background: '#ddd' }}>
                      <img src={src} alt="" style={{ width: '100%', height: '100%', objectFit: 'cover' }} />
                    </div>
                  ))}
                </div>
              </div>
            )}

            {/* 이벤트 / 공지 */}
            {storeInfo?.events && (
              <div style={{ background: 'var(--wu-ink)', padding: 16, marginBottom: 12 }}>
                <div className="mono" style={{ fontSize: 10, color: 'var(--wu-lime)', marginBottom: 10, letterSpacing: '0.06em' }}>NOTICE · 매장 공지</div>
                {storeInfo.events.split('\n').filter(l => l.trim()).map((line, i) => {
                  const isEvt = line.includes('[이벤트]');
                  const isNotice = line.includes('[공지]');
                  const isNew = line.includes('[신상]');
                  const c = isEvt ? 'var(--wu-orange)' : isNotice ? 'var(--wu-lime)' : isNew ? '#4A9EFF' : 'var(--wu-mute)';
                  return (
                    <div key={i} style={{ padding: '10px 12px', marginBottom: 6, background: '#1A1A17', borderLeft: '3px solid ' + c }}>
                      <div className="kr" style={{ fontSize: 13, color: 'var(--wu-paper)', lineHeight: 1.5 }}>{line}</div>
                    </div>
                  );
                })}
              </div>
            )}

            {/* 점주 정보 미등록 시 */}
            {!storeInfo && (
              <div style={{ background: 'var(--wu-bg)', padding: 20, textAlign: 'center', marginBottom: 12 }}>
                <div className="kr" style={{ fontSize: 13, color: 'var(--wu-mute)' }}>아직 매장 상세 정보가 등록되지 않았습니다</div>
              </div>
            )}

            {/* 하단 액션 버튼 */}
            <div style={{ display: 'flex', gap: 8 }}>
              <button onClick={() => setSelected(null)} className="wu-btn" style={{ flex: 1, padding: '14px', fontSize: 14, fontWeight: 700 }}>닫기</button>
              {(storeInfo?.phone || selected.mobile || selected.phone) && (
                <a href={'tel:' + (storeInfo?.phone || selected.mobile || selected.phone)} className="wu-btn ghost" style={{ flex: 1, textAlign: 'center', textDecoration: 'none', padding: '14px', fontSize: 14, fontWeight: 700, display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 6 }}>
                  <svg width="16" height="16" viewBox="0 0 20 20" fill="none" stroke="currentColor" strokeWidth="1.8"><path d="M3 4h4l2 3-2.5 2.5a11.4 11.4 0 005 5L14 12l3 2v4a1 1 0 01-1 1A16 16 0 012 5a1 1 0 011-1z"/></svg>
                  전화
                </a>
              )}
              {selectedPos && (
                <a href={'https://map.kakao.com/link/to/' + encodeURIComponent(selected.name) + ',' + selectedPos.lat + ',' + selectedPos.lng} target="_blank" rel="noopener noreferrer" className="wu-btn" style={{ flex: 1, textAlign: 'center', textDecoration: 'none', padding: '14px', fontSize: 14, fontWeight: 700, background: '#FEE500', color: '#191919', border: 'none', display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 6 }}>
                  <svg width="16" height="16" viewBox="0 0 20 20" fill="none" stroke="#191919" strokeWidth="1.8"><path d="M10 2L3 10h4v6h6v-6h4L10 2z"/></svg>
                  길찾기
                </a>
              )}
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

Object.assign(window, { ConsumerHome, ConsumerMap, ConsumerStoreDetail: ConsumerMap, ConsumerProductDetail });
