function AddPostsSheet({ onClose, onDone }) {
  const { BottomSheet, Button, Avatar } = window.SpotureDesignSystem_f7ad96;
  const [sel, setSel] = React.useState([]);
  const [menuPost, setMenuPost] = React.useState(null);
  const pool = [
    { menu: '순대국', place: '할매순대국 강남점' }, { menu: '마제소바', place: '멘야하나비 역삼' },
    { menu: '수육', place: null }, { menu: '로제떡볶이', place: null },
    { menu: '핸드드립', place: '로스트림 로스터스' }, { menu: '뼈해장국', place: '역삼 해장촌' },
    { menu: '돈까스', place: '연돈부부' }, { menu: '냉면', place: '을밀대 역삼' }, { menu: '샌드위치', place: null }
  ];
  const toggle = i => setSel(p => p.includes(i) ? p.filter(x => x !== i) : [...p, i]);
  return (
    <BottomSheet title="컬렉션에 담기" onClose={onClose} footer={<Button variant="primary" disabled={!sel.length} onClick={() => onDone ? onDone(sel.length) : onClose()}>{sel.length ? sel.length + '개 담기' : '담을 게시물을 선택해주세요'}</Button>}>
      <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', marginBottom: 10 }}>
        <span style={{ font: 'var(--text-body-strong)' }}>내 게시물</span>
        <span style={{ font: 'var(--text-small)', color: 'var(--text-secondary)' }}>{sel.length}개 선택</span>
      </div>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3,1fr)', gap: 8 }}>
        {pool.map((p, i) => {
          const on = sel.includes(i);
          return (
            <div key={i} onClick={() => toggle(i)} style={{ width: '100%', aspectRatio: '1', borderRadius: 'var(--radius-tile)', background: 'var(--surface-2)', position: 'relative', display: 'flex', alignItems: 'center', justifyContent: 'center', overflow: 'hidden', cursor: 'pointer', boxShadow: on ? '0 0 0 2px var(--text-accent)' : 'none' }}>
              <i className="ti ti-photo" style={{ fontSize: 20, color: 'var(--text-muted)' }}></i>
              <span style={{ position: 'absolute', left: 6, bottom: 6, font: 'var(--text-micro)', color: '#fff', background: 'rgba(26,26,26,.68)', borderRadius: 999, padding: '3px 7px' }}>#{p.menu}</span>
              <div style={{ position: 'absolute', right: 6, top: 6, width: 20, height: 20, borderRadius: '50%', background: on ? 'var(--text-accent)' : 'rgba(255,255,255,.85)', border: on ? 'none' : '1.5px solid var(--border-strong)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                {on && <i className="ti ti-check" style={{ fontSize: 12, color: '#fff' }}></i>}
              </div>
            </div>
          );
        })}
      </div>
    </BottomSheet>
  );
}
window.AddPostsSheet = AddPostsSheet;

function CollectionMenuSheet({ cvis, onTogglePublic, onReorder, onShare, onClose }) {
  const { BottomSheet } = window.SpotureDesignSystem_f7ad96;
  const rows = [
    { icon: 'pencil', label: '이름·설명·아이콘 수정' },
    { icon: visMeta(cvis).icon, label: '공개 범위 · ' + visMeta(cvis).label, sub: visCapped(accountVis(), cvis) ? '계정 설정 때문에 지금은 ' + visMeta(effVis(accountVis(), cvis)).label : null, act: onTogglePublic },
    { icon: 'arrows-sort', label: '게시물 순서 변경', act: onReorder },
    { icon: 'share', label: '컬렉션 공유', act: onShare },
    { icon: 'trash', label: '컬렉션 삭제', danger: true }
  ];
  return (
    <BottomSheet title="컬렉션 관리" onClose={onClose}>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
        {rows.map(r => (
          <div key={r.label} onClick={() => { r.act && r.act(); onClose(); }} style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '16px 18px', background: 'var(--surface-2)', borderRadius: 'var(--radius-tile)', cursor: 'pointer' }}>
            <i className={'ti ti-' + r.icon} style={{ fontSize: 19, color: r.danger ? 'var(--text-danger)' : 'var(--text-primary)', flexShrink: 0 }}></i>
            <div style={{ flex: 1, minWidth: 0 }}>
              <span style={{ font: 'var(--text-body)', color: r.danger ? 'var(--text-danger)' : 'var(--text-primary)', display: 'block' }}>{r.label}</span>
              {r.sub && <span style={{ font: 'var(--text-micro)', color: 'var(--text-warning)' }}>{r.sub}</span>}
            </div>
          </div>
        ))}
      </div>
    </BottomSheet>
  );
}
window.CollectionMenuSheet = CollectionMenuSheet;

function MoveCollectionSheet({ count, onClose, onPick }) {
  const { BottomSheet, Button, Avatar } = window.SpotureDesignSystem_f7ad96;
  const [pick, setPick] = React.useState(null);
  const cols = [
    { name: '혼밥 가능', sub: '1인석 있는 곳', count: 8, icon: 'user' },
    { name: '데이트 코스', sub: '분위기 좋은 곳', count: 5, icon: 'heart' },
    { name: '야식 리스트', sub: '11시 이후 영업', count: 17, icon: 'moon-stars' },
    { name: '주말 브런치', sub: '늦게 열어도 되는 곳', count: 6, icon: 'coffee' }
  ];
  return (
    <BottomSheet title="다른 컬렉션으로 이동" footer={<Button variant="primary" disabled={!pick} onClick={() => onPick(pick)}>{pick ? '「' + pick + '」(으)로 옮기기' : '옮길 컬렉션을 골라주세요'}</Button>} onClose={onClose}>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
        <span style={{ font: 'var(--text-caption)', color: 'var(--text-secondary)', lineHeight: 1.6, marginBottom: 2 }}>선택한 게시물 {count}개가 이 컬렉션에서 빠지고 고른 컬렉션으로 옮겨져요.</span>
        {cols.map(c => {
          const on = pick === c.name;
          return (
            <div key={c.name} onClick={() => setPick(c.name)} style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '14px 16px', background: on ? 'var(--bg-accent)' : 'var(--surface-2)', border: '1.5px solid ' + (on ? 'var(--text-accent)' : 'transparent'), borderRadius: 'var(--radius-tile)', cursor: 'pointer' }}>
              <div style={{ width: 40, height: 40, borderRadius: 12, background: 'var(--surface-1)', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}><i className={'ti ti-' + c.icon} style={{ fontSize: 18, color: on ? 'var(--text-accent)' : 'var(--text-secondary)' }}></i></div>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ font: 'var(--text-body-strong)', color: on ? 'var(--text-accent)' : 'var(--text-primary)', marginBottom: 2, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{c.name}</div>
                <div style={{ font: 'var(--text-micro)', color: 'var(--text-muted)', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{c.sub} · {c.count}곳</div>
              </div>
              <span style={{ width: 18, height: 18, borderRadius: '50%', border: '2px solid ' + (on ? 'var(--text-accent)' : 'var(--border-strong)'), background: on ? 'var(--text-accent)' : 'transparent', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>{on && <span style={{ width: 6, height: 6, borderRadius: '50%', background: '#fff' }}></span>}</span>
            </div>
          );
        })}
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8, border: '1.5px dashed var(--border-strong)', borderRadius: 'var(--radius-tile)', padding: '15px 0', cursor: 'pointer', marginTop: 2 }}>
          <i className="ti ti-plus" style={{ fontSize: 16, color: 'var(--text-secondary)' }}></i>
          <span style={{ font: '600 14px/1 var(--font-family)', color: 'var(--text-secondary)' }}>새 컬렉션 만들어 옮기기</span>
        </div>
      </div>
    </BottomSheet>
  );
}
window.MoveCollectionSheet = MoveCollectionSheet;

function CollectionDetail({ nav, other }) {
  const { Avatar } = window.SpotureDesignSystem_f7ad96;
  const { Button } = window.SpotureDesignSystem_f7ad96;
  const params = new URLSearchParams(location.search);
  const empty = params.get('cdempty') === '1';
  const [view, setView] = React.useState(params.get('cdview') === 'map' ? 'map' : 'grid');
  const [edit, setEdit] = React.useState(false);
  const [sel, setSel] = React.useState([]);
  const [menuPost, setMenuPost] = React.useState(null);
  const [menu, setMenu] = React.useState(false);
  const [add, setAdd] = React.useState(false);
  const [cToast, setCToast] = React.useState(null);
  const [moveOpen, setMoveOpen] = React.useState(false);
  const [shareOpen, setShareOpen] = React.useState(params.get('cshare') === '1');
  React.useEffect(() => { if (!cToast) return; const t = setTimeout(() => setCToast(null), 2200); return () => clearTimeout(t); }, [cToast]);
  const [cvis, setCvis] = React.useState(params.get('cvis') || 'public');
  const [cvisOpen, setCvisOpen] = React.useState(params.get('cvisopen') === '1');
  const cAcc = accountVis();
  const cEff = effVis(cAcc, cvis);
  const [open, setOpen] = React.useState(null);
  const [sort, setSort] = React.useState(params.get('cdsort') === '1');
  const [ord, setOrd] = React.useState([0, 1, 2, 3, 4]);
  const [saved, setSaved] = React.useState(false);
  const [following, setFollowing] = React.useState(false);
  const move = (pos, d) => setOrd(o => { const n = o.slice(), t = pos + d; if (t < 0 || t >= n.length) return o; const tmp = n[pos]; n[pos] = n[t]; n[t] = tmp; return n; });
  const items = empty ? [] : [
    { menu: '순대국', place: '할매순대국 강남점', mediaCount: 4, likes: 128, comments: 24, time: '2시간 전', x: '30%', y: '34%' },
    { menu: '내장탕', place: '역삼동 국밥집', mediaCount: 2, likes: 76, comments: 8, time: '어제', x: '62%', y: '26%' },
    { menu: '뼈해장국', place: '역삼 해장촌', mediaCount: 3, likes: 54, comments: 6, time: '4일 전', x: '46%', y: '55%' },
    { menu: '수육', place: null, mediaCount: 3, likes: 41, comments: 5, time: '1주 전', reportCount: 2, x: '72%', y: '68%' },
    { menu: '설렁탕', place: '이문설농탕 역삼', mediaCount: 1, likes: 33, comments: 2, time: '2주 전', x: '20%', y: '74%' }
  ];
  const places = items.filter(i => i.place).length;
  const toggle = i => setSel(p => p.includes(i) ? p.filter(x => x !== i) : [...p, i]);
  const exitEdit = () => { setEdit(false); setSel([]); };
  return (
    <div style={{ flex: '1 1 0%', minHeight: 0, display: 'flex', flexDirection: 'column', position: 'relative' }}>
      <StatusBar />
      <ScreenHeader title={sort ? '순서 변경' : edit ? (sel.length ? sel.length + '개 선택' : '게시물 선택') : '역삼 국밥 지도'} sub={other ? '@국밥러버92 · 공개 컬렉션' : sort ? '위·아래로 움직여 새 순서를 만들어주세요' : edit ? '컬렉션에서 뺄 게시물을 골라주세요' : null} onBack={sort ? () => setSort(false) : edit ? exitEdit : () => nav(other ? 'feed' : 'profile')}
        right={other
          ? <div onClick={() => setShareOpen(true)} style={{ width: 42, height: 42, borderRadius: '50%', background: 'var(--surface-1)', display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer', boxShadow: 'var(--shadow-card)', flexShrink: 0 }}><i className="ti ti-share" style={{ fontSize: 18 }}></i></div>
          : sort
          ? <span onClick={() => setSort(false)} style={{ font: '600 14px/1 var(--font-family)', color: 'var(--text-accent)', cursor: 'pointer', flexShrink: 0 }}>완료</span>
          : edit
          ? <span onClick={exitEdit} style={{ font: '600 14px/1 var(--font-family)', color: 'var(--text-secondary)', cursor: 'pointer', flexShrink: 0 }}>취소</span>
          : <div onClick={() => setMenu(true)} style={{ width: 42, height: 42, borderRadius: '50%', background: 'var(--surface-1)', display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer', boxShadow: 'var(--shadow-card)', flexShrink: 0 }}><i className="ti ti-dots" style={{ fontSize: 19 }}></i></div>} />
      <div style={{ flex: '1 1 0%', minHeight: 0, overflowY: 'auto', paddingBottom: edit ? 108 : 104 }}>
        {!edit && !sort && (
          <div style={{ padding: '0 20px 16px' }}>
            <div style={{ background: 'var(--surface-1)', borderRadius: 'var(--radius-card)', padding: 18, boxShadow: 'var(--shadow-card)' }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 14 }}>
                <div style={{ width: 46, height: 46, borderRadius: 14, background: 'var(--bg-accent)', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}><i className="ti ti-soup" style={{ fontSize: 22, color: 'var(--text-accent)' }}></i></div>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <span style={{ font: 'var(--text-body-strong)', display: 'block', marginBottom: 3 }}>해장 성공한 곳만</span>
                  <span style={{ font: 'var(--text-small)', color: 'var(--text-secondary)' }}>게시물 {items.length}개 · 장소 {places}곳</span>
                </div>
                {other ? <span style={{ flexShrink: 0, display: 'inline-flex', alignItems: 'center', gap: 4, font: 'var(--text-micro)', color: 'var(--text-accent)', background: 'var(--bg-accent)', borderRadius: 999, padding: '6px 10px' }}><i className="ti ti-world" style={{ fontSize: 11 }}></i>공개 컬렉션</span> : <VisibilityChip v={cEff} size="sm" />}
              </div>
              {!other && visCapped(cAcc, cvis) && <div style={{ marginBottom: 14 }}><VisibilityNotice account={cAcc} item={cvis} word="컬렉션" onOpenSettings={() => nav('settings')} /></div>}
              {other && (
                <div style={{ display: 'flex', alignItems: 'center', gap: 10, background: 'var(--surface-2)', borderRadius: 'var(--radius-tile)', padding: 12, marginBottom: 14 }}>
                  <Avatar user="국밥러버92" size={38} />
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <span style={{ font: 'var(--text-body-strong)', display: 'block', marginBottom: 2 }}>@국밥러버92</span>
                    <span style={{ font: 'var(--text-small)', color: 'var(--text-secondary)' }}>국밥전문가 배지 · 이 동네 84게시물</span>
                  </div>
                  <span onClick={() => setFollowing(!following)} style={{ flexShrink: 0, font: '600 13px/1 var(--font-family)', color: following ? 'var(--text-secondary)' : '#fff', background: following ? 'var(--surface-1)' : 'var(--text-accent)', border: following ? '1px solid var(--border-strong)' : 'none', borderRadius: 999, padding: '10px 14px', cursor: 'pointer' }}>{following ? '팔로잉' : '팔로우'}</span>
                </div>
              )}
              <div style={{ display: 'flex', gap: 8 }}>
                {other
                  ? <button onClick={() => setSaved(!saved)} style={{ flex: 1, padding: '12px 0', font: '600 14px/1 var(--font-family)', border: saved ? '1px solid var(--border-strong)' : 'none', background: saved ? 'var(--surface-1)' : 'var(--bg-ink)', color: saved ? 'var(--text-primary)' : '#fff', borderRadius: 999, cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 6 }}><i className={saved ? 'ti ti-bookmarks' : 'ti ti-bookmark'} style={{ fontSize: 15 }}></i>{saved ? '저장됨' : '이 컬렉션 저장'}</button>
                  : <button onClick={() => setAdd(true)} style={{ flex: 1, padding: '12px 0', font: '600 14px/1 var(--font-family)', border: 'none', background: 'var(--bg-ink)', color: '#fff', borderRadius: 999, cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 6 }}><i className="ti ti-plus" style={{ fontSize: 15 }}></i>게시물 담기</button>}
                <button onClick={() => setShareOpen(true)} style={{ flex: 1, padding: '12px 0', font: '600 14px/1 var(--font-family)', border: '1px solid var(--border-strong)', background: 'var(--surface-1)', color: 'var(--text-primary)', borderRadius: 999, cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 6 }}><i className="ti ti-share" style={{ fontSize: 15 }}></i>공유</button>
              </div>
            </div>
          </div>
        )}
        {sort ? (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 8, padding: '0 20px' }}>
            {ord.map((idx, pos) => {
              const p = items[idx];
              return (
                <div key={idx} style={{ display: 'flex', alignItems: 'center', gap: 12, background: 'var(--surface-1)', borderRadius: 'var(--radius-tile)', padding: 12, boxShadow: 'var(--shadow-card)' }}>
                  <i className="ti ti-grip-vertical" style={{ fontSize: 18, color: 'var(--text-muted)', flexShrink: 0 }}></i>
                  <div style={{ width: 46, height: 46, borderRadius: 12, background: 'var(--surface-2)', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}><i className="ti ti-photo" style={{ fontSize: 18, color: 'var(--text-muted)' }}></i></div>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <span style={{ font: 'var(--text-body-strong)', display: 'block', marginBottom: 3, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>#{p.menu}</span>
                    <span style={{ font: 'var(--text-small)', color: p.place ? 'var(--text-secondary)' : 'var(--text-warning)' }}>{p.place || '장소 미지정'}</span>
                  </div>
                  <div style={{ display: 'flex', gap: 6, flexShrink: 0 }}>
                    {[['chevron-up', -1, pos === 0], ['chevron-down', 1, pos === ord.length - 1]].map(([ic, d, off]) => (
                      <div key={ic} onClick={() => !off && move(pos, d)} style={{ width: 38, height: 38, borderRadius: '50%', background: off ? 'var(--surface-2)' : 'var(--surface-1)', border: '1px solid ' + (off ? 'transparent' : 'var(--border-strong)'), display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: off ? 'default' : 'pointer' }}>
                        <i className={'ti ti-' + ic} style={{ fontSize: 17, color: off ? 'var(--text-muted)' : 'var(--text-primary)' }}></i>
                      </div>
                    ))}
                  </div>
                </div>
              );
            })}
            <span style={{ font: 'var(--text-micro)', color: 'var(--text-muted)', textAlign: 'center', marginTop: 4 }}>바꾼 순서는 컬렉션 공개 화면에도 그대로 보여요</span>
          </div>
        ) : items.length === 0 ? (
          <div style={{ textAlign: 'center', padding: '34px 32px' }}>
            <div style={{ width: 62, height: 62, borderRadius: '50%', background: 'var(--surface-1)', display: 'flex', alignItems: 'center', justifyContent: 'center', margin: '0 auto 16px', boxShadow: 'var(--shadow-card)' }}><i className="ti ti-photo-off" style={{ fontSize: 26, color: 'var(--text-muted)' }}></i></div>
            <span style={{ font: 'var(--text-body-strong)', display: 'block', marginBottom: 6 }}>아직 담은 게시물이 없어요</span>
            <p style={{ font: 'var(--text-caption)', color: 'var(--text-secondary)', margin: '0 0 18px', lineHeight: 1.6 }}>내 게시물을 담으면 이 컬렉션이<br />하나의 지도로 완성돼요.</p>
            <div><Button variant="primary" size="sm" onClick={() => setAdd(true)}><i className="ti ti-plus" style={{ fontSize: 15 }}></i>게시물 담기</Button></div>
          </div>
        ) : (
          <React.Fragment>
            <div style={{ padding: '0 20px 14px', display: edit ? 'none' : 'flex', alignItems: 'center', gap: 10 }}>
              <div style={{ flex: 1, display: 'flex', background: 'var(--surface-2)', borderRadius: 999, padding: 4 }}>
                {['격자', '지도'].map(t => {
                  const key = t === '격자' ? 'grid' : 'map';
                  const on = view === key;
                  return <span key={t} onClick={() => setView(key)} style={{ flex: 1, textAlign: 'center', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 5, font: on ? '600 13px/1 var(--font-family)' : '400 13px/1 var(--font-family)', color: on ? '#fff' : 'var(--text-secondary)', background: on ? 'var(--bg-ink)' : 'transparent', borderRadius: 999, padding: '11px 0', cursor: 'pointer', transition: 'all .16s ease' }}><i className={'ti ti-' + (key === 'grid' ? 'layout-grid' : 'map-2')} style={{ fontSize: 14 }}></i>{t}</span>;
                })}
              </div>
              {!edit && !other && <span onClick={() => { setView('grid'); setEdit(true); }} style={{ flexShrink: 0, font: '600 13px/1 var(--font-family)', color: 'var(--text-secondary)', border: '1px solid var(--border-strong)', borderRadius: 999, padding: '11px 14px', cursor: 'pointer' }}>편집</span>}
            </div>
            {view === 'grid' ? (
              <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2,1fr)', gridAutoRows: 'min-content', gap: 10, padding: '0 20px' }}>
                {items.map((p, i) => {
                  const on = sel.includes(i);
                  return (
                    <div key={i} onClick={() => edit ? toggle(i) : setOpen({ ...p, user: '국밥러버92', imageId: 'cd-' + i })} style={{ background: 'var(--surface-1)', borderRadius: 'var(--radius-card)', overflow: 'hidden', boxShadow: 'var(--shadow-card)', cursor: 'pointer', border: '2px solid ' + (edit && on ? 'var(--text-accent)' : 'transparent'), boxSizing: 'border-box' }}>
                      <div style={{ width: '100%', aspectRatio: '1', background: 'var(--surface-2)', position: 'relative', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                        <i className="ti ti-photo" style={{ fontSize: 24, color: 'var(--text-muted)' }}></i>
                        {p.mediaCount > 1 && !edit && <span style={{ position: 'absolute', right: 8, top: 8, font: 'var(--text-micro)', color: '#fff', background: 'rgba(26,26,26,.68)', borderRadius: 999, padding: '4px 8px' }}>1/{p.mediaCount}</span>}
                        <span style={{ position: 'absolute', left: 8, bottom: 8, font: 'var(--text-micro)', color: '#fff', background: 'rgba(26,26,26,.68)', borderRadius: 999, padding: '4px 8px' }}>#{p.menu}</span>
                        {edit && <div style={{ position: 'absolute', right: 8, top: 8, width: 22, height: 22, borderRadius: '50%', background: on ? 'var(--text-accent)' : 'rgba(255,255,255,.85)', border: on ? 'none' : '1.5px solid var(--border-strong)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>{on && <i className="ti ti-check" style={{ fontSize: 13, color: '#fff' }}></i>}</div>}
                        {p.reportCount && !edit && <span style={{ position: 'absolute', left: 8, top: 8, font: '600 11px/1 var(--font-family)', color: '#fff', background: 'var(--text-warning)', borderRadius: 999, padding: '5px 8px', display: 'inline-flex', alignItems: 'center', gap: 3 }}><i className="ti ti-map-pin-question" style={{ fontSize: 10 }}></i>제보 {p.reportCount}</span>}
                      </div>
                      <div style={{ padding: '11px 12px 13px' }}>
                        <div style={{ display: 'flex', alignItems: 'center', gap: 4, marginBottom: 6 }}>
                          <i className={p.place ? 'ti ti-map-pin' : 'ti ti-map-pin-question'} style={{ fontSize: 11, color: p.place ? 'var(--text-secondary)' : 'var(--text-warning)', flexShrink: 0 }}></i>
                          <span style={{ font: 'var(--text-small)', color: p.place ? 'var(--text-primary)' : 'var(--text-warning)', fontWeight: 600, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{p.place || '장소 미지정'}</span>
                        </div>
                        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                          <span style={{ font: 'var(--text-micro)', color: 'var(--text-muted)', display: 'inline-flex', alignItems: 'center', gap: 3 }}><i className="ti ti-heart" style={{ fontSize: 10 }}></i>{p.likes}</span>
                          <span style={{ font: 'var(--text-micro)', color: 'var(--text-muted)', display: 'inline-flex', alignItems: 'center', gap: 3 }}><i className="ti ti-message-circle" style={{ fontSize: 10 }}></i>{p.comments}</span>
                          <span style={{ font: 'var(--text-micro)', color: 'var(--text-muted)', marginLeft: 'auto' }}>{p.time}</span>
                        </div>
                      </div>
                    </div>
                  );
                })}
              </div>
            ) : (
              <div style={{ padding: '0 20px' }}>
                <div style={{ height: 300, borderRadius: 'var(--radius-card)', background: 'var(--surface-2)', position: 'relative', overflow: 'hidden' }}>
                  {items.filter(p => p.place).map((p, i) => (
                    <div key={i} onClick={() => setOpen({ ...p, user: '국밥러버92', imageId: 'cdm-' + i })} style={{ position: 'absolute', left: p.x, top: p.y, transform: 'translate(-50%,-100%)', display: 'flex', flexDirection: 'column', alignItems: 'center', cursor: 'pointer' }}>
                      <span style={{ width: 34, height: 34, borderRadius: '50%', background: 'var(--text-accent)', border: '2px solid #fff', display: 'flex', alignItems: 'center', justifyContent: 'center', boxShadow: 'var(--shadow-float)' }}><i className="ti ti-soup" style={{ fontSize: 17, color: '#fff' }}></i></span>
                      <span style={{ font: 'var(--text-micro)', color: 'var(--text-primary)', background: 'var(--surface-1)', borderRadius: 999, padding: '4px 9px', marginTop: 3, whiteSpace: 'nowrap', boxShadow: 'var(--shadow-card)' }}>{p.place.split(' ')[0]}</span>
                    </div>
                  ))}
                  <span style={{ position: 'absolute', left: 14, top: 14, font: 'var(--text-micro)', color: '#fff', background: 'rgba(26,26,26,.7)', borderRadius: 999, padding: '8px 12px' }}>강남구 역삼동 일대 · 핀 {places}개</span>
                </div>
                <p style={{ font: 'var(--text-small)', color: 'var(--text-muted)', textAlign: 'center', margin: '10px 0 0' }}>장소 미지정 게시물 {items.length - places}개는 지도에 표시되지 않아요</p>
              </div>
            )}
          </React.Fragment>
        )}
      </div>
      {edit && (
        <div style={{ position: 'absolute', left: 0, right: 0, bottom: 0, zIndex: 25, background: 'var(--surface-1)', borderTop: '1px solid var(--border)', padding: '12px 20px 20px', display: 'flex', gap: 8, boxShadow: 'var(--shadow-float)' }}>
          <button onClick={() => sel.length && setMoveOpen(true)} disabled={!sel.length} style={{ flex: 1, padding: '14px 0', font: '600 14px/1 var(--font-family)', border: '1px solid var(--border-strong)', background: 'var(--surface-1)', color: sel.length ? 'var(--text-primary)' : 'var(--text-muted)', borderRadius: 999, cursor: sel.length ? 'pointer' : 'default' }}>다른 컬렉션으로 이동</button>
          <button onClick={() => { const c = sel.length; if (!c) return; exitEdit(); setCToast('게시물 ' + c + '개를 컬렉션에서 뺐어요'); }} disabled={!sel.length} style={{ flex: 1, padding: '14px 0', font: '600 14px/1 var(--font-family)', border: 'none', background: sel.length ? 'var(--text-accent)' : 'var(--surface-2)', color: sel.length ? '#fff' : 'var(--text-muted)', borderRadius: 999, cursor: sel.length ? 'pointer' : 'default' }}>컬렉션에서 빼기</button>
        </div>
      )}
      {open && <PostViewer post={open} onClose={() => setOpen(null)} onComments={() => setOpen(null)} onMenu={() => { setMenuPost(open); setOpen(null); }} onPlace={() => { setOpen(null); nav('restaurantDetail'); }} />}
      {menuPost && <PostActionSheets post={menuPost} onClose={() => setMenuPost(null)} onDeleted={() => setMenuPost(null)} onEdit={(pp) => nav('editPost', { post: pp })} />}
      {menu && <CollectionMenuSheet cvis={cvis} onTogglePublic={() => { setMenu(false); setCvisOpen(true); }} onReorder={() => setSort(true)} onShare={() => setShareOpen(true)} onClose={() => setMenu(false)} />}
      {shareOpen && <ShareCollectionSheet name="역삼 국밥 지도" owner={other ? '국밥러버92' : '국밥러버'} count={items.length} places={places} onClose={() => setShareOpen(false)} />}
      {cvisOpen && <VisibilitySheet current={cvis} account={cAcc} word="컬렉션" title="컬렉션 공개 범위" onClose={() => setCvisOpen(false)} onPick={(v) => { setCvis(v); setCvisOpen(false); setCToast('공개 범위를 ' + visMeta(effVis(cAcc, v)).label + '로 바꿨어요'); }} />}
      {moveOpen && <MoveCollectionSheet count={sel.length} onClose={() => setMoveOpen(false)} onPick={(nm) => { const c = sel.length; setMoveOpen(false); exitEdit(); setCToast('게시물 ' + c + '개를 「' + nm + '」(으)로 옮겼어요'); }} />}
      {add && <AddPostsSheet onClose={() => setAdd(false)} onDone={(cnt) => { setAdd(false); setCToast('게시물 ' + cnt + '개를 컬렉션에 담았어요'); }} />}
      {cToast && (
        <div style={{ position: 'absolute', left: 20, right: 20, bottom: 92, background: 'var(--bg-ink)', color: '#fff', borderRadius: 'var(--radius-tile)', padding: '14px 16px', display: 'flex', alignItems: 'center', gap: 10, boxShadow: 'var(--shadow-float)', zIndex: 60 }}>
          <i className="ti ti-circle-check" style={{ fontSize: 18, flexShrink: 0 }}></i>
          <span style={{ font: '600 14px/1.4 var(--font-family)' }}>{cToast}</span>
        </div>
      )}
    </div>
  );
}
window.CollectionDetail = CollectionDetail;
