function Profile({ nav }) {
  const { Badge, RestaurantCard } = window.SpotureDesignSystem_f7ad96;
  const pp = new URLSearchParams(location.search);
  const [tab, setTab] = React.useState({ collections: '컬렉션', saved: '찜', challenges: '챌린지', badges: '배지' }[pp.get('ptab')] || '게시물');
  const [menuPost, setMenuPost] = React.useState(null);
  const [unsaved, setUnsaved] = React.useState({});
  const [askUnsave, setAskUnsave] = React.useState(pp.get('punsave') === '1' ? '할매순대국 강남점' : null);
  const savedPlaces = [
    { name: '할매순대국 강남점', category: '한식', distance: '45m', photos: 128, likes: 642 },
    { name: '멘야하나비 역삼', category: '일식', distance: '90m', photos: 46, likes: 214 },
    { name: '청년다방 역삼점', category: '분식', distance: '80m' },
    { name: '로스트림 로스터스', category: '카페', distance: '210m', photos: 31, likes: 88 },
    { name: '이치란 시부야점', category: '라멘', distance: '도쿄 시부야', photos: 12, likes: 57 },
    { name: '을밀대 역삼', category: '한식', distance: '320m', photos: 8, likes: 24 }
  ];
  const [mySheet, setMySheet] = React.useState(pp.get('psheet') ? { type: pp.get('psheet'), idx: 0, post: { menu: '순대국', place: '할매순대국 강남점', mediaCount: 4, likes: 128, comments: 24, time: '2시간 전' } } : null);
  const [pfHidden, setPfHidden] = React.useState({});
  const [pfGone, setPfGone] = React.useState({});
  const [sheet, setSheet] = React.useState(false);
  const [colSheet, setColSheet] = React.useState(pp.get('csheet') === '1');
  const [shareSheet, setShareSheet] = React.useState(!!pp.get('share'));
  const [pToast, setPToast] = React.useState(null);
  React.useEffect(() => { if (!pToast) return; const t = setTimeout(() => setPToast(null), 2200); return () => clearTimeout(t); }, [pToast]);
  const badges = [{ icon: 'soup', label: '국밥전문가' }, { icon: 'moon-stars', label: '야식탐험가' }, { icon: 'flame', label: '올해의 기록가' }, { icon: 'soup', label: '이달의 국밥왕' }, { icon: 'map-pin-check', label: '위치제보왕' }, { icon: 'bowl-chopsticks', label: '분식마스터' }, { icon: 'coffee', label: '카페인탐정' }, { icon: 'building-store', label: '동네박사' }];
  const [open, setOpen] = React.useState(null);
  const [badgeOpen, setBadgeOpen] = React.useState(pp.get('bdg') ? (window.BADGE_CATALOG || []).find(b => b.n === pp.get('bdg')) || null : null);
  const noBadges = pp.get('nobadge') === '1';
  const ownedBadges = noBadges ? [] : (window.BADGE_CATALOG || []).filter(b => b.got);
  const [featured, setFeatured] = React.useState(() => pp.get('feat') === 'none' ? null : (ownedBadges.find(b => b.n === (pp.get('feat') || '동네 지킴이')) || ownedBadges[0] || null));
  const [pickBadge, setPickBadge] = React.useState(pp.get('pickbadge') === '1');
  const collections = [
    { name: '역삼 국밥 지도', count: 12, sub: '해장 성공한 곳만', icon: 'soup' },
    { name: '혼밥 가능', count: 8, sub: '1인석 있는 곳', icon: 'user' },
    { name: '데이트 코스', count: 5, sub: '분위기 좋은 곳', icon: 'heart' },
    { name: '야식 리스트', count: 17, sub: '11시 이후 영업', icon: 'moon-stars' }
  ];
  const savedCollections = [
    { name: '늦게까지 하는 카페', owner: '카페인탐정', count: 15, places: 12, icon: 'coffee' },
    { name: '역삼 점심 로테이션', owner: '역삼동토박이', count: 22, places: 18, icon: 'building-store' }
  ];
  const [cFilter, setCFilter] = React.useState('진행 중');
  const [openRank, setOpenRank] = React.useState('8월 국밥 랭킹');
  const RANKINGS = [
    { key: '8월 국밥 랭킹', name: '8월 국밥 랭킹', icon: 'trophy', badge: '이달의 국밥왕', badgeIcon: 'soup', badgeColor: '#E8A33D',
      period: '1개월', reset: '1개월마다 초기화 · 마포구', cycle: '8월 1일 ~ 8월 31일', ends: '9/1 확정', top: 10, min: '3곳 이상', hold: '다음 집계까지만 보유', unit: '곳', total: 1840,
      me: { rank: 2, value: 13, handle: 'gukbap_lover92' },
      prev: { label: '7월', rank: 9, value: 5, awarded: true, held: false, note: '8월 순위 확정 시 재집계돼요' },
      board: [[1, '미도리', 'midori_eats', 14, '#E31E24'], [2, '국밥러버', 'gukbap_lover92', 13, '#1A1A1A'], [3, '태윤', 'taeyun', 11, '#E8A33D'], [4, '도현', 'dohyun.gk', 10, '#2C5282'], [5, '수아', 'sua_9', 9, '#1B8F5A']] },
    { key: '3분기 카페 탐험 랭킹', name: '3분기 카페 탐험 랭킹', icon: 'coffee', badge: '카페 챔피언', badgeIcon: 'coffee', badgeColor: '#8A5A2B',
      period: '분기', reset: '분기마다 초기화 · 전국', cycle: '7월 1일 ~ 9월 30일', ends: '10/1 확정', top: 3, min: '10곳 이상', hold: '영구 보유', unit: '곳', total: 624,
      me: { rank: 8, value: 11 },
      prev: { label: '2분기', rank: 6, value: 9, awarded: false, note: '상위 3명 밖이라 수여되지 않았어요' },
      board: [[1, '시우', 'siwoo.kim', 31, '#B83280'], [2, '다은', 'daeun_pl', 28, '#3182CE'], [3, '하늘', 'haneul_c', 24, '#805AD5', '공동 3위'], [3, '예린', 'yerin.k', 24, '#DD6B20', '공동 3위'], [5, '수아', 'sua_9', 19, '#1B8F5A']] },
    { key: '2026 연간 기록 랭킹', name: '2026 연간 기록 랭킹', icon: 'calendar-event', badge: '올해의 기록가', badgeIcon: 'flame', badgeColor: '#E0563B',
      period: '1년', reset: '1년마다 초기화 · 전국', cycle: '1월 1일 ~ 12월 31일', ends: '1/1 확정', top: 100, min: '50개 이상', hold: '영구 보유', unit: '개', total: 8420,
      me: { rank: 41, value: 268 },
      prev: { label: '2025년', rank: 78, value: 402, awarded: true, held: true, note: '영구 보유 배지예요' },
      board: [[1, '미도리', 'midori_eats', 612, '#1B8F5A'], [2, '태윤', 'taeyun', 574, '#E8A33D'], [3, '국밥마니아', 'gukbap_mania', 559, '#E31E24'], [4, '수아', 'sua_9', 498, '#8A5CD9'], [5, '연남토박이', 'ynn_local', 470, '#3B6FD9']] },
  ];
  const endedChallenges = [
    { name: '새벽 국밥 인증 챌린지', now: 3, goal: 3, period: '2026-07-01 ~ 2026-07-31', icon: 'soup', achieved: true,
      reward: '국밥교환권 (100명 추첨)', lottery: true, prizeCount: 100, drawDate: '2026-07-28',
      won: true, rewardState: '당첨', rank: 42, joinedCount: 742, doneCount: 486, percentile: 6,
      note: '7/28 발표 · 스폰서가 개별 안내드렸어요',
      winners: [['미도리', 'midori_eats'], ['국밥러버', 'gukbap_lover92'], ['수아', 'sua_9'], ['도윤', 'doyun'], ['예린', 'yerin.k'], ['민서', 'minseo.eat'], ['준호', 'junho_88'], ['채원', 'chaewon.s']] },
    { name: '분식 3종 도장깨기', now: 3, goal: 3, period: '2026-06-10 ~ 2026-06-30', icon: 'bowl', achieved: true,
      reward: '5,000원 쿠폰', lottery: true, prizeCount: 300, drawDate: '2026-07-03',
      won: false, rewardState: '미당첨', rank: 210, joinedCount: 1180, doneCount: 604, percentile: 18,
      note: '완주했지만 추첨에서 아쉽게 떨어졌어요',
      winners: [['하윤', 'hayoon_b'], ['도현', 'dohyun.j'], ['가은', 'gaeun_k'], ['서준', 'seojun_gk'], ['소민', 'somin.eats'], ['태윤', 'taeyun'], ['지안', 'jian_00'], ['현우', 'hyunwoo.p']] },
    { name: '을지로 노포 도장깨기', now: 2, goal: 4, period: '2026-05-02 ~ 2026-05-31', icon: 'building-store', achieved: false,
      reward: '노포 수집가 배지', lottery: false, won: false, rewardState: '미달성', rank: null, joinedCount: 892, doneCount: 341, percentile: null,
      note: '2곳만 더 채웠다면 완주였어요' },
  ];
  const challenges = [
    { name: '국밥 10곳 원정대', now: 7, goal: 10, left: '12일 남음', reward: '국밥전문가 배지', icon: 'soup', joined: true },
    { name: '이 동네 20곳 채우기', now: 14, goal: 20, left: '이달 말까지', reward: '동네박사 배지', icon: 'building-store', joined: true },
    { name: '위치 제보 30건', now: 30, goal: 30, left: '완료', reward: '위치제보왕 배지', icon: 'map-pin-check', done: true },
    { name: '이달의 밀키트 인증샷', now: 0, goal: 3, left: '6일 남음', reward: '이벤트 응모권', icon: 'gift' },
    { name: '라멘 7종 도장깨기', now: 4, goal: 7, left: '20일 남음', reward: '라멘러버 배지', icon: 'bowl-chopsticks', joined: true },
    { name: '카페 15곳 순례', now: 9, goal: 15, left: '이달 말까지', reward: '카페인탐정 배지', icon: 'coffee', joined: true },
    { name: '분식 10곳 정복', now: 10, goal: 10, left: '완료', reward: '분식마스터 배지', icon: 'bowl', done: true },
    { name: '야식 자정 인증 5회', now: 3, goal: 5, left: '9일 남음', reward: '야식탐험가 배지', icon: 'moon-stars', joined: true },
    { name: '아침 7시 조식 3회', now: 0, goal: 3, left: '14일 남음', reward: '아침형탐험가 배지', icon: 'sunrise' },
    { name: '이웃 위치 제보 도와주기 10건', now: 6, goal: 10, left: '이달 말까지', reward: '동네해결사 배지', icon: 'map-pin-check', joined: true },
    { name: '내 사진에 장소 확정 15건', now: 11, goal: 15, left: '상시', reward: '기록정리왕 배지', icon: 'pin', joined: true },
    { name: '새 가게 첫 등록 3곳', now: 1, goal: 3, left: '25일 남음', reward: '개척자 배지', icon: 'flag' },
    { name: '동영상 후기 5개', now: 2, goal: 5, left: '18일 남음', reward: '영상기록가 배지', icon: 'video', joined: true },
    { name: '한 가게 재방문 3회', now: 2, goal: 3, left: '상시', reward: '단골 배지', icon: 'repeat', joined: true },
    { name: '컬렉션 3개 완성', now: 3, goal: 3, left: '완료', reward: '큐레이터 배지', icon: 'folder', done: true },
    { name: '내 컬렉션 50명 저장', now: 34, goal: 50, left: '상시', reward: '인기큐레이터 배지', icon: 'bookmark' },
    { name: '댓글로 맛집 추천 20회', now: 13, goal: 20, left: '이달 말까지', reward: '수다쟁이 배지', icon: 'message-circle', joined: true },
    { name: '이웃 5명 팔로우', now: 5, goal: 5, left: '완료', reward: '이웃사촌 배지', icon: 'users', done: true },
    { name: '옆 동네 원정 5곳', now: 2, goal: 5, left: '30일 남음', reward: '원정대 배지', icon: 'compass', joined: true },
    { name: '지하철 3개 역 커버', now: 2, goal: 3, left: '상시', reward: '역세권탐험가 배지', icon: 'train' },
    { name: '비 오는 날 국물 3곳', now: 1, goal: 3, left: '장마철 한정', reward: '국물사냥꾼 배지', icon: 'umbrella', joined: true },
    { name: '혼밥 인증 7회', now: 5, goal: 7, left: '이달 말까지', reward: '혼밥고수 배지', icon: 'user', joined: true },
    { name: '가을 제철 메뉴 4종', now: 0, goal: 4, left: '9월 시작', reward: '제철미식가 배지', icon: 'leaf' },
    { name: '연속 7일 기록', now: 4, goal: 7, left: '진행 중', reward: '꾸준왕 배지', icon: 'flame', joined: true }
  ];
  const posts = [
    { user: '국밥러버92', place: '금강산초다리 역삼점', city: '서울 강남구', area: '역삼동', menu: '갈치조림', caption: '갈치가 두툼하고 양념이 짜지 않다. 무가 국물을 다 먹었다.', mediaCount: 4, likes: 128, comments: 24, time: '2시간 전', src: '../../assets/feed/jorim-1.jpeg' },
    { user: '국밥러버92', menu: '스테이크 플래터', city: '서울 강남구', area: '역삼동', mission: true, missionStatus: 'review', mediaCount: 3, likes: 64, comments: 8, time: '5시간 전', src: '../../assets/feed/steak-platter.jpeg' },
    { user: '국밥러버92', place: '역삼 백반집', city: '서울 강남구', area: '역삼동', menu: '김치찌개', caption: '묵은지가 푹 익어서 국물이 달다. 점심에 줄 서는 이유가 있다.', mediaCount: 2, likes: 76, comments: 8, time: '어제', src: '../../assets/feed/kimchi-jjigae.jpeg' },
    { user: '국밥러버92', menu: '곱창구이', mediaCount: 3, likes: 41, comments: 5, time: '3일 전', reportCount: 2, src: '../../assets/feed/gopchang.jpeg' },
    { user: '국밥러버92', place: '우동하나 역삼', city: '서울 강남구', area: '역삼동', menu: '붓카케 우동', caption: '국물 없이 비벼 먹는 우동. 면이 굵고 탱탱하다.', mediaCount: 6, likes: 91, comments: 12, time: '5일 전', src: '../../assets/feed/udon.jpeg' },
    { user: '국밥러버92', menu: '묵은지찜', mediaCount: 5, likes: 63, comments: 9, time: '1주 전', reportCount: 1, src: '../../assets/feed/mukeunji-jjim.jpeg' },
    { user: '국밥러버92', place: '나무가나길 커피', city: '서울 강남구', area: '선릉역', menu: '핸드드립', caption: '밥 먹고 커피. 산미 적은 원두 추천받아 마셨다.', mediaCount: 1, likes: 44, comments: 3, time: '2주 전', src: '../../assets/feed/cafe-2.jpeg' }
  ];
  const [pArea, setPArea] = React.useState('전체');
  const pAreaCounts = posts.reduce((a, p) => { const k = p.area || '장소 미지정'; return { ...a, [k]: (a[k] || 0) + 1 }; }, {});
  const pAreaList = Object.keys(pAreaCounts).sort((a, b) => pAreaCounts[b] - pAreaCounts[a]);
  return (
    <div style={{ flex: '1 1 0%', minHeight: 0, display: 'flex', flexDirection: 'column', position: 'relative' }}>
      <StatusBar />
      <ScreenHeader title="프로필" right={<div onClick={() => nav('settings')} style={{ width: 42, height: 42, borderRadius: '50%', background: 'var(--surface-1)', display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer', boxShadow: 'var(--shadow-card)' }}><i className="ti ti-settings" style={{ fontSize: 19 }}></i></div>} />
      <div style={{ flex: '1 1 0%', minHeight: 0, overflowY: 'auto', paddingBottom: 104 }}>
        <div style={{ padding: '0 20px 18px' }}>
          <div style={{ background: 'var(--surface-1)', borderRadius: 'var(--radius-card)', padding: 20, boxShadow: 'var(--shadow-card)' }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 16, marginBottom: 18 }}>
              <div onClick={() => setSheet(true)} style={{ position: 'relative', cursor: 'pointer', flexShrink: 0 }}>
                <div style={{ width: 72, height: 72, borderRadius: '50%', overflow: 'hidden', background: 'var(--surface-2)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}><img src="../../assets/profile-me.jpeg" alt="프로필 사진" style={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block' }} /></div>
                {featured ? (
                  <div onClick={(e) => { e.stopPropagation(); setPickBadge(true); }} title="대표 배지 변경" style={{ position: 'absolute', right: -3, bottom: -3, width: 30, height: 30, borderRadius: '50%', background: (window.BADGE_SERIES[featured.s] || {}).color, border: '3px solid var(--surface-1)', display: 'flex', alignItems: 'center', justifyContent: 'center', boxShadow: 'var(--shadow-card)' }}><i className={'ti ti-' + featured.i} style={{ fontSize: 14, color: '#fff' }}></i></div>
                ) : (
                  <div onClick={(e) => { e.stopPropagation(); setPickBadge(true); }} title="아직 받은 배지가 없어요" style={{ position: 'absolute', right: -3, bottom: -3, width: 30, height: 30, borderRadius: '50%', background: 'var(--surface-1)', border: '3px solid var(--surface-1)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                    <div style={{ width: '100%', height: '100%', borderRadius: '50%', border: '1.5px dashed var(--border-strong)', background: 'var(--surface-2)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}><i className="ti ti-lock" style={{ fontSize: 12, color: 'var(--text-muted)' }}></i></div>
                  </div>
                )}
              </div>
              <div style={{ flex: 1, minWidth: 0 }}>
                <span style={{ font: 'var(--text-heading)', display: 'block', marginBottom: 4 }}>국밥러버92</span>
                <span style={{ font: 'var(--text-caption)', color: 'var(--text-secondary)' }}>@gukbap_lover92 · 역삼동</span>
              </div>
            </div>
            <p style={{ font: 'var(--text-caption)', color: 'var(--text-secondary)', lineHeight: 1.6, margin: '-6px 0 16px', textWrap: 'pretty' }}>국밥 한 그릇으로 하루를 시작하는 사람. 역삼·선릉 위주로 기록해요.</p>
            <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 16 }}>
              <div style={{ flexShrink: 0, padding: '2px 12px 2px 2px' }}>
                <span style={{ font: 'var(--text-heading)', display: 'block', lineHeight: 1.1 }}>84</span>
                <span style={{ font: 'var(--text-small)', color: 'var(--text-muted)' }}>게시물</span>
              </div>
              <div style={{ width: 1, height: 34, background: 'var(--border)', flexShrink: 0 }}></div>
              {[['312', '팔로워', 'follows'], ['128', '팔로잉', 'followsFollowing']].map(([n, l, route]) => (
                <div key={l} onClick={() => nav(route)} style={{ flex: 1, minWidth: 0, display: 'flex', alignItems: 'center', gap: 6, background: 'var(--surface-1)', border: '1px solid var(--border-strong)', borderRadius: 999, padding: '10px 12px', cursor: 'pointer' }}>
                  <span style={{ font: '700 15px/1 var(--font-family)', color: 'var(--text-primary)' }}>{n}</span>
                  <span style={{ font: 'var(--text-small)', color: 'var(--text-secondary)' }}>{l}</span>
                  <i className="ti ti-chevron-right" style={{ fontSize: 15, color: 'var(--text-muted)', marginLeft: 'auto', flexShrink: 0 }}></i>
                </div>
              ))}
            </div>
            <div style={{ display: 'flex', gap: 8 }}>
              <button onClick={() => nav('editProfile')} style={{ flex: 1, padding: '13px 0', font: '600 14px/1 var(--font-family)', border: 'none', background: 'var(--bg-ink)', color: '#fff', borderRadius: 999, cursor: 'pointer' }}>프로필 편집</button>
              <button onClick={() => setShareSheet(true)} style={{ flex: 1, padding: '13px 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' }}>공유</button>
            </div>
          </div>
        </div>
        <div style={{ display: 'flex', gap: 8, padding: '0 20px 16px', overflowX: 'auto' }}>
          {['게시물', '컬렉션', '찜', '챌린지', '배지'].map(t => (
            <span key={t} onClick={() => setTab(t)} style={{ font: tab === t ? '600 14px/1 var(--font-family)' : '400 14px/1 var(--font-family)', color: tab === t ? '#fff' : 'var(--text-primary)', background: tab === t ? 'var(--bg-ink)' : 'var(--surface-1)', borderRadius: 999, padding: '12px 18px', cursor: 'pointer', whiteSpace: 'nowrap' }}>{t}</span>
          ))}
        </div>
        {tab === '찜' ? (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 10, padding: '0 20px' }}>
            <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between' }}>
              <span style={{ font: 'var(--text-body-strong)' }}>찜한 가게</span>
              <span onClick={() => nav('savedPlaces')} style={{ font: 'var(--text-micro)', color: 'var(--text-accent)', cursor: 'pointer' }}>전체보기</span>
            </div>
            {savedPlaces.filter(s => !unsaved[s.name]).map((s, i) => (
              <div key={s.name} style={{ position: 'relative' }}>
                <RestaurantCard name={s.name} category={s.category} distance={s.distance} photos={s.photos} likes={s.likes} imageId={'pv-' + i} onClick={() => nav('restaurantDetail')} />
                <span onClick={(e) => { e.stopPropagation(); setAskUnsave(s.name); }} title="찜 해제" style={{ position: 'absolute', right: 58, top: '50%', transform: 'translateY(-50%)', width: 34, height: 34, borderRadius: '50%', background: 'var(--text-accent)', display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer' }}>
                  <i className="ti ti-bookmark" style={{ fontSize: 16, color: '#fff' }}></i>
                </span>
              </div>
            ))}
            {savedPlaces.filter(s => !unsaved[s.name]).length === 0 && (
              <div style={{ textAlign: 'center', padding: '44px 0 0' }}>
                <i className="ti ti-bookmark-off" style={{ fontSize: 30, color: 'var(--text-muted)' }}></i>
                <p style={{ font: 'var(--text-caption)', color: 'var(--text-secondary)', margin: '12px 0 0', lineHeight: 1.6 }}>찜한 가게가 없어요<br />가게 상세에서 북마크를 누르면 여기에 모여요</p>
              </div>
            )}
          </div>
        ) : tab === '컬렉션' ? (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 10, padding: '0 20px' }}>
            <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between' }}>
              <span style={{ font: 'var(--text-body-strong)' }}>내 컬렉션</span>
              <span style={{ font: 'var(--text-micro)', color: 'var(--text-muted)' }}>{collections.length}개</span>
            </div>
            {collections.map(c => (
              <div key={c.name} onClick={() => nav('collectionDetail')} style={{ display: 'flex', alignItems: 'center', gap: 12, background: 'var(--surface-1)', borderRadius: 'var(--radius-card)', padding: 14, boxShadow: 'var(--shadow-card)', cursor: 'pointer' }}>
                <div style={{ display: 'flex', flexShrink: 0 }}>
                  {[0, 1, 2].map(i => (
                    <div key={i} style={{ width: 48, height: 48, borderRadius: 12, background: 'var(--surface-2)', border: '2px solid var(--surface-1)', marginLeft: i ? -16 : 0, display: 'flex', alignItems: 'center', justifyContent: 'center' }}><i className="ti ti-photo" style={{ fontSize: 15, color: 'var(--text-muted)' }}></i></div>
                  ))}
                </div>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 5, marginBottom: 3 }}>
                    <i className={'ti ti-' + c.icon} style={{ fontSize: 13, color: 'var(--text-accent)', flexShrink: 0 }}></i>
                    <span style={{ font: 'var(--text-body-strong)', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{c.name}</span>
                  </div>
                  <span style={{ font: 'var(--text-small)', color: 'var(--text-secondary)', display: 'block' }}>{c.sub}</span>
                  <span style={{ font: 'var(--text-micro)', color: 'var(--text-muted)' }}>게시물 {c.count}개</span>
                </div>
                <i className="ti ti-chevron-right" style={{ fontSize: 17, color: 'var(--text-muted)', flexShrink: 0 }}></i>
              </div>
            ))}
            <div onClick={() => setColSheet(true)} style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8, border: '1.5px dashed var(--border-strong)', borderRadius: 'var(--radius-card)', padding: '18px 0', cursor: 'pointer' }}>
              <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 style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', marginTop: 12 }}>
              <span style={{ font: 'var(--text-body-strong)' }}>저장한 컬렉션</span>
              <span style={{ font: 'var(--text-micro)', color: 'var(--text-muted)' }}>{savedCollections.length}개</span>
            </div>
            {savedCollections.map(c => (
              <div key={c.name} onClick={() => nav('collectionDetailOther')} style={{ display: 'flex', alignItems: 'center', gap: 12, background: 'var(--surface-1)', borderRadius: 'var(--radius-card)', padding: 14, boxShadow: 'var(--shadow-card)', cursor: 'pointer' }}>
                <div style={{ display: 'flex', flexShrink: 0 }}>
                  {[0, 1, 2].map(i => (
                    <div key={i} style={{ width: 48, height: 48, borderRadius: 12, background: 'var(--surface-2)', border: '2px solid var(--surface-1)', marginLeft: i ? -16 : 0, display: 'flex', alignItems: 'center', justifyContent: 'center' }}><i className="ti ti-photo" style={{ fontSize: 15, color: 'var(--text-muted)' }}></i></div>
                  ))}
                </div>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 5, marginBottom: 3 }}>
                    <i className={'ti ti-' + c.icon} style={{ fontSize: 13, color: 'var(--text-accent)', flexShrink: 0 }}></i>
                    <span style={{ font: 'var(--text-body-strong)', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{c.name}</span>
                  </div>
                  <span style={{ font: 'var(--text-small)', color: 'var(--text-secondary)', display: 'block' }}>@{c.owner}</span>
                  <span style={{ font: 'var(--text-micro)', color: 'var(--text-muted)' }}>게시물 {c.count}개 · 장소 {c.places}곳</span>
                </div>
                <i className="ti ti-bookmarks" style={{ fontSize: 16, color: 'var(--text-accent)', flexShrink: 0 }}></i>
              </div>
            ))}
          </div>
        ) : tab === '챌린지' ? (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 10, padding: '0 20px' }}>
            <div style={{ display: 'flex', gap: 8 }}>
              {['진행 중', '종료'].map(t => (
                <span key={t} onClick={() => setCFilter(t)} style={{ font: cFilter === t ? '600 13px/1 var(--font-family)' : '400 13px/1 var(--font-family)', color: cFilter === t ? '#fff' : 'var(--text-secondary)', background: cFilter === t ? 'var(--bg-ink)' : 'var(--surface-2)', borderRadius: 999, padding: '9px 14px', cursor: 'pointer' }}>{t}{t === '종료' ? ' ' + endedChallenges.length : ''}</span>
              ))}
            </div>
            {cFilter === '종료' ? endedChallenges.map(e => (
              <div key={e.name} onClick={() => nav('missionDetail', { ended: { ...e, from: 'profile' } })} style={{ background: 'var(--surface-1)', borderRadius: 'var(--radius-card)', padding: 16, boxShadow: 'var(--shadow-card)', cursor: 'pointer' }}>
                <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 12 }}>
                  <div style={{ width: 42, height: 42, borderRadius: '50%', background: e.won ? 'var(--bg-success)' : 'var(--surface-2)', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}><i className={'ti ti-' + (e.won ? 'trophy' : e.icon)} style={{ fontSize: 19, color: e.won ? 'var(--text-success)' : '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' }}>{e.name}</span>
                    <span style={{ font: 'var(--text-micro)', color: 'var(--text-muted)' }}>{e.period}</span>
                  </div>
                  <span style={{ flexShrink: 0, font: '600 12px/1 var(--font-family)', borderRadius: 999, padding: '7px 11px', color: e.won ? 'var(--text-success)' : e.achieved ? 'var(--text-secondary)' : 'var(--text-muted)', background: e.won ? 'var(--bg-success)' : 'var(--surface-2)' }}>{e.rewardState}</span>
                </div>
                <div style={{ display: 'flex', alignItems: 'center', gap: 8, background: 'var(--surface-2)', borderRadius: 'var(--radius-tile)', padding: '12px 14px' }}>
                  <span style={{ font: 'var(--text-small)', color: 'var(--text-secondary)' }}>최종 {e.now}/{e.goal}</span>
                  <span style={{ width: 3, height: 3, borderRadius: 999, background: 'var(--text-muted)' }}></span>
                  <span style={{ font: 'var(--text-small)', color: 'var(--text-secondary)' }}>{e.achieved ? '완주' : '미완주'}</span>
                  {e.percentile && <React.Fragment><span style={{ width: 3, height: 3, borderRadius: 999, background: 'var(--text-muted)' }}></span><span style={{ font: 'var(--text-small)', color: 'var(--text-secondary)' }}>상위 {e.percentile}%</span></React.Fragment>}
                  <i className="ti ti-chevron-right" style={{ marginLeft: 'auto', fontSize: 15, color: 'var(--text-muted)' }}></i>
                </div>
              </div>
            )) : (<React.Fragment>
            <div onClick={() => nav('missions')} style={{ display: 'flex', alignItems: 'center', gap: 11, background: 'var(--bg-accent)', borderRadius: 'var(--radius-tile)', padding: '14px 16px', cursor: 'pointer' }}>
              <i className="ti ti-flag" style={{ fontSize: 18, color: 'var(--text-accent)', flexShrink: 0 }}></i>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ font: '600 14px/1.4 var(--font-family)', color: 'var(--text-accent)', marginBottom: 2 }}>보상 있는 미션 보기</div>
                <div style={{ font: 'var(--text-micro)', color: 'var(--text-secondary)' }}>진행 중 3개 · 참여 중 3개</div>
              </div>
              <i className="ti ti-chevron-right" style={{ fontSize: 15, color: 'var(--text-accent)', flexShrink: 0 }}></i>
            </div>
            {RANKINGS.map(R => {
              const on = openRank === R.key, max = R.board[0][3], inCut = R.me.rank <= R.top;
              return (
                <div key={R.key} style={{ background: 'var(--surface-1)', borderRadius: 'var(--radius-card)', padding: 16, boxShadow: 'var(--shadow-card)' }}>
                  <div onClick={() => setOpenRank(on ? null : R.key)} style={{ display: 'flex', alignItems: 'center', gap: 12, cursor: 'pointer' }}>
                    <div style={{ width: 42, height: 42, borderRadius: '50%', background: 'var(--surface-2)', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}><i className={'ti ti-' + R.icon} style={{ fontSize: 19, color: 'var(--text-secondary)' }}></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' }}>{R.name}</span>
                      <span style={{ font: 'var(--text-micro)', color: 'var(--text-muted)' }}>{R.reset}</span>
                    </div>
                    <i className={'ti ti-chevron-' + (on ? 'up' : 'down')} style={{ fontSize: 16, color: 'var(--text-muted)', flexShrink: 0 }}></i>
                  </div>
                  <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6, marginTop: 11 }}>
                    <span style={{ font: '600 11px/1 var(--font-family)', color: 'var(--text-secondary)', background: 'var(--surface-2)', borderRadius: 999, padding: '7px 10px' }}>상위 {R.top}명 지급</span>
                    <span style={{ font: '600 11px/1 var(--font-family)', color: 'var(--text-secondary)', background: 'var(--surface-2)', borderRadius: 999, padding: '7px 10px' }}>최소 {R.min}</span>
                    <span style={{ font: '600 11px/1 var(--font-family)', color: 'var(--text-secondary)', background: 'var(--surface-2)', borderRadius: 999, padding: '7px 10px' }}>{R.hold}</span>
                  </div>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginTop: 12, background: 'var(--bg-accent)', borderRadius: 'var(--radius-tile)', padding: '13px 14px' }}>
                    <div style={{ minWidth: 0, flex: 1 }}>
                      <span style={{ font: 'var(--text-micro)', color: 'var(--text-secondary)', display: 'block', marginBottom: 5 }}>현재 주기 {R.cycle} · 내 순위</span>
                      <div style={{ display: 'flex', alignItems: 'baseline', gap: 6 }}>
                        <span style={{ font: '700 24px/1 var(--font-family)', color: 'var(--text-accent)' }}>{R.me.rank}</span>
                        <span style={{ font: 'var(--text-small)', color: 'var(--text-secondary)' }}>위 / {R.total.toLocaleString()}명</span>
                      </div>
                    </div>
                    <div style={{ textAlign: 'right', flexShrink: 0 }}>
                      <span style={{ font: 'var(--text-micro)', color: 'var(--text-secondary)', display: 'block', marginBottom: 5 }}>{R.ends}</span>
                      <span style={{ font: '700 17px/1 var(--font-family)' }}>{R.me.value}{R.unit}</span>
                    </div>
                  </div>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 11, marginTop: 8, background: 'var(--surface-2)', borderRadius: 'var(--radius-tile)', padding: '12px 14px' }}>
                    <span style={{ width: 34, height: 34, borderRadius: 10, flexShrink: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', background: R.prev.awarded ? R.badgeColor + '1A' : 'var(--surface-1)', border: '1px solid ' + (R.prev.awarded ? R.badgeColor + '40' : 'var(--border)') }}><i className={'ti ti-' + (R.prev.awarded ? R.badgeIcon : 'lock')} style={{ fontSize: 17, color: R.prev.awarded ? R.badgeColor : 'var(--text-muted)' }}></i></span>
                    <div style={{ flex: 1, minWidth: 0 }}>
                      <span style={{ font: 'var(--text-micro)', color: 'var(--text-secondary)', display: 'block', marginBottom: 4 }}>직전 주기 {R.prev.label} 확정 순위</span>
                      <div style={{ display: 'flex', alignItems: 'baseline', gap: 5 }}>
                        <span style={{ font: '700 15px/1 var(--font-family)' }}>{R.prev.rank}위</span>
                        <span style={{ font: 'var(--text-micro)', color: 'var(--text-muted)' }}>{R.prev.value}{R.unit}</span>
                      </div>
                    </div>
                    <span style={{ flexShrink: 0, textAlign: 'right', maxWidth: 122 }}>
                      <span style={{ font: '600 12px/1.35 var(--font-family)', color: R.prev.awarded ? 'var(--text-primary)' : 'var(--text-muted)', display: 'block' }}>{R.badge}</span>
                      <span style={{ font: 'var(--text-micro)', color: R.prev.awarded ? 'var(--text-success)' : 'var(--text-muted)' }}>{R.prev.awarded ? '수여됨' : '배지 없음'}</span>
                    </span>
                  </div>
                  <span style={{ display: 'block', marginTop: 8, font: 'var(--text-micro)', color: 'var(--text-muted)', lineHeight: 1.55 }}>직전 주기 확정 순위 기준으로 「{R.badge}」 배지가 수여됩니다 · {R.prev.note}</span>
                  <span style={{ display: 'block', marginTop: 6, font: '600 12px/1.5 var(--font-family)', color: inCut ? 'var(--text-success)' : 'var(--text-secondary)' }}>{inCut ? '지급권 진입 · 이대로 확정되면 「' + R.badge + '」 배지를 받아요' : R.me.rank - R.top + '단계 더 올리면 상위 ' + R.top + '명에 들어요'}</span>
                  {on && (
                    <div style={{ marginTop: 14, paddingTop: 14, borderTop: '1px solid var(--border)', display: 'flex', flexDirection: 'column', gap: 10 }}>
                      {R.board.map((u, i) => (
                        <div key={u[2]} style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
                          <span style={{ width: 20, textAlign: 'center', flexShrink: 0, font: u[0] <= 3 ? '700 13px/1 var(--font-family)' : '400 13px/1 var(--font-family)', color: u[0] === 1 ? '#E8A33D' : u[0] <= 3 ? 'var(--text-primary)' : 'var(--text-muted)' }}>{u[0]}</span>
                          <div style={{ width: 28, height: 28, borderRadius: '50%', background: u[4], display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}><span style={{ font: '700 12px/1 var(--font-family)', color: '#fff' }}>{u[1].slice(0, 1)}</span></div>
                          <div style={{ flex: 1, minWidth: 0 }}>
                            <span style={{ font: 'var(--text-small)', fontWeight: 600, display: 'block', marginBottom: 5, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{u[1]}{u[2] === R.me.handle ? <span style={{ font: '600 11px/1 var(--font-family)', color: 'var(--text-accent)', marginLeft: 5 }}>나</span> : null}{u[5] ? <span style={{ font: '400 11px/1 var(--font-family)', color: 'var(--text-muted)', marginLeft: 5 }}>{u[5]}</span> : null}</span>
                            <div style={{ height: 5, borderRadius: 999, background: 'var(--surface-2)', overflow: 'hidden' }}><div style={{ width: Math.round(u[3] / max * 100) + '%', height: '100%', borderRadius: 999, background: u[0] === 1 ? '#E8A33D' : 'var(--text-accent)' }}></div></div>
                          </div>
                          <span style={{ font: 'var(--text-small)', color: 'var(--text-secondary)', flexShrink: 0 }}>{u[3]}</span>
                        </div>
                      ))}
                    </div>
                  )}
                </div>
              );
            })}
            {challenges.map(c => {
              const pct = Math.round(c.now / c.goal * 100);
              return (
                <div key={c.name} onClick={() => { if (c.icon === 'gift') nav('missionDetail'); }} style={{ background: 'var(--surface-1)', borderRadius: 'var(--radius-card)', padding: 16, boxShadow: 'var(--shadow-card)', cursor: 'pointer' }}>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 12 }}>
                    <div style={{ width: 42, height: 42, borderRadius: '50%', background: c.done ? 'var(--bg-success)' : 'var(--bg-accent)', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}><i className={'ti ti-' + (c.done ? 'check' : c.icon)} style={{ fontSize: 19, color: c.done ? 'var(--text-success)' : 'var(--text-accent)' }}></i></div>
                    <div style={{ flex: 1, minWidth: 0 }}>
                      <span style={{ font: 'var(--text-body-strong)', display: 'block', marginBottom: 2, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{c.name}</span>
                      <span style={{ font: 'var(--text-small)', color: 'var(--text-secondary)' }}>보상 · {c.reward}</span>
                    </div>
                    {!c.joined && !c.done && <span style={{ flexShrink: 0, font: '600 13px/1 var(--font-family)', color: '#fff', background: 'var(--text-accent)', borderRadius: 999, padding: '11px 14px' }}>참여</span>}
                  </div>
                  <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', marginBottom: 7 }}>
                    <span style={{ font: 'var(--text-small)', color: 'var(--text-primary)', fontWeight: 600 }}>{c.now} / {c.goal}</span>
                    <span style={{ font: 'var(--text-micro)', color: c.done ? 'var(--text-success)' : 'var(--text-muted)' }}>{c.left}</span>
                  </div>
                  <div style={{ width: '100%', height: 7, borderRadius: 999, background: 'var(--surface-2)', overflow: 'hidden' }}>
                    <div style={{ width: pct + '%', height: '100%', borderRadius: 999, background: c.done ? 'var(--text-success)' : 'var(--text-accent)' }}></div>
                  </div>
                </div>
              );
            })}
            </React.Fragment>)}
          </div>
        ) : tab !== '배지' ? (
          <div>
          {tab === '게시물' && (
            <div style={{ display: 'flex', gap: 7, padding: '0 20px 14px', overflowX: 'auto', scrollbarWidth: 'none' }}>
              {['전체'].concat(pAreaList).map(a => (
                <span key={a} onClick={() => setPArea(a)} style={{ flexShrink: 0, display: 'inline-flex', alignItems: 'center', gap: 5, font: '600 13px/1 var(--font-family)', color: pArea === a ? 'var(--text-accent)' : 'var(--text-secondary)', background: pArea === a ? 'var(--bg-accent)' : 'var(--surface-1)', border: '1px solid ' + (pArea === a ? 'transparent' : 'var(--border)'), borderRadius: 999, padding: '10px 13px', cursor: 'pointer', whiteSpace: 'nowrap' }}>
                  {a !== '전체' && <i className="ti ti-map-pin" style={{ fontSize: 12 }}></i>}{a}
                  <span style={{ font: 'var(--text-micro)', color: pArea === a ? 'var(--text-accent)' : 'var(--text-muted)' }}>{a === '전체' ? posts.length : pAreaCounts[a]}</span>
                </span>
              ))}
            </div>
          )}
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2,1fr)', gridAutoRows: 'min-content', gap: 10, padding: '0 20px' }}>
            {posts.map((p2, i) => pfGone[i] || (tab === '게시물' && pArea !== '전체' && (p2.area || '장소 미지정') !== pArea) ? null : (
              <div key={i} onClick={() => setOpen({ ...p2, imageId: 'pf-' + i })} style={{ background: 'var(--surface-1)', borderRadius: 'var(--radius-card)', overflow: 'hidden', boxShadow: 'var(--shadow-card)', cursor: 'pointer', opacity: pfHidden[i] ? .55 : 1 }}>
                <div style={{ width: '100%', aspectRatio: '1', background: 'var(--surface-2)', position: 'relative', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                  {p2.src ? <img src={p2.src} alt={p2.menu} style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover' }} /> : <i className={p2.hasVideo ? 'ti ti-video' : 'ti ti-photo'} style={{ fontSize: 24, color: 'var(--text-muted)' }}></i>}
                  <span onClick={(e) => { e.stopPropagation(); setMySheet({ type: 'menu', post: { ...p2, _key: i, isMine: true, mediaCount: p2.mediaCount || 1 }, idx: i }); }} style={{ position: 'absolute', right: 4, top: 4, width: 44, height: 44, display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer', zIndex: 3 }}><span style={{ width: 34, height: 34, borderRadius: '50%', background: 'rgba(255,255,255,.92)', backdropFilter: 'blur(8px)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}><i className="ti ti-dots" style={{ fontSize: 18, color: 'var(--text-primary)' }}></i></span></span>
                  {pfHidden[i] && <span style={{ position: 'absolute', left: 8, top: 8, font: '600 10px/1 var(--font-family)', color: '#fff', background: 'rgba(26,26,26,.78)', borderRadius: 999, padding: '5px 8px', display: 'inline-flex', alignItems: 'center', gap: 3, zIndex: 2 }}><i className="ti ti-eye-off" style={{ fontSize: 10 }}></i>숨김</span>}
                  {p2.mediaCount > 1 && <span style={{ position: 'absolute', right: 8, bottom: 8, font: 'var(--text-micro)', color: '#fff', background: 'rgba(26,26,26,.68)', borderRadius: 999, padding: '4px 8px' }}>1/{p2.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' }}>#{p2.menu}</span>
                  {p2.mission
                    ? <span style={{ position: 'absolute', left: 8, top: 8, font: '700 10px/1 var(--font-family)', color: '#fff', background: 'var(--text-accent)', borderRadius: 999, padding: '5px 8px', letterSpacing: '.03em' }}>MISSION</span>
                    : p2.reportCount ? <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>제보 {p2.reportCount}</span> : null}
                </div>
                <div style={{ padding: '11px 12px 13px' }}>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 4, marginBottom: 6 }}>
                    <i className={p2.mission ? 'ti ti-gift' : p2.place ? 'ti ti-map-pin' : 'ti ti-map-pin-question'} style={{ fontSize: 11, color: p2.mission ? 'var(--text-accent)' : p2.place ? 'var(--text-secondary)' : 'var(--text-warning)', flexShrink: 0 }}></i>
                    <span style={{ font: 'var(--text-small)', color: p2.mission ? 'var(--text-accent)' : p2.place ? 'var(--text-primary)' : 'var(--text-warning)', fontWeight: 600, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{p2.mission ? '밀키트 미션 · 심사 중' : p2.place || (p2.reportCount ? '제보 확인 필요' : '장소 미지정')}</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>{p2.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>{p2.comments}</span>
                    <span style={{ font: 'var(--text-micro)', color: 'var(--text-muted)', marginLeft: 'auto' }}>{p2.time}</span>
                  </div>
                  {p2.area && <div style={{ display: 'flex', alignItems: 'center', gap: 3, marginTop: 6 }}><i className="ti ti-map-2" style={{ fontSize: 11, color: 'var(--text-muted)', flexShrink: 0 }}></i><span style={{ font: 'var(--text-micro)', color: 'var(--text-muted)', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{p2.city} {p2.area}</span></div>}
                </div>
              </div>
            ))}
            <div onClick={() => nav('myPosts')} style={{ gridColumn: '1 / -1', display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8, background: 'var(--surface-1)', border: '1px solid var(--border-strong)', borderRadius: 999, padding: '15px 0', cursor: 'pointer', marginTop: 2 }}>
              <span style={{ font: '600 14px/1 var(--font-family)', color: 'var(--text-primary)' }}>게시물 전체보기</span>
              <i className="ti ti-chevron-right" style={{ fontSize: 16, color: 'var(--text-muted)' }}></i>
            </div>
            </div>
          </div>
        ) : (
          <BadgeCollection noneOwned={noBadges} onOpen={(b) => setBadgeOpen(b)} />
        )}
      </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 })} />}
      {mySheet && mySheet.type === 'menu' && <MyPostMenuSheet post={{ ...mySheet.post, hidden: !!pfHidden[mySheet.idx] }} onClose={() => setMySheet(null)} onEdit={() => { const pp2 = mySheet.post; setMySheet(null); nav('editPost', { post: pp2 }); }} onHide={() => setMySheet({ ...mySheet, type: 'hide' })} onPhotos={() => setMySheet({ ...mySheet, type: 'photos' })} onShare={() => setMySheet(null)} onDelete={() => setMySheet({ ...mySheet, type: 'delete' })} />}
      {mySheet && mySheet.type === 'hide' && <HidePostConfirm post={mySheet.post} hidden={!!pfHidden[mySheet.idx]} onCancel={() => setMySheet({ ...mySheet, type: 'menu' })} onConfirm={(v) => { const k = mySheet.idx; setPfHidden(x => ({ ...x, [k]: v === 'private' })); setMySheet(null); setPToast('공개 범위를 ' + visMeta(effVis(accountVis(), v)).label + '로 바꿨어요'); }} />}
      {mySheet && mySheet.type === 'photos' && <EditPhotosSheet post={mySheet.post} onClose={() => setMySheet({ ...mySheet, type: 'menu' })} onDone={(n, left) => { setMySheet(null); setPToast('사진 ' + n + '장을 지웠어요 · ' + left + '장 남음'); }} onDeletePost={() => setMySheet({ ...mySheet, type: 'delete' })} />}
      {mySheet && mySheet.type === 'delete' && <DeletePostConfirm post={mySheet.post} onCancel={() => setMySheet({ ...mySheet, type: 'menu' })} onConfirm={() => { setPfGone(g => ({ ...g, [mySheet.idx]: true })); setMySheet(null); setPToast('게시물을 삭제했어요'); }} />}
      {pickBadge && <FeaturedBadgeSheet noneOwned={noBadges} onSeeAll={() => { setPickBadge(false); setTab('배지'); }} current={featured} onClose={() => setPickBadge(false)} onSelect={(b) => { setFeatured(b); setPickBadge(false); setPToast(b ? '대표 배지를 「' + b.n + '」로 바꿨어요' : '대표 배지를 표시하지 않아요'); }} />}
      {badgeOpen && <BadgeDetailSheet badge={noBadges ? Object.assign({}, badgeOpen, { got: null, cur: 0 }) : badgeOpen} onClose={() => setBadgeOpen(null)} />}
      {sheet && <ProfilePhotoSheet onClose={() => setSheet(false)} />}
      {colSheet && <NewCollectionSheet onClose={() => setColSheet(false)} onDone={(nm) => { setColSheet(false); setPToast('「' + nm + '」 컬렉션을 만들었어요'); }} />}
      {pToast && (
        <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)' }}>{pToast}</span>
        </div>
      )}
      {askUnsave && <UnsavePlaceConfirm name={askUnsave} onCancel={() => setAskUnsave(null)} onConfirm={() => { setUnsaved(u => ({ ...u, [askUnsave]: true })); setAskUnsave(null); }} />}
      {shareSheet && <ShareProfileSheet onClose={() => setShareSheet(false)} />}
    </div>
  );
}
window.Profile = Profile;
