// 스윙 영상 리스트 + 스윙 상세 (샷 분포도 / 목표 적중률)

// ===== 스윙 영상 (스윙영상 탭) — Figma 04.0.CategoryHome_Video =====
const SW_MONTHS = ["2026년 1월","2025년 12월","2025년 11월","2025년 10월","2025년 9월","2025년 8월"];
const SW_SHOTS = ["전체","티샷","세컨샷","어프로치","퍼팅","리플레이샷"];  // FS SwingShotType
const SW_SORTS = ["최신순","좋아요순"];                                    // FS SwingSortType
const SW_MY = {
  "2026년 1월":[
    {date:"1월 20일", store:"골드레이크 · 골드/레이크", ic:"multi", clips:[{dist:"20.1m",club:"어프로치",shot:"어프로치"},{dist:"153.9m",club:"드라이버",shot:"티샷",best:true},{dist:"3.9m",club:"퍼터",shot:"퍼팅"}]},
    {date:"1월 12일", store:"서산수", ic:"tree", clips:[{dist:"88.2m",club:"7번 아이언",shot:"세컨샷"},{dist:"151.4m",club:"드라이버",shot:"티샷"}]},
    {date:"1월 4일",  store:"루트52", ic:"fire", clips:[{dist:"20.1m",club:"어프로치",shot:"어프로치"},{dist:"175.5m",club:"드라이버",shot:"티샷",best:true},{dist:"120.1m",club:"6번 아이언",shot:"세컨샷"}]},
  ],
  "2025년 12월":[
    {date:"12월 24일", store:"판교점 · 마스터", ic:"multi", clips:[{dist:"178.2m",club:"드라이버",shot:"티샷"},{dist:"95.5m",club:"8번 아이언",shot:"세컨샷"},{dist:"2.1m",club:"퍼터",shot:"퍼팅"}]},
    {date:"12월 10일", store:"서산수", ic:"tree", clips:[{dist:"30.4m",club:"웨지",shot:"어프로치"},{dist:"165.8m",club:"드라이버",shot:"티샷",best:true}]},
  ],
};
const SW_TRAINING = {
  "2026년 1월":[
    {date:"1월 18일", store:"판교점 · 연습", ic:"tree", clips:[{dist:"185.2m",club:"드라이버",shot:"티샷",best:true},{dist:"142.1m",club:"5번 아이언",shot:"세컨샷"},{dist:"90.4m",club:"9번 아이언",shot:"세컨샷"}]},
    {date:"1월 9일",  store:"판교점 · 연습", ic:"tree", clips:[{dist:"28.3m",club:"웨지",shot:"어프로치"},{dist:"172.0m",club:"드라이버",shot:"티샷"}]},
  ],
  "2025년 12월":[
    {date:"12월 28일", store:"강남점 · 연습", ic:"tree", clips:[{dist:"160.5m",club:"드라이버",shot:"티샷"},{dist:"110.2m",club:"7번 아이언",shot:"세컨샷",best:true}]},
  ],
};
const SW_COMMUNITY = [
  {author:"나는쏘니야", store:"골드레이크", clips:[{dist:"40.0m",club:"어프로치",shot:"어프로치",likes:24},{dist:"180.2m",club:"드라이버",shot:"티샷",likes:57}]},
  {author:"라이언석",   store:"판교점",     clips:[{dist:"155.1m",club:"드라이버",shot:"티샷",likes:12},{dist:"12.3m",club:"퍼터",shot:"퍼팅",likes:8}]},
  {author:"어피치",     store:"강남점",     clips:[{dist:"92.4m",club:"7번 아이언",shot:"세컨샷",likes:41},{dist:"33.0m",club:"웨지",shot:"어프로치",likes:19}]},
];
// 스윙 데이터(구질/비거리/캐리/볼스피드/발사각/백스핀) — 클립 시드로 생성 (구질 등은 FS 나의 샷 데이터와 동일 구성)
const SW_SHAPES = ["푸시슬라이스","스트레이트","드로우","페이드","훅"];
const swSeed = (c)=>{ const t=(c?.club||"")+(c?.dist||"")+(c?.shot||""); let s=0; for(let i=0;i<t.length;i++) s+=t.charCodeAt(i); return s; };
const swData = (c)=>{ const seed=swSeed(c); const d=parseFloat(c?.dist)||120; const k=seed%7;
  return [["구질",SW_SHAPES[seed%5]],["비거리",c?.dist||"-"],["캐리",(d*0.72).toFixed(1)+"m"],["볼스피드",(24+k*1.7).toFixed(1)+"m/s"],["발사각",(12+k*1.9).toFixed(1)+"°"],["백스핀",(1800+k*230).toLocaleString()+"rpm"]]; };
// 같은 스톡 영상 → 클립별 필터로 시각 구분
const swFilter = (c)=> ["none","hue-rotate(16deg) brightness(1.05)","hue-rotate(-14deg) saturate(1.15)","brightness(.92) contrast(1.08)","hue-rotate(28deg)"][swSeed(c)%5];
// 광고 배너
function SwBanner(){
  return (
    <div style={{margin:"10px 20px 0",borderRadius:12,overflow:"hidden",background:"linear-gradient(90deg,#F97316,#FB923C)",padding:"15px 18px",position:"relative"}}>
      <div style={{fontSize:14,fontWeight:800,color:"#fff",lineHeight:1.35}}>광동제약과 함께 하는<br/>행운가드득 클래식 시즌2</div>
      <div style={{position:"absolute",right:14,bottom:12,display:"flex",gap:4}}>{[0,1,2].map(i=><span key={i} style={{width:5,height:5,borderRadius:"50%",background:i===0?"#fff":"rgba(255,255,255,.5)"}}/>)}</div>
    </div>
  );
}
const swStoreIc = (ic)=> ic==="fire" ? <Icon name="fire" size={14} style={{color:"#F97316"}}/>
  : ic==="tree" ? <svg viewBox="0 0 16 16" width="14" height="14"><path d="M8 1l4 6H9l3 5H4l3-5H4z" fill="#16A34A"/><rect x="7" y="12" width="2" height="3" fill="#16A34A"/></svg>
  : <Icon name="people" size={14} style={{color:"#3B82F6"}}/>;
// 썸네일 셀 (check!==undefined 이면 선택 모드)
function SwThumb({ clip, extra, onClick, check }){
  const sel = check===true;
  return (
    <button onClick={onClick} style={{background:"transparent",border:"none",padding:0,textAlign:"left"}}>
      <div style={{position:"relative",aspectRatio:"3/4",borderRadius:8,overflow:"hidden",background:"#111",outline:sel?"2.5px solid var(--primary)":"none",outlineOffset:-1}}>
        <img src="assets/swing-poster.png" alt="" style={{width:"100%",height:"100%",objectFit:"cover",filter:swFilter(clip),opacity:check!==undefined&&!sel?.75:1}}/>
        {clip.best && <span style={{position:"absolute",left:6,top:6,fontSize:9,fontWeight:800,color:"#111",background:"#FDE047",padding:"2px 5px",borderRadius:4}}>리플레이</span>}
        {check!==undefined ? (
          <span style={{position:"absolute",right:6,top:6,width:20,height:20,borderRadius:"50%",background:sel?"var(--primary)":"rgba(0,0,0,.35)",border:sel?"none":"1.5px solid #fff",display:"flex",alignItems:"center",justifyContent:"center"}}>{sel && <Icon name="check" size={13} style={{color:"#fff"}}/>}</span>
        ) : (
          <div style={{position:"absolute",top:"50%",left:"50%",transform:"translate(-50%,-50%)",width:26,height:26,borderRadius:"50%",background:"rgba(255,255,255,.22)",backdropFilter:"blur(6px)",display:"flex",alignItems:"center",justifyContent:"center",color:"#fff"}}><Icon name="play" size={11}/></div>
        )}
      </div>
      <div style={{fontSize:14,fontWeight:800,marginTop:6,letterSpacing:"-.01em"}}>{clip.dist}</div>
      <div style={{fontSize:11.5,color:"var(--text-sub)",display:"flex",alignItems:"center",gap:4}}>{clip.club}{extra}</div>
    </button>
  );
}

function SwingScreen({ onNav, onOpenDetail }){
  const [tab, setTab] = React.useState("screen"); // screen | training | community
  const [month, setMonth] = React.useState("2026년 1월");
  const [monthSheet, setMonthSheet] = React.useState(false);
  const [shot, setShot] = React.useState("전체");
  const [sort, setSort] = React.useState("최신순");
  const [sortSheet, setSortSheet] = React.useState(false);
  const [demoEmpty, setDemoEmpty] = React.useState(false); // 데모: 영상 없을 때
  const [select, setSelect] = React.useState(false);       // 트레이닝 선택 모드
  const [sel, setSel] = React.useState(()=>new Set());
  const [dlg, setDlg] = React.useState(null);              // "delete" | "save"
  const [toast, setToast] = React.useState(null);
  const pop=(m)=>{ setToast(m); window.clearTimeout(pop._t); pop._t=window.setTimeout(()=>setToast(null),2200); };
  const community = tab==="community", train = tab==="training";
  const shiftMonth = (d)=>{ if(select) return; const i=SW_MONTHS.indexOf(month); const n=i+d; if(n>=0&&n<SW_MONTHS.length) setMonth(SW_MONTHS[n]); };
  const open = (clip, meta)=> onOpenDetail && onOpenDetail({...clip, ...meta, community});
  const matchShot = (c)=> shot==="전체" ? true : shot==="리플레이샷" ? !!c.best : c.shot===shot;
  const srcRounds = demoEmpty ? [] : (train ? (SW_TRAINING[month]||[]) : (SW_MY[month]||[]));
  const fRounds = srcRounds.map(r=>({...r, clips:r.clips.filter(matchShot)})).filter(r=>r.clips.length>0);
  const comm = demoEmpty ? [] : (sort==="좋아요순" ? SW_COMMUNITY.map(u=>({...u, clips:[...u.clips].sort((a,b)=>b.likes-a.likes)})) : SW_COMMUNITY);
  // 선택 모드 키
  const allKeys=[]; fRounds.forEach((r,ri)=>r.clips.forEach((c,ci)=>allKeys.push(ri+"_"+ci)));
  const toggleKey=(k)=> setSel(s=>{ const n=new Set(s); n.has(k)?n.delete(k):n.add(k); return n; });
  const allSel = allKeys.length>0 && allKeys.every(k=>sel.has(k));
  const exitSelect=()=>{ setSelect(false); setSel(new Set()); };
  const doAction=(type)=>{ setDlg(null); const n=sel.size; exitSelect(); pop(type==="delete"?"영상이 삭제되었습니다.":n+"개 영상을 저장했습니다."); };

  return (
    <div className="screen">
      <StatusBar/>
      {toast && <div className="toast"><span>{toast}</span></div>}
      <div style={{display:"flex",borderBottom:"1px solid var(--line)",paddingTop:6}}>
        {[["screen","스크린"],["training","트레이닝"],["community","커뮤니티"]].map(([id,label])=>(
          <button key={id} onClick={()=>{ if(select)return; setTab(id); }} style={{flex:1,padding:"13px 0",fontSize:15,fontWeight:700,color:tab===id?"var(--text)":"var(--text-mute)",borderBottom:"2px solid "+(tab===id?"var(--text)":"transparent"),background:"none",marginBottom:-1,opacity:select&&tab!==id?.4:1}}>{label}</button>
        ))}
      </div>

      <div className="scroll" style={{paddingBottom:select?96:90}}>
        <SwBanner/>
        {/* 월 네비 + 데모 토글 */}
        <div style={{position:"relative",display:"flex",alignItems:"center",justifyContent:"center",gap:14,padding:"14px 0 10px"}}>
          <button onClick={()=>shiftMonth(1)} className="icon-btn" style={{width:28,height:28}}><Icon name="back" size={16}/></button>
          <button onClick={()=>!select&&setMonthSheet(true)} style={{fontSize:15,fontWeight:700,background:"transparent",borderBottom:"1px solid var(--text)",paddingBottom:2}}>{month}</button>
          <button onClick={()=>shiftMonth(-1)} className="icon-btn" style={{width:28,height:28}}><Icon name="chev-r" size={16}/></button>
          <button onClick={()=>{ setDemoEmpty(v=>!v); exitSelect(); }} style={{position:"absolute",right:16,fontSize:9,fontWeight:600,color:"var(--text-mute)",background:"transparent",border:"1px dashed var(--line)",borderRadius:4,padding:"3px 6px"}}>데모:{demoEmpty?"빈":"영상"}</button>
        </div>

        {/* 필터/정렬/선택 헤더 */}
        {select ? (
          <div style={{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"2px 20px 8px"}}>
            <button onClick={()=>setSel(allSel?new Set():new Set(allKeys))} style={{display:"flex",alignItems:"center",gap:8,background:"transparent"}}>
              <span style={{width:20,height:20,borderRadius:"50%",background:allSel?"var(--primary)":"transparent",border:allSel?"none":"1.5px solid var(--line-strong)",display:"flex",alignItems:"center",justifyContent:"center"}}>{allSel && <Icon name="check" size={13} style={{color:"#fff"}}/>}</span>
              <span style={{fontSize:14,fontWeight:700}}>전체 선택 <span style={{color:"var(--primary)"}}>{sel.size}</span></span>
            </button>
            <button onClick={exitSelect} style={{fontSize:14,fontWeight:600,color:"var(--text-sub)",background:"transparent"}}>취소</button>
          </div>
        ) : community ? (
          <div style={{display:"flex",justifyContent:"flex-end",padding:"0 20px 6px"}}>
            <button onClick={()=>setSortSheet(true)} style={{display:"flex",alignItems:"center",gap:3,fontSize:13,fontWeight:600,color:"var(--text-sub)",background:"transparent"}}>{sort} <Icon name="chev-d" size={13}/></button>
          </div>
        ) : (
          <div style={{display:"flex",alignItems:"center",gap:8,padding:"0 20px 6px"}}>
            <div style={{display:"flex",gap:8,overflowX:"auto",scrollbarWidth:"none",flex:1}}>
              {SW_SHOTS.map(fl=>(
                <button key={fl} onClick={()=>setShot(fl)} style={{flexShrink:0,fontSize:13,fontWeight:shot===fl?700:600,padding:"7px 14px",borderRadius:18,border:shot===fl?"none":"1px solid var(--line-strong)",background:shot===fl?"#1A1C1F":"#fff",color:shot===fl?"#fff":"var(--text-sub)",whiteSpace:"nowrap"}}>{fl}</button>
              ))}
            </div>
            {train && fRounds.length>0 && <button onClick={()=>setSelect(true)} style={{flexShrink:0,fontSize:13,fontWeight:700,color:"var(--text-sub)",background:"transparent"}}>선택</button>}
          </div>
        )}

        {community ? (
          comm.length===0 ? (
            <div style={{padding:"56px 30px",textAlign:"center"}}>
              <img src="assets/course-empty.png" alt="" style={{width:120,height:126,objectFit:"contain"}}/>
              <div style={{fontSize:15,fontWeight:600,color:"var(--text-mute)",marginTop:14}}>등록된 스윙영상이 없어요.</div>
            </div>
          ) : (
          <div style={{padding:"6px 20px 0"}}>
            {comm.map((u,ui)=>(
              <div key={ui} style={{marginBottom:8}}>
                <div style={{display:"flex",alignItems:"center",gap:8,padding:"10px 0 8px"}}>
                  <div className="avatar" style={{width:26,height:26,fontSize:12}}>{u.author[0]}</div>
                  <span style={{fontSize:13.5,fontWeight:700}}>{u.author}</span>
                  <span style={{fontSize:12,color:"var(--text-mute)"}}>· {u.store}</span>
                </div>
                <div style={{display:"grid",gridTemplateColumns:"1fr 1fr 1fr",gap:8}}>
                  {u.clips.map((clip,ci)=><SwThumb key={ci} clip={clip} extra={<span style={{display:"inline-flex",alignItems:"center",gap:2,marginLeft:4,color:"var(--text-mute)"}}><Icon name="heart" size={11}/>{clip.likes}</span>} onClick={()=>open(clip,{author:u.author,store:u.store})}/>)}
                </div>
              </div>
            ))}
          </div>
          )
        ) : fRounds.length===0 ? (
          <div style={{padding:"56px 30px",textAlign:"center"}}>
            <img src="assets/course-empty.png" alt="" style={{width:120,height:126,objectFit:"contain"}}/>
            <div style={{fontSize:15,fontWeight:600,color:"var(--text-mute)",marginTop:14}}>저장된 스윙영상이 없어요.</div>
          </div>
        ) : (
          fRounds.map((r,ri)=>(
            <div key={ri} style={{padding:"14px 20px 0"}}>
              <div style={{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:10}}>
                <span style={{fontSize:13.5,fontWeight:700}}>{r.date}</span>
                <span style={{display:"flex",alignItems:"center",gap:5,fontSize:12,color:"var(--text-sub)",fontWeight:600}}>{swStoreIc(r.ic)}{r.store}</span>
              </div>
              <div style={{display:"grid",gridTemplateColumns:"1fr 1fr 1fr",gap:8}}>
                {r.clips.map((clip,ci)=>{ const k=ri+"_"+ci; return (
                  <SwThumb key={ci} clip={clip} check={select?sel.has(k):undefined}
                    onClick={()=> select ? toggleKey(k) : open(clip,{date:r.date,store:r.store})}/>
                ); })}
              </div>
            </div>
          ))
        )}
      </div>

      {/* 선택 모드 하단 액션 */}
      {select ? (
        <div style={{position:"absolute",left:0,right:0,bottom:0,display:"flex",gap:8,padding:"12px 20px 24px",background:"#fff",borderTop:"1px solid var(--line)"}}>
          <button onClick={()=> sel.size ? setDlg("save") : pop("다운로드 할 영상을 선택해주세요.")} className="btn btn-soft" style={{flex:1}}>저장</button>
          <button onClick={()=> sel.size ? setDlg("delete") : pop("삭제할 영상을 선택해주세요.")} className="btn" style={{flex:1,background:"var(--danger)",color:"#fff"}}>삭제</button>
        </div>
      ) : <TabBar current="swing" onNav={onNav}/>}

      {monthSheet && (
        <Sheet title="날짜 선택" onClose={()=>setMonthSheet(false)}
          footer={<button className="btn btn-primary" style={{width:"100%"}} onClick={()=>setMonthSheet(false)}>적용</button>}>
          {SW_MONTHS.map(m=><SheetItem key={m} label={m} on={month===m} onClick={()=>setMonth(m)}/>)}
        </Sheet>
      )}
      {sortSheet && (
        <Sheet title="정렬" onClose={()=>setSortSheet(false)}>
          {SW_SORTS.map(s=><SheetItem key={s} label={s} on={sort===s} onClick={()=>{setSort(s); setSortSheet(false);}}/>)}
        </Sheet>
      )}
      {dlg && (
        <div onClick={()=>setDlg(null)} style={{position:"absolute",inset:0,background:"rgba(0,0,0,.45)",zIndex:50,display:"flex",alignItems:"center",justifyContent:"center",padding:"0 30px"}}>
          <div onClick={e=>e.stopPropagation()} style={{width:"100%",maxWidth:320,background:"#fff",borderRadius:16,padding:"24px 22px 18px",textAlign:"center"}}>
            <div style={{fontSize:16,fontWeight:800,lineHeight:1.4}}>{dlg==="delete"?"영상을 삭제하시겠습니까?":"선택한 영상을 저장하시겠습니까?"}</div>
            <div style={{fontSize:12.5,color:"var(--text-sub)",marginTop:10,lineHeight:1.6}}>{dlg==="delete"?"삭제를 누르면, 선택한 정면/측면 영상이 영구 삭제됩니다.":"3G/5G/LTE 환경에서 연결 시 데이터 통화료가 부과될 수 있습니다."}</div>
            <div style={{display:"flex",gap:8,marginTop:20}}>
              <button onClick={()=>setDlg(null)} className="btn btn-soft" style={{flex:1}}>취소</button>
              <button onClick={()=>doAction(dlg)} className="btn" style={{flex:1,background:dlg==="delete"?"var(--danger)":"var(--primary)",color:"#fff"}}>{dlg==="delete"?"삭제":"저장"}</button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

// 스윙 비디오 상세 (정면/측면 탭 + 플레이어 + 나의 스윙 정보 + 올리기 / 좋아요)
function SwingVideoDetail({ clip, onBack, onOpenUpload, onOpenDraw, onOpenAi }){
  const c = clip || {dist:"40.0m",club:"어프로치",shot:"어프로치",date:"1월 20일",store:"골드레이크 · 골드/레이크"};
  const community = c.community;
  const [aspect, setAspect] = React.useState("정면"); // 정면 | 측면 (FS TrainingAspectType)
  const SW_SPEEDS = [0.25,0.5,0.75,1,1.5];           // FS SwingExoVideoPlayer
  const [speed, setSpeed] = React.useState(1);
  const cycleSpeed = ()=> setSpeed(s=>{ const i=SW_SPEEDS.indexOf(s); return SW_SPEEDS[(i+1)%SW_SPEEDS.length]; });
  const [liked, setLiked] = React.useState(false);
  const [menu, setMenu] = React.useState(false);
  const [comm, setComm] = React.useState(false);
  const [cmtText, setCmtText] = React.useState("");
  const [toast, setToast] = React.useState(null);
  const pop = (m)=>{ setToast(m); window.clearTimeout(pop._t); pop._t=window.setTimeout(()=>setToast(null),2200); };
  const iconBtn = (svg,onClick)=> <button onClick={onClick} className="icon-btn">{svg}</button>;
  const data = swData(c);
  return (
    <div className="screen">
      <StatusBar/>
      <Appbar title={community?"스윙영상":"나의 스윙영상"} onBack={onBack}
        right={<div style={{display:"flex",gap:2}}>
          {iconBtn(<Icon name="share" size={18}/>, ()=>pop("공유 링크를 복사했어요."))}
          {!community && iconBtn(<svg viewBox="0 0 20 20" width="18" height="18" fill="none" stroke="currentColor" strokeWidth="1.7"><path d="M10 3v10M6 9l4 4 4-4M4 16h12" strokeLinecap="round" strokeLinejoin="round"/></svg>, ()=>pop("영상을 저장했어요."))}
        </div>}/>
      {toast && <div className="toast"><span>{toast}</span></div>}
      {/* 정면 / 측면 */}
      <div style={{display:"flex",borderBottom:"1px solid var(--line)"}}>
        {["정면","측면"].map(a=>(
          <button key={a} onClick={()=>setAspect(a)} style={{flex:1,padding:"12px 0",fontSize:14,fontWeight:700,color:aspect===a?"var(--text)":"var(--text-mute)",borderBottom:"2px solid "+(aspect===a?"var(--text)":"transparent"),background:"none",marginBottom:-1}}>{a}</button>
        ))}
      </div>
      <div className="scroll" style={{paddingBottom:90}}>
        {/* 유저 */}
        <div style={{display:"flex",alignItems:"center",gap:10,padding:"12px 20px 10px"}}>
          <div className="avatar" style={{width:34,height:34,fontSize:14}}>{(c.author||"나는쏘니야")[0]}</div>
          <div style={{flex:1}}>
            <div style={{fontSize:14,fontWeight:700}}>{c.author||"나는쏘니야"}</div>
            <div style={{fontSize:12,color:"var(--text-sub)"}}>{c.store||"골드레이크 · 골드/레이크"}</div>
          </div>
          <button onClick={()=>setMenu(true)} className="icon-btn"><svg viewBox="0 0 20 20" width="20" height="20" fill="currentColor"><circle cx="10" cy="4" r="1.6"/><circle cx="10" cy="10" r="1.6"/><circle cx="10" cy="16" r="1.6"/></svg></button>
        </div>
        {/* 플레이어 (측면=미러 데모) */}
        <div style={{position:"relative",background:"#000",overflow:"hidden"}}>
          <img src="assets/swing-poster.png" alt="" style={{width:"100%",display:"block",filter:swFilter(c),transform:aspect==="측면"?"scaleX(-1)":"none"}}/>
          {!community && <button onClick={onOpenDraw} style={{position:"absolute",right:12,top:12,display:"flex",alignItems:"center",gap:5,background:"rgba(0,0,0,.5)",color:"#fff",border:"none",borderRadius:16,padding:"7px 12px",fontSize:12,fontWeight:700}}>
            <svg viewBox="0 0 16 16" width="13" height="13" fill="none" stroke="currentColor" strokeWidth="1.6"><path d="M11 2l3 3-8 8-4 1 1-4z" strokeLinejoin="round"/></svg>그리기 도구</button>}
          <div style={{position:"absolute",top:"50%",left:"50%",transform:"translate(-50%,-50%)",width:52,height:52,borderRadius:"50%",background:"rgba(255,255,255,.22)",backdropFilter:"blur(8px)",display:"flex",alignItems:"center",justifyContent:"center",color:"#fff"}}><Icon name="play" size={22}/></div>
          {/* 배속 (FS: 0.25/0.5/0.75/1/1.5) */}
          <button onClick={cycleSpeed} style={{position:"absolute",right:12,bottom:12,minWidth:56,textAlign:"center",background:"rgba(0,0,0,.55)",color:"#fff",border:"none",borderRadius:14,padding:"6px 11px",fontSize:12,fontWeight:800}}>{speed}배속</button>
        </div>
        {/* 클럽/거리/날짜 */}
        <div style={{padding:"16px 20px 6px"}}>
          <div style={{display:"flex",alignItems:"center",justifyContent:"space-between"}}>
            <span style={{fontSize:17,fontWeight:800}}>{c.club}{c.shot && <span style={{fontSize:12,fontWeight:600,color:"var(--text-sub)",marginLeft:6}}>{c.shot}</span>}</span>
            <span style={{fontSize:20,fontWeight:800,letterSpacing:"-.02em"}}>{c.dist}</span>
          </div>
          <div style={{fontSize:12.5,color:"var(--text-sub)",marginTop:6}}>{c.date||"1월 20일"}</div>
        </div>
        {/* 나의 스윙 정보 */}
        <div style={{padding:"14px 20px 4px"}}>
          <div style={{fontSize:14,fontWeight:800,marginBottom:2}}>나의 스윙 정보</div>
          <div style={{display:"grid",gridTemplateColumns:"repeat(3,1fr)"}}>
            {data.map(([k,v],i)=>(
              <div key={i} style={{textAlign:"center",padding:"16px 4px"}}>
                <div style={{fontSize:12,color:"var(--text-sub)",marginBottom:6}}>{k}</div>
                <div style={{fontSize:15,fontWeight:800,color:"var(--primary)",letterSpacing:"-.01em"}}>{v}</div>
              </div>
            ))}
          </div>
        </div>
        {/* AI 스윙 분석 결과 진입 (나의 스윙 · IP 카메라 매장) */}
        {!community && onOpenAi && (
          <div style={{padding:"14px 20px 0"}}>
            <button onClick={()=>onOpenAi({club:c.club, grade:"NOT BAD", date:c.date||"2026.06.20", store:(c.store||"판교점").split(" ")[0], dist:c.dist})}
              style={{width:"100%",display:"flex",alignItems:"center",gap:12,padding:"14px",borderRadius:12,border:"1px solid var(--line)",background:"linear-gradient(100deg,#EEF4FF 0%,#F0FDF4 100%)",textAlign:"left"}}>
              <span style={{width:38,height:38,borderRadius:10,background:"#fff",display:"flex",alignItems:"center",justifyContent:"center",flexShrink:0}}>
                <svg viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="#3B82F6" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M4 14s1.5-2 4-2 4 2 4 2M12 12s1.5-2 4-2 4 2 4 2"/><circle cx="8" cy="8" r="1.4"/><circle cx="16" cy="8" r="1.4"/><path d="M4 20h16"/></svg>
              </span>
              <div style={{flex:1}}>
                <div style={{fontSize:14,fontWeight:800}}>AI 스윙 분석 결과 보기</div>
                <div style={{fontSize:11.5,color:"var(--text-sub)",marginTop:1}}>6구간 진단 · 풋프린트 · 종합 진단</div>
              </div>
              <Icon name="chev-r" size={15} style={{color:"var(--text-mute)"}}/>
            </button>
          </div>
        )}
        <div style={{padding:"12px 20px 0",display:"flex",gap:6,fontSize:12,color:"var(--text-mute)",lineHeight:1.6}}><span>·</span><span>매장 설정에 따라 옵션 일반 또는 초고속 카메라가 노출됩니다.</span></div>
      </div>
      {/* 하단 */}
      <div style={{position:"absolute",left:0,right:0,bottom:0,padding:"14px 20px 24px",background:"#fff",borderTop:"1px solid var(--line)"}}>
        {community ? (
          <div style={{display:"flex",alignItems:"center",gap:18}}>
            <button onClick={()=>setLiked(v=>!v)} style={{display:"flex",alignItems:"center",gap:6,background:"transparent",fontSize:14,fontWeight:700,color:liked?"var(--danger)":"var(--text-sub)"}}>
              <Icon name={liked?"heart-fill":"heart"} size={20}/>{(24+(liked?1:0))}
            </button>
            <button onClick={()=>setComm(true)} style={{display:"flex",alignItems:"center",gap:6,background:"transparent",fontSize:14,fontWeight:700,color:"var(--text-sub)"}}>
              <svg viewBox="0 0 20 20" width="19" height="19" fill="none" stroke="currentColor" strokeWidth="1.6"><path d="M3 5h14v9H8l-4 3v-3H3z" strokeLinejoin="round"/></svg>3
            </button>
          </div>
        ) : (
          <button className="btn btn-primary" style={{width:"100%"}} onClick={onOpenUpload}>커뮤니티에 올리기</button>
        )}
      </div>
      {menu && (
        <Sheet title="스윙영상" onClose={()=>setMenu(false)}>
          {!community && <SheetItem label="그리기 도구" onClick={()=>{ setMenu(false); onOpenDraw&&onOpenDraw(); }}/>}
          <SheetItem label="영상 저장" onClick={()=>{ setMenu(false); pop("영상을 저장했어요."); }}/>
          <SheetItem label="삭제" onClick={()=>{ setMenu(false); pop("삭제되었어요."); }}/>
        </Sheet>
      )}
      {comm && (
        <Sheet title="댓글 3" onClose={()=>setComm(false)}
          footer={<div style={{display:"flex",gap:8}}>
            <input value={cmtText} onChange={e=>setCmtText(e.target.value)} placeholder="댓글을 입력하세요" style={{flex:1,height:44,border:"1px solid var(--line-strong)",borderRadius:22,padding:"0 16px",fontSize:14,outline:"none"}}/>
            <button onClick={()=>{ if(cmtText.trim()){ setCmtText(""); pop("댓글을 등록했어요."); } }} className="btn btn-primary" style={{width:64,height:44,flexShrink:0}}>등록</button>
          </div>}>
          <div style={{padding:"2px 20px 8px"}}>
            {[["버디사냥꾼","임팩트 자세 정말 좋네요! 👍","2시간 전"],["어프로치장인","팔로우 스루가 부드러워요","5시간 전"],["골든하이머","저도 이 코스에서 연습해봐야겠어요","1일 전"]].map(([n,c,t],i)=>(
              <div key={i} style={{display:"flex",gap:10,padding:"12px 0",borderTop:i?"1px solid var(--line)":"none"}}>
                <div className="avatar" style={{width:34,height:34,fontSize:14,flexShrink:0}}>{n[0]}</div>
                <div style={{flex:1}}>
                  <div style={{display:"flex",alignItems:"center",gap:6}}><span style={{fontSize:13,fontWeight:700}}>{n}</span><span style={{fontSize:11,color:"var(--text-mute)"}}>{t}</span></div>
                  <div style={{fontSize:13.5,color:"var(--text-sub)",marginTop:3,lineHeight:1.5}}>{c}</div>
                </div>
              </div>
            ))}
          </div>
        </Sheet>
      )}
    </div>
  );
}

// 커뮤니티에 올리기
function SwingUpload({ clip, onBack, onDone }){
  const [text, setText] = React.useState("");
  const [toast, setToast] = React.useState(false);
  const submit = ()=>{ setToast(true); window.setTimeout(()=>{ onDone&&onDone(); }, 1100); };
  return (
    <div className="screen">
      <StatusBar/>
      <Appbar title="커뮤니티에 올리기" onBack={onBack}/>
      {toast && <div className="toast"><span>커뮤니티에 등록되었어요.</span></div>}
      <div className="scroll" style={{paddingBottom:100}}>
        <img src="assets/swing-poster.png" alt="" style={{width:"100%",display:"block"}}/>
        <div style={{padding:"20px"}}>
          <div style={{fontSize:13,fontWeight:700,marginBottom:10}}>내용</div>
          <textarea value={text} onChange={e=>setText(e.target.value.slice(0,70))} placeholder="내용을 70자 이내로 입력해주세요." style={{width:"100%",height:96,border:"1px solid var(--line)",borderRadius:10,padding:"12px 14px",fontSize:14,outline:"none",resize:"none",fontFamily:"inherit"}}/>
          <div style={{textAlign:"right",fontSize:11,color:"var(--text-mute)",marginTop:4}}>{text.length}/70자</div>
        </div>
      </div>
      <div style={{position:"absolute",left:0,right:0,bottom:0,padding:"14px 20px 24px",background:"#fff",borderTop:"1px solid var(--line)"}}>
        <button className="btn btn-primary" style={{width:"100%"}} onClick={submit}>등록</button>
      </div>
    </div>
  );
}

// 그리기 도구 (스윙 분석) — 캔버스 드로잉(직선/원형/사각형/각도) + 색상 + undo/redo
function SwingDraw({ onBack }){
  const COLORS = ["#22C55E","#EF4444","#FACC15","#3B82F6","#FFFFFF"];
  const [tool, setTool] = React.useState("직선");    // FS SwingDrawType: Line/Circle/Square/Angle
  const [color, setColor] = React.useState("#22C55E");
  const [shapes, setShapes] = React.useState([]);
  const [redo, setRedo] = React.useState([]);
  const curRef = React.useRef(null);
  const wrapRef = React.useRef(null);
  const canvasRef = React.useRef(null);
  const [playing, setPlaying] = React.useState(false);
  const tools = [["직선","line"],["원형","circle"],["사각형","rect"],["각도","angle"]];

  const drawShape = (ctx, s, w, h)=>{
    ctx.strokeStyle=s.color; ctx.lineWidth=3; ctx.lineCap="round"; ctx.lineJoin="round";
    const x1=s.x1*w, y1=s.y1*h, x2=s.x2*w, y2=s.y2*h;
    if(s.type==="직선"){ ctx.beginPath(); ctx.moveTo(x1,y1); ctx.lineTo(x2,y2); ctx.stroke(); }
    else if(s.type==="사각형"){ ctx.strokeRect(Math.min(x1,x2),Math.min(y1,y2),Math.abs(x2-x1),Math.abs(y2-y1)); }
    else if(s.type==="원형"){ ctx.beginPath(); ctx.ellipse((x1+x2)/2,(y1+y2)/2,Math.abs(x2-x1)/2,Math.abs(y2-y1)/2,0,0,Math.PI*2); ctx.stroke(); }
    else if(s.type==="각도"){ ctx.beginPath(); ctx.moveTo(x1,y2); ctx.lineTo(x1,y1); ctx.lineTo(x2,y1); ctx.stroke();
      const deg=Math.round(Math.atan2(Math.abs(y2-y1),Math.abs(x2-x1)||1)*180/Math.PI);
      ctx.fillStyle=s.color; ctx.font="bold 15px -apple-system,sans-serif"; ctx.fillText(deg+"°", x1+8, (y1+y2)/2); }
  };
  const render = ()=>{ const cv=canvasRef.current; if(!cv) return; const ctx=cv.getContext("2d"); const w=cv.width,h=cv.height;
    ctx.clearRect(0,0,w,h); const all=curRef.current?shapes.concat([curRef.current]):shapes; all.forEach(s=>drawShape(ctx,s,w,h)); };
  React.useEffect(()=>{ const cv=canvasRef.current, wr=wrapRef.current; if(cv&&wr){ if(cv.width!==wr.clientWidth) cv.width=wr.clientWidth; if(cv.height!==wr.clientHeight) cv.height=wr.clientHeight; } render(); });
  const rel = (e)=>{ const r=wrapRef.current.getBoundingClientRect(); const t=(e.touches&&e.touches[0])||e; return {x:(t.clientX-r.left)/r.width, y:(t.clientY-r.top)/r.height}; };
  const down = (e)=>{ const p=rel(e); curRef.current={type:tool,color,x1:p.x,y1:p.y,x2:p.x,y2:p.y}; render(); };
  const move = (e)=>{ if(!curRef.current) return; const p=rel(e); curRef.current={...curRef.current,x2:p.x,y2:p.y}; render(); };
  const up = ()=>{ if(!curRef.current) return; const s=curRef.current; curRef.current=null; setShapes(a=>a.concat([s])); setRedo([]); };
  const undo = ()=> setShapes(a=>{ if(!a.length) return a; setRedo(r=>r.concat([a[a.length-1]])); return a.slice(0,-1); });
  const redoFn = ()=> setRedo(r=>{ if(!r.length) return r; setShapes(a=>a.concat([r[r.length-1]])); return r.slice(0,-1); });
  const toolIcon = (ic,s="currentColor")=>{ switch(ic){
    case "line": return <svg viewBox="0 0 20 20" width="18" height="18" fill="none" stroke={s} strokeWidth="1.6"><path d="M4 16L16 4"/></svg>;
    case "circle": return <svg viewBox="0 0 20 20" width="18" height="18" fill="none" stroke={s} strokeWidth="1.6"><circle cx="10" cy="10" r="7"/></svg>;
    case "rect": return <svg viewBox="0 0 20 20" width="18" height="18" fill="none" stroke={s} strokeWidth="1.6"><rect x="4" y="4" width="12" height="12" rx="1.5"/></svg>;
    case "angle": return <svg viewBox="0 0 20 20" width="18" height="18" fill="none" stroke={s} strokeWidth="1.6"><path d="M4 16h12M4 16L14 6"/></svg>;
  }};
  return (
    <div className="screen" style={{background:"#0B0B0C"}}>
      <StatusBar/>
      <div style={{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"10px 16px",color:"#fff"}}>
        <button onClick={onBack} style={{background:"transparent",color:"#fff",border:"none"}}><Icon name="back" size={22}/></button>
        <div style={{display:"flex",gap:14}}>
          <button onClick={undo} style={{background:"transparent",color:shapes.length?"#fff":"rgba(255,255,255,.35)",border:"none"}}><svg viewBox="0 0 22 22" width="20" height="20" fill="none" stroke="currentColor" strokeWidth="1.7"><path d="M4 9a7 7 0 1 1-1.5 4.5" strokeLinecap="round"/><path d="M4 4v5h5" strokeLinecap="round" strokeLinejoin="round"/></svg></button>
          <button onClick={redoFn} style={{background:"transparent",color:redo.length?"#fff":"rgba(255,255,255,.35)",border:"none"}}><svg viewBox="0 0 22 22" width="20" height="20" fill="none" stroke="currentColor" strokeWidth="1.7"><path d="M18 9a7 7 0 1 0 1.5 4.5" strokeLinecap="round"/><path d="M18 4v5h-5" strokeLinecap="round" strokeLinejoin="round"/></svg></button>
        </div>
      </div>
      <div ref={wrapRef} onPointerDown={down} onPointerMove={move} onPointerUp={up} onPointerLeave={up}
        style={{flex:1,position:"relative",touchAction:"none",overflow:"hidden",userSelect:"none",WebkitUserSelect:"none",cursor:"crosshair"}}>
        <img src="assets/swing-poster.png" alt="" style={{position:"absolute",inset:0,width:"100%",height:"100%",objectFit:"contain"}}/>
        <canvas ref={canvasRef} style={{position:"absolute",inset:0,width:"100%",height:"100%"}}/>
        <span style={{position:"absolute",right:14,bottom:14,fontSize:11,fontWeight:800,color:"#111",background:"#FDE047",padding:"3px 8px",borderRadius:4}}>FRIENDS</span>
      </div>
      {/* 툴바 */}
      <div style={{display:"flex",justifyContent:"space-around",alignItems:"flex-start",padding:"14px 8px 10px",background:"#141416"}}>
        <button onClick={()=>setColor(c=>COLORS[(COLORS.indexOf(c)+1)%COLORS.length])} style={{display:"flex",flexDirection:"column",alignItems:"center",gap:6,background:"transparent",border:"none"}}>
          <span style={{width:30,height:30,borderRadius:"50%",display:"flex",alignItems:"center",justifyContent:"center",border:"2px solid rgba(255,255,255,.25)"}}><span style={{width:16,height:16,borderRadius:"50%",background:color,border:color==="#FFFFFF"?"1px solid #999":"none"}}/></span>
          <span style={{fontSize:11,color:"rgba(255,255,255,.7)"}}>색상</span>
        </button>
        {tools.map(([label,ic])=>{ const on=tool===label; return (
          <button key={label} onClick={()=>setTool(label)} style={{display:"flex",flexDirection:"column",alignItems:"center",gap:6,background:"transparent",border:"none"}}>
            <span style={{width:30,height:30,borderRadius:"50%",display:"flex",alignItems:"center",justifyContent:"center",border:on?"2px solid #22C55E":"2px solid transparent",color:on?"#22C55E":"rgba(255,255,255,.85)"}}>{toolIcon(ic)}</span>
            <span style={{fontSize:11,color:on?"#22C55E":"rgba(255,255,255,.7)",fontWeight:on?700:500}}>{label}</span>
          </button>
        ); })}
      </div>
      {/* 프레임 타임라인 */}
      <div style={{display:"flex",gap:3,padding:"0 12px",background:"#141416"}}>
        {[0,1,2,3,4].map(i=><div key={i} style={{flex:1,aspectRatio:"1",borderRadius:4,overflow:"hidden",border:i===2?"2px solid #22C55E":"none"}}><img src="assets/swing-poster.png" alt="" style={{width:"100%",height:"100%",objectFit:"cover",filter:`hue-rotate(${i*20}deg)`}}/></div>)}
      </div>
      <div style={{display:"flex",alignItems:"center",gap:10,padding:"12px 16px 20px",background:"#141416"}}>
        <button onClick={()=>setPlaying(p=>!p)} style={{background:"transparent",color:"#fff",border:"none"}}>
          {playing
            ? <svg viewBox="0 0 24 24" width="18" height="18" fill="currentColor"><rect x="6" y="5" width="4" height="14" rx="1"/><rect x="14" y="5" width="4" height="14" rx="1"/></svg>
            : <Icon name="play" size={18}/>}
        </button>
        <div style={{flex:1,height:3,borderRadius:2,background:"rgba(255,255,255,.2)",position:"relative"}}><div style={{position:"absolute",left:0,top:0,bottom:0,width:playing?"70%":"40%",background:"#22C55E",borderRadius:2,transition:"width .4s"}}/></div>
      </div>
    </div>
  );
}

const GRADE_C = {S:"#22C55E",A:"#374151",B:"#9CA3AF",C:"#F87171"};

// 클럽 분류 (FS TRClubType 기준) — 이미지/목표적중률 형태 결정
const clubCategory = (name="")=>{
  if(/드라이버/.test(name)) return "driver";
  if(/우드/.test(name)) return "wood";
  if(/하이브리드/.test(name)) return "hybrid";
  if(/아이언/.test(name)) return "iron";
  if(/^(PW|GW|SW|LW|AW)$/.test(name.trim())) return "wedge";
  return "driver";
};
// 클럽 이미지: 드라이버 / 우드·하이브리드=hybrid / 아이언·웨지=iron
const clubImgType = (name)=>{ const c=clubCategory(name); return c==="driver"?"driver":(c==="wood"||c==="hybrid")?"hybrid":"iron"; };
// 목표 적중률 형태: 아이언·웨지=과녁(동심원) / 그 외=U 코리도 (Figma)
const isBullseye = (name)=> ["iron","wedge"].includes(clubCategory(name));
// 클럽 선택 바텀시트 그룹
const CLUB_GROUPS = [
  {g:"우드", items:["드라이버","3번 우드","5번 우드","7번 우드"]},
  {g:"하이브리드", items:["3번 하이브리드","4번 하이브리드","5번 하이브리드","7번 하이브리드"]},
  {g:"아이언", items:["3번 아이언","4번 아이언","5번 아이언","6번 아이언","7번 아이언","8번 아이언","9번 아이언"]},
  {g:"웨지", items:["PW","GW","SW","LW","AW"]},
];

// 공용 바텀시트 (footer = 하단 고정 영역)
function Sheet({ title, onClose, children, footer }){
  return (
    <div onClick={onClose} style={{position:"absolute",inset:0,background:"rgba(0,0,0,.4)",zIndex:40,display:"flex",alignItems:"flex-end"}}>
      <div onClick={e=>e.stopPropagation()} style={{width:"100%",maxHeight:"82%",display:"flex",flexDirection:"column",background:"#fff",borderRadius:"18px 18px 0 0"}}>
        <div style={{width:40,height:4,borderRadius:2,background:"var(--line-strong)",margin:"8px auto 4px",flexShrink:0}}/>
        {title && (
          <div style={{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"8px 20px 12px",flexShrink:0}}>
            <span style={{fontSize:16,fontWeight:800}}>{title}</span>
            <button onClick={onClose} style={{background:"transparent",border:"none",lineHeight:0,padding:2}}><Icon name="x" size={20} style={{color:"var(--text-sub)"}}/></button>
          </div>
        )}
        <div style={{overflowY:"auto",padding:"0 0 8px"}}>{children}</div>
        {footer && <div style={{padding:"12px 20px 22px",flexShrink:0}}>{footer}</div>}
      </div>
    </div>
  );
}
// 필터 시트 그룹 + 칩
function FilterGroup({ title, children }){
  return (
    <div style={{padding:"18px 20px 4px"}}>
      <div style={{fontSize:15,fontWeight:800,marginBottom:12}}>{title}</div>
      <div style={{display:"flex",flexWrap:"wrap",gap:8}}>{children}</div>
    </div>
  );
}
function FChip({ label, on, onClick }){
  return <button onClick={onClick} style={{fontSize:13,fontWeight:on?700:600,padding:"10px 16px",borderRadius:22,border:"1px solid "+(on?"var(--primary)":"var(--line-strong)"),background:on?"var(--primary-tint)":"#fff",color:on?"var(--primary)":"var(--text-sub)"}}>{label}</button>;
}
// 시트 항목 (선택 시 체크)
function SheetItem({ label, on, onClick, sub }){
  return (
    <button onClick={onClick} style={{display:"flex",alignItems:"center",justifyContent:"space-between",width:"100%",padding:"14px 20px",background:"transparent",border:"none",textAlign:"left"}}>
      <span style={{fontSize:15,fontWeight:on?800:500,color:on?"var(--text)":"var(--text-sub)"}}>{label}{sub && <span style={{fontSize:12,color:"var(--text-mute)",marginLeft:6,fontWeight:500}}>{sub}</span>}</span>
      {on && <Icon name="check" size={18} style={{color:"var(--primary)"}}/>}
    </button>
  );
}

// 클럽 헤드 이미지 (드라이버 / 하이브리드=우드+하이브리드 / 아이언=아이언+웨지) — FS 프로덕션 에셋
function ClubHead({ type="driver" }){
  return <img src={`assets/club-${type}.png`} alt="" style={{width:104,height:78,objectFit:"contain",flexShrink:0}}/>;
}

// 목표 적중률 다이어그램 — 아이언·웨지=과녁 동심원 / 그 외=U 코리도
function TargetDiagram({ club, rates }){
  const bull = isBullseye(club);
  const labels = (
    <>
      <div style={{position:"absolute",top:bull?"40%":"30%",left:0,right:0,textAlign:"center",fontSize:24,fontWeight:800,color:"var(--primary)"}}>{rates[0]}</div>
      <div style={{position:"absolute",top:bull?"56%":"52%",left:0,right:0,textAlign:"center",fontSize:15,fontWeight:700,color:"var(--text-sub)"}}>{rates[1]}</div>
      <div style={{position:"absolute",top:bull?"70%":"70%",left:0,right:0,textAlign:"center",fontSize:15,fontWeight:700,color:"var(--text-sub)"}}>{rates[2]}</div>
      <div style={{position:"absolute",top:bull?"84%":"86%",left:0,right:0,textAlign:"center",fontSize:16,fontWeight:800}}>{rates[3]}</div>
    </>
  );
  return (
    <div style={{padding:"24px 20px 16px",display:"flex",justifyContent:"center"}}>
      <div style={{position:"relative",width:236,height:250}}>
        {bull ? (
          <svg viewBox="0 0 236 250" width="236" height="250">
            <line x1="118" y1="10" x2="118" y2="240" stroke="var(--line)" strokeWidth="1" strokeDasharray="4 5"/>
            <line x1="12" y1="125" x2="224" y2="125" stroke="var(--line)" strokeWidth="1" strokeDasharray="4 5"/>
            <circle cx="118" cy="125" r="110" fill="#F3F4F6"/>
            <circle cx="118" cy="125" r="74" fill="#EAF9F0"/>
            <circle cx="118" cy="125" r="40" fill="#BBF7D0"/>
          </svg>
        ) : (
          <svg viewBox="0 0 236 250" width="236" height="250">
            <path d="M30 10 L30 168 Q30 236 118 236 Q206 236 206 168 L206 10" fill="none" stroke="#EDEFF2" strokeWidth="20" strokeLinecap="round"/>
            <path d="M88 10 L88 166 Q88 198 118 198 Q148 198 148 166 L148 10 Z" fill="#D6F5E3"/>
          </svg>
        )}
        {labels}
      </div>
    </div>
  );
}

// 클럽 상세 (샷분포도 / 목표 적중률 + 나의 샷 데이터)
function SwingDetail({ onBack, clip, onOpenAll }){
  const [tab, setTab] = React.useState("dist");
  const club = clip?.club || "하이브리드";
  const dist = clip?.dist || "275.5m";
  const grade = clip?.grade || "A";
  // 엣지: 우드는 백스핀 미측정 → "데이터 준비중" (FS 값 null 처리 · Figma cm06)
  const backSpin = clubCategory(club)==="wood" ? null : "2,331rpm";
  const shotData = [["구질","푸시슬라이스"],["비거리","215.8m"],["캐리","71.2m"],["볼스피드","29.5m/s"],["발사각","25.4°"],["백스핀",backSpin],["최고 높이","13.2m"],["방향각","5.4°"],["사이드 스핀","1,231rpm"]];
  return (
    <div className="screen">
      <StatusBar/>
      <Appbar title={clip?.d || "4월 2일"} onBack={onBack}/>
      <div className="scroll" style={{paddingBottom:20}}>
        {/* 클럽 헤더 */}
        <div style={{padding:"14px 20px 20px",display:"flex",alignItems:"center",gap:12,background:"var(--bg-soft)"}}>
          <div style={{flex:1}}>
            <div style={{fontSize:14,fontWeight:600,color:"var(--text-sub)"}}>{club}</div>
            <div style={{display:"flex",alignItems:"center",gap:8,marginTop:5}}>
              <div style={{fontSize:24,fontWeight:800,letterSpacing:"-.02em"}}>{dist}</div>
              <div style={{width:26,height:26,borderRadius:"50%",background:GRADE_C[grade]||"#374151",color:"#fff",display:"flex",alignItems:"center",justifyContent:"center",fontSize:12,fontWeight:800}}>{grade}</div>
            </div>
          </div>
          <ClubHead type={clubImgType(club)}/>
        </div>

        <div style={{padding:"0 20px",borderBottom:"1px solid var(--line)",display:"flex",gap:20}}>
          {[["dist","샷분포도"],["goal","목표 적중률"]].map(([k,v])=>(
            <button key={k} onClick={()=>setTab(k)} style={{padding:"14px 0",fontSize:14,fontWeight:700,color:tab===k?"var(--text)":"var(--text-mute)",borderBottom:tab===k?"2px solid var(--text)":"2px solid transparent",marginBottom:-1,background:"transparent"}}>{v}</button>
          ))}
        </div>

        {tab==="dist" ? (
          <div style={{padding:"24px 20px 16px"}}>
            <div style={{display:"flex",justifyContent:"space-between",marginBottom:6,fontSize:11,color:"var(--text-sub)"}}>
              <div>앞, 뒤 차이<br/><b style={{color:"var(--text)",fontSize:14}}>5.8m</b></div>
              <div style={{textAlign:"right"}}>좌, 우 차이<br/><b style={{color:"var(--text)",fontSize:14}}>17.8m</b></div>
            </div>
            <div style={{position:"relative",width:"100%",aspectRatio:"1",margin:"10px 0"}}>
              <div style={{position:"absolute",top:"50%",left:0,right:0,height:1,borderTop:"1px dashed var(--line-strong)"}}/>
              <div style={{position:"absolute",left:"50%",top:0,bottom:0,width:1,borderLeft:"1px dashed var(--line-strong)"}}/>
              <div style={{position:"absolute",inset:"25% 25%",borderRadius:"50%",background:"rgba(34,197,94,.2)"}}/>
              {[[45,45],[55,40],[60,50],[50,60],[52,55],[40,50],[48,42],[58,48],[45,55],[50,50]].map(([x,y],i)=>(
                <div key={i} style={{position:"absolute",left:`${x}%`,top:`${y}%`,width:8,height:8,borderRadius:"50%",background:"#15803D",transform:"translate(-50%,-50%)"}}/>
              ))}
            </div>
          </div>
        ) : (
          <TargetDiagram club={club} rates={["80%","5%","5%","10%"]}/>
        )}

        <div style={{height:10,background:"var(--bg-soft)"}}/>
        <div style={{padding:"20px 20px 26px"}}>
          <div style={{fontSize:16,fontWeight:800,letterSpacing:"-.02em",marginBottom:6}}>나의 샷 데이터</div>
          <div style={{display:"grid",gridTemplateColumns:"repeat(3,1fr)"}}>
            {shotData.map(([k,v],i)=>(
              <div key={i} style={{display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",gap:8,padding:"20px 4px"}}>
                <div style={{fontSize:12.5,color:"var(--text-sub)"}}>{k}</div>
                {v==null
                  ? <div style={{fontSize:13,fontWeight:600,color:"var(--text-mute)"}}>데이터 준비중</div>
                  : <div style={{fontSize:16,fontWeight:800,color:"var(--primary)",letterSpacing:"-.01em"}}>{v}</div>}
              </div>
            ))}
          </div>
        </div>
        <div style={{padding:"20px"}}>
          <button className="btn btn-outline" style={{width:"100%"}} onClick={onOpenAll}>모든 기록 보기</button>
        </div>
      </div>
    </div>
  );
}

// 클럽 측정 (기록 / 클럽별 통계) — 기록 없으면 가상 스코어 노출
function ClubMeasure({ onNav, onBack, onOpenDetail }){
  const [tab, setTab] = React.useState("log");
  const [hasData, setHasData] = React.useState(true); // 데모: 측정 기록 유무
  // 클럽별 통계 필터
  const [selClub, setSelClub] = React.useState("드라이버");
  const [period, setPeriod] = React.useState("최근 5회");
  const [visited, setVisited] = React.useState(false);
  const [sheet, setSheet] = React.useState(null); // "club" | "period"
  const PERIODS = ["최근 5회","최근 10회","최근 20회","전체"];

  const months = [
    {m:"2024년 4월", n:3, items:[
      {d:"4월 16일", club:"드라이버", avg:"5구 평균", dist:"201.3m", grade:"B"},
      {d:"4월 8일", club:"3번 우드", avg:"10구 평균", dist:"168.5m", grade:"C"},
      {d:"4월 2일", club:"6번 아이언", avg:"6구 평균", dist:"130.5m", grade:"A"},
    ]},
    {m:"2024년 3월", n:3, items:[
      {d:"3월 23일", club:"7번 아이언", avg:"10구 평균", dist:"110.9m", grade:"S"},
      {d:"3월 12일", club:"9번 아이언", avg:"6구 평균", dist:"95.5m", grade:"A"},
      {d:"3월 3일", club:"4번 하이브리드", avg:"5구 평균", dist:"195.5m", grade:"C"},
    ]},
  ];
  const stats = [["220.2","m","비거리",true],["222.7","m","캐리"],["90.4","m/s","볼스피드"],["90.4","m","최고높이"],["60.0","°","발사각"],["20.9","°","방향각"],["3536","rpm","백스핀"],["1022","rpm","사이드스핀"]];
  const chart = [
    {x:"12.1", dist:236, dl:"236.1m", rate:30, rl:"30%"},
    {x:"12.2", dist:156, dl:"156.1m", rate:0,  rl:"0%", rmin:true},
    {x:"12.17",dist:96,  dl:"96.1m",  rate:25, rl:"25%", dmin:true},
    {x:"1.8",  dist:99,  dl:"98.7m",  rate:20, rl:"20%"},
    {x:"1.21", dist:271, dl:"271.1m", rate:35, rl:"35%", dmax:true},
    {x:"2.1",  dist:251, dl:"250.9m", rate:10, rl:"10%"},
    {x:"2.12", dist:96,  dl:"96.3m",  rate:60, rl:"60%", rmax:true},
  ];
  const CW=50, maxD=280, baseY=150, topY=46;
  const bx = i => 26 + i*CW;
  const by = d => baseY - (d/maxD)*100;          // bar top
  const ly = r => topY + (60-r)/60*70;           // line y (rate 0~60 → topY..topY+70)
  const linePts = chart.map((c,i)=>`${bx(i)},${ly(c.rate)}`).join(" ");

  return (
    <div className="screen">
      <StatusBar/>
      <Appbar title="클럽 측정" onBack={onBack||(()=>onNav&&onNav("home"))}/>
      <div className="scroll" style={{paddingBottom: onNav?100:30}}>
        <div style={{padding:"0 20px",borderBottom:"1px solid var(--line)",display:"flex",gap:24}}>
          {[["log","기록"],["stat","클럽별 통계"]].map(([k,v])=>(
            <button key={k} onClick={()=>setTab(k)} style={{padding:"15px 0",fontSize:15,fontWeight:700,color:tab===k?"var(--text)":"var(--text-mute)",borderBottom:tab===k?"2px solid var(--text)":"2px solid transparent",marginBottom:-1,background:"transparent"}}>{v}</button>
          ))}
        </div>

        {/* 데모 토글 */}
        <div style={{display:"flex",justifyContent:"flex-end",padding:"8px 16px 0"}}>
          <button onClick={()=>setHasData(v=>!v)} style={{fontSize:9,color:"var(--text-mute)",background:"transparent",border:"1px dashed var(--line)",borderRadius:4,padding:"3px 6px",fontWeight:600}}>데모: 기록 {hasData?"없음":"있음"}</button>
        </div>

        {!hasData && (
          <div style={{padding:"10px 20px 4px"}}>
            <div style={{fontSize:19,fontWeight:800,lineHeight:1.35,letterSpacing:"-.02em"}}>{tab==="log" ? <>클럽 측정을 하면<br/>자세한 샷 정보를 확인할 수 있어요.</> : <>샷 변화 추이를 그래프를 통해<br/>한눈에 확인할 수 있어요.</>}</div>
            <div style={{fontSize:13,color:"var(--text-mute)",marginTop:8}}>아래 데이터는 가상 스코어입니다.</div>
          </div>
        )}

        <div style={{opacity:hasData?1:.55, pointerEvents:hasData?"auto":"none"}}>
          {tab==="log" ? (
            months.map((mo,mi)=>(
              <div key={mi}>
                <div style={{display:"flex",justifyContent:"space-between",padding:"16px 20px 8px"}}>
                  <span style={{fontSize:14,fontWeight:800}}>{mo.m}</span>
                  <span style={{fontSize:13,color:"var(--text-sub)",fontWeight:600}}>{mo.n}회</span>
                </div>
                <div style={{padding:"0 20px",display:"flex",flexDirection:"column",gap:10}}>
                  {mo.items.map((it,i)=>(
                    <button key={i} onClick={()=>onOpenDetail&&onOpenDetail(it)} style={{background:"var(--bg-soft)",borderRadius:12,padding:"16px",width:"100%",textAlign:"left",border:"none"}}>
                      <div style={{display:"flex",justifyContent:"space-between",alignItems:"baseline",marginBottom:8}}>
                        <span style={{fontSize:13,color:"var(--text-sub)"}}>{it.d}</span>
                        <span style={{fontSize:12,color:"var(--text-sub)"}}>{it.avg}</span>
                      </div>
                      <div style={{display:"flex",justifyContent:"space-between",alignItems:"center"}}>
                        <span style={{fontSize:17,fontWeight:800}}>{it.club}</span>
                        <span style={{display:"flex",alignItems:"center",gap:10}}>
                          <span style={{fontSize:24,fontWeight:800,letterSpacing:"-.02em"}}>{hasData?it.dist:it.dist}</span>
                          <span style={{width:34,height:34,borderRadius:"50%",background:hasData?(GRADE_C[it.grade]):"#22C55E",color:"#fff",display:"flex",alignItems:"center",justifyContent:"center",fontSize:14,fontWeight:800}}>{hasData?it.grade:"S"}</span>
                        </span>
                      </div>
                    </button>
                  ))}
                </div>
              </div>
            ))
          ) : (
            <div style={{padding:"14px 20px 0"}}>
              <div style={{display:"flex",gap:8,marginBottom:16,overflowX:"auto",scrollbarWidth:"none"}}>
                <button onClick={()=>setSheet("club")} style={{flexShrink:0,display:"flex",alignItems:"center",gap:5,fontSize:14,fontWeight:700,padding:"9px 15px",borderRadius:20,background:"#1A1C1F",color:"#fff",border:"none"}}>{selClub} <Icon name="chev-d" size={13}/></button>
                <button onClick={()=>setSheet("period")} style={{flexShrink:0,display:"flex",alignItems:"center",gap:5,fontSize:14,fontWeight:600,padding:"9px 15px",borderRadius:20,background:"#fff",color:"var(--text-sub)",border:"1px solid var(--line-strong)"}}>{period} <Icon name="chev-d" size={13}/></button>
                <button onClick={()=>setVisited(v=>!v)} style={{flexShrink:0,fontSize:14,fontWeight:visited?700:600,padding:"9px 15px",borderRadius:20,background:visited?"var(--primary-tint)":"#fff",color:visited?"var(--primary)":"var(--text-sub)",border:"1px solid "+(visited?"var(--primary)":"var(--line-strong)")}}>방문한</button>
              </div>
              <div style={{display:"grid",gridTemplateColumns:"1fr 1fr 1fr 1fr",gap:10}}>
                {stats.map(([v,u,k,hi],i)=>(
                  <div key={i} style={{borderRadius:12,padding:"16px 6px",textAlign:"center",background:hi?"var(--primary)":"var(--bg-soft)"}}>
                    <div style={{fontSize:17,fontWeight:800,letterSpacing:"-.02em",color:hi?"#fff":"var(--text)"}}>{v}<span style={{fontSize:10,fontWeight:600,marginLeft:1}}>{u}</span></div>
                    <div style={{fontSize:11,marginTop:6,color:hi?"rgba(255,255,255,.85)":"var(--text-sub)"}}>{k}</div>
                  </div>
                ))}
              </div>
              <div style={{display:"flex",alignItems:"center",justifyContent:"space-between",margin:"18px 0 4px"}}>
                <div style={{display:"flex",gap:14,fontSize:12,color:"var(--text-sub)"}}>
                  <span style={{display:"flex",alignItems:"center",gap:5}}><span style={{width:14,height:3,borderRadius:2,background:"#22C55E"}}/>비거리</span>
                  <span style={{display:"flex",alignItems:"center",gap:5}}><span style={{width:14,height:3,borderRadius:2,background:"#9CA3AF"}}/>타겟안착률</span>
                </div>
                <span style={{fontSize:12,color:"var(--text-mute)"}}>누적 14회 평균</span>
              </div>
              <svg viewBox="0 0 360 200" width="100%" style={{overflow:"visible"}}>
                {chart.map((c,i)=>(<rect key={i} x={bx(i)-11} y={by(c.dist)} width="22" height={baseY-by(c.dist)} rx="5" fill={c.dmax?"#22C55E":"#BBF7D0"}/>))}
                {chart.map((c,i)=>(<text key={"d"+i} x={bx(i)} y={by(c.dist)-6} fontSize="9" fontWeight="700" fill={c.dmax?"#16A34A":"var(--text-sub)"} textAnchor="middle">{c.dl}</text>))}
                {chart.map((c,i)=> (c.dmax||c.dmin) ? <g key={"db"+i}><rect x={bx(i)-14} y={by(c.dist)-30} width="28" height="14" rx="4" fill={c.dmax?"#22C55E":"#6B7280"}/><text x={bx(i)} y={by(c.dist)-20} fontSize="8.5" fontWeight="700" fill="#fff" textAnchor="middle">{c.dmax?"최고":"최소"}</text></g> : null)}
                <polyline points={linePts} fill="none" stroke="#9CA3AF" strokeWidth="1.6"/>
                {chart.map((c,i)=>(<circle key={"c"+i} cx={bx(i)} cy={ly(c.rate)} r="3.5" fill="#fff" stroke={c.rmax?"#22C55E":"#9CA3AF"} strokeWidth="1.8"/>))}
                {chart.map((c,i)=>(<text key={"r"+i} x={bx(i)} y={ly(c.rate)-8} fontSize="9" fontWeight="700" fill={c.rmax?"#16A34A":"var(--text)"} textAnchor="middle">{c.rl}</text>))}
                {chart.map((c,i)=> (c.rmax||c.rmin) ? <g key={"rb"+i}><rect x={bx(i)-14} y={ly(c.rate)-26} width="28" height="13" rx="4" fill={c.rmax?"#22C55E":"#6B7280"}/><text x={bx(i)} y={ly(c.rate)-16.5} fontSize="8" fontWeight="700" fill="#fff" textAnchor="middle">{c.rmax?"최고":"최소"}</text></g> : null)}
                {chart.map((c,i)=>(<text key={"x"+i} x={bx(i)} y={172} fontSize="9" fill="var(--text-mute)" textAnchor="middle">{c.x}</text>))}
              </svg>
            </div>
          )}
        </div>
      </div>

      {/* 클럽 선택 바텀시트 */}
      {sheet==="club" && (
        <Sheet title="클럽 선택" onClose={()=>setSheet(null)}>
          {CLUB_GROUPS.map((grp,gi)=>(
            <div key={gi}>
              <div style={{fontSize:12,fontWeight:700,color:"var(--text-mute)",padding:"10px 20px 2px"}}>{grp.g}</div>
              {grp.items.map(it=>(
                <SheetItem key={it} label={it} on={selClub===it} onClick={()=>{setSelClub(it); setSheet(null);}}/>
              ))}
            </div>
          ))}
        </Sheet>
      )}
      {/* 기간 선택 바텀시트 */}
      {sheet==="period" && (
        <Sheet title="기간" onClose={()=>setSheet(null)}>
          {PERIODS.map(p=>(
            <SheetItem key={p} label={p} on={period===p} onClick={()=>{setPeriod(p); setSheet(null);}}/>
          ))}
        </Sheet>
      )}
      {onNav && <TabBar current="swing" onNav={onNav}/>}
    </div>
  );
}

// 모든 기록 보기 — 드라이버 샷 데이터 (내 기록 표 / 평균기록 비교)
function ClubShotData({ onBack, club="드라이버" }){
  const [tab, setTab] = React.useState("mine");
  const [level, setLevel] = React.useState("더블보기 플레이어");
  const [levelSheet, setLevelSheet] = React.useState(false);
  const levels = ["초보","더블보기 플레이어","보기 플레이어","싱글 플레이어","PGA 선수급"];
  const labels = [["구질",""],["비거리","(m)"],["캐리","(m)"],["볼스피드","(m/s)"],["최고높이","(m)"],["발사각","(°)"],["방향각","(°)"],["백스핀","(rpm)"],["사이드스핀","(rpm)"]];
  const shots = [
    {q:"스트레이트", v:["194.4","60.7","27.4","14.5","-1.5","1534","-900","210.3"]},
    {q:"푸시 슬라이스", v:["42.7","26.7","3.2","11.7","-4.3","2839","-1002","215.6"]},
    {q:"페이드", v:["194.0","60.2","27.1","14.2","3.4","1530","-900","93.4"]},
    {q:"드로우", v:["188.2","58.1","26.5","13.8","2.1","1490","-880","102.5"]},
    {q:"훅", v:["176.5","55.0","25.2","13.1","-2.8","1602","-940","188.7"]},
  ];
  const cmp = [
    {k:"비거리",   me:"192.4", mu:"m",   diff:"+2.0", them:"192.4", tu:"m"},
    {k:"볼스피드", me:"27.9",  mu:"m/s", diff:"-0.6", them:"56.8",  tu:"m/s"},
    {k:"발사각",   me:"14.3",  mu:"°",   diff:"-22",  them:"13.6",  tu:"°"},
    {k:"백스핀",   me:"3654",  mu:"rpm", diff:"-120", them:"3500",  tu:"rpm"},
  ];
  return (
    <div className="screen">
      <StatusBar/>
      <Appbar title={`${club} 샷 데이터`} onBack={onBack}/>
      <div className="scroll" style={{paddingBottom:30}}>
        <div style={{padding:"0 20px",borderBottom:"1px solid var(--line)",display:"flex",gap:24}}>
          {[["mine","내 기록"],["compare","평균기록 비교"]].map(([k,v])=>(
            <button key={k} onClick={()=>setTab(k)} style={{padding:"15px 0",fontSize:15,fontWeight:700,color:tab===k?"var(--text)":"var(--text-mute)",borderBottom:tab===k?"2px solid var(--text)":"2px solid transparent",marginBottom:-1,background:"transparent"}}>{v}</button>
          ))}
        </div>

        {tab==="mine" ? (
          <div style={{display:"flex"}}>
            <div style={{flexShrink:0,borderRight:"1px solid var(--line)"}}>
              {labels.map(([l,u],r)=>(
                <div key={r} style={{padding:"16px 16px",height:r===0?54:60,display:"flex",alignItems:"center",background:r%2?"#fff":"var(--bg-soft)"}}>
                  <span style={{fontSize:r===0?14:13.5,fontWeight:r===0?700:800}}>{l}<span style={{fontSize:10,color:"var(--text-mute)",marginLeft:2,fontWeight:600}}>{u}</span></span>
                </div>
              ))}
            </div>
            <div style={{overflowX:"auto",flex:1,scrollbarWidth:"none"}}>
              <div style={{display:"flex"}}>
                {shots.map((s,ci)=>(
                  <div key={ci} style={{minWidth:108,flexShrink:0}}>
                    {[s.q, ...s.v].map((val,r)=>(
                      <div key={r} style={{padding:"16px 14px",height:r===0?54:60,display:"flex",alignItems:"center",justifyContent:"flex-end",background:r%2?"#fff":"var(--bg-soft)"}}>
                        <span style={{fontSize:r===0?13.5:15,fontWeight:r===0?700:500,color:r===0?"var(--text-sub)":"var(--text-sub)"}}>{val}</span>
                      </div>
                    ))}
                  </div>
                ))}
              </div>
            </div>
          </div>
        ) : (
          <div style={{padding:"24px 20px"}}>
            <div style={{display:"flex",alignItems:"center",justifyContent:"center",gap:14,marginBottom:24}}>
              <div style={{textAlign:"center"}}>
                <div style={{width:64,height:64,borderRadius:"50%",background:"linear-gradient(180deg,#fde68a,#fbbf24)",margin:"0 auto 8px"}}/>
                <div style={{fontSize:14,fontWeight:700}}>수내이덕화</div>
              </div>
              <div style={{fontSize:18,fontWeight:800,color:"var(--text-mute)"}}>VS</div>
              <div style={{textAlign:"center"}}>
                <div style={{width:64,height:64,borderRadius:"50%",background:"#E5E7EB",margin:"0 auto 8px",display:"flex",alignItems:"center",justifyContent:"center",fontSize:26,color:"#fff"}}>👤</div>
                <button onClick={()=>setLevelSheet(true)} style={{display:"flex",alignItems:"center",gap:3,fontSize:14,fontWeight:700,background:"transparent",border:"none"}}>{level} <Icon name="chev-d" size={13}/></button>
              </div>
            </div>
            <div className="card" style={{padding:0,overflow:"hidden"}}>
              {cmp.map((r,i)=>{
                const up = r.diff.startsWith("+");
                return (
                  <div key={i} style={{display:"grid",gridTemplateColumns:"1fr 1fr 1fr",alignItems:"center",padding:"18px 12px",borderBottom:i<cmp.length-1?"1px solid var(--line)":"0"}}>
                    <div style={{textAlign:"left",fontSize:20,fontWeight:800,color:"var(--text-sub)"}}>{r.me}<span style={{fontSize:12,fontWeight:600}}>{r.mu}</span></div>
                    <div style={{textAlign:"center"}}>
                      <div style={{fontSize:14,fontWeight:800}}>{r.k}</div>
                      <div style={{fontSize:11,fontWeight:700,color:up?"var(--primary)":"var(--danger)",marginTop:2}}>평균보다 {r.diff}</div>
                    </div>
                    <div style={{textAlign:"right",fontSize:20,fontWeight:800,color:"var(--text-sub)"}}>{r.them}<span style={{fontSize:12,fontWeight:600}}>{r.tu}</span></div>
                  </div>
                );
              })}
            </div>
          </div>
        )}
      </div>

      {/* 비교 레벨 선택 바텀시트 */}
      {levelSheet && (
        <Sheet title="비교 레벨" onClose={()=>setLevelSheet(false)}>
          {levels.map(l=>(
            <SheetItem key={l} label={l} on={level===l} onClick={()=>{setLevel(l); setLevelSheet(false);}}/>
          ))}
        </Sheet>
      )}
    </div>
  );
}

// 예약 내역 (메뉴에서 진입) — 리스트형 + 상세
// 예약 상태(정책 §8 7단계) 색/구분
const BK_STATUS_COLOR = (s)=>
  (s==="예약완료"||s==="체크인"||s==="이용중") ? "var(--primary)"
  : s==="현장결제 대기" ? "#F59E0B"
  : (s==="노쇼"||s==="취소") ? "var(--danger)"
  : "var(--text-mute)";
const BK_UPCOMING = (s)=> s==="예약완료" || s==="현장결제 대기" || s==="체크인" || s==="이용중";
// 유형 → 카테고리(필터) / 아이콘
const BK_CAT = (t)=> t==="스크린" ? "스크린" : "아카데미"; // 레슨·타석 = 아카데미
const BkTypeIcon = ({ t, size=13 })=> t==="스크린"
  ? <svg viewBox="0 0 16 16" width={size} height={size} fill="none" stroke="currentColor" strokeWidth="1.4"><rect x="2" y="3" width="12" height="8" rx="1"/><path d="M6 14h4M8 11v3"/></svg>
  : t==="레슨"
  ? <svg viewBox="0 0 16 16" width={size} height={size} fill="none" stroke="currentColor" strokeWidth="1.4"><circle cx="8" cy="5" r="2.4"/><path d="M3 14c0-2.8 2.2-4.5 5-4.5s5 1.7 5 4.5"/></svg>
  : <svg viewBox="0 0 16 16" width={size} height={size} fill="none" stroke="currentColor" strokeWidth="1.4"><path d="M5 2v8M5 2l6 2-6 2"/><circle cx="10" cy="13" r="2"/></svg>;
const bkValue = (r)=> r.type==="스크린" ? r.people : r.type==="레슨" ? r.pro : r.bay;
// 예약 데이터 — 오늘(세션 기준) 상대날짜로 생성해 실제 달력에 표기. 상태 정책 7단계 전수
const bkMk = (off)=>{ const t=new Date(); t.setHours(0,0,0,0); t.setDate(t.getDate()+off);
  const m=t.getMonth()+1, day=t.getDate();
  return { y:t.getFullYear(), m, day, d:`${m}월 ${day}일`, date:`${t.getFullYear()}.${String(m).padStart(2,"0")}.${String(day).padStart(2,"0")}` }; };
const BK_ROWS = [
  {...bkMk(5),   t:"오후 11시 15분", time:"23:15 - 익일 01:00 (45분)", type:"레슨",   status:"예약완료",     pro:"박은선 프로", store:"프렌즈 아카데미 판교 파미어스몰", voucher:{name:"2024 가나다 정기 레슨권", dur:"20분 (1회)", left:"1회", total:"10회"}},
  {...bkMk(2),   t:"오후 7시",       time:"19:00 - 21:00 (120분)", type:"스크린", status:"현장결제 대기", people:"2명",     store:"탄천종합운동장", pay:"현장 결제"},
  {...bkMk(0),   t:"오후 2시",       time:"14:00 - 16:00 (120분)", type:"타석",   status:"이용중",       bay:"12번 타석",   store:"프렌즈 아카데미 판교점", voucher:{name:"트레이닝 60분권", dur:"120분", left:"14회", total:"20회"}},
  {...bkMk(-3),  t:"오후 9시 30분",  time:"21:30 - 22:30 (60분)",  type:"타석",   status:"이용완료",     bay:"5번 타석",    store:"프렌즈 스크린 판교점", voucher:{name:"트레이닝 60분권", dur:"60분", left:"13회", total:"20회"}},
  {...bkMk(-6),  t:"오전 11시",      time:"11:00 - 11:20 (20분)",  type:"레슨",   status:"노쇼",         pro:"로엘이 프로", store:"프렌즈 아카데미 강남점", voucher:{name:"일일 레슨권", dur:"20분 (1회)", left:"7회", total:"10회"}},
  {...bkMk(-10), t:"오후 8시",       time:"20:00 - 22:00 (120분)", type:"스크린", status:"취소",         people:"4명",     store:"프렌즈 스크린 판교점", pay:"VX머니 결제"},
  {...bkMk(-34), t:"오후 6시",       time:"18:00 - 20:00 (120분)", type:"타석",   status:"이용완료",     bay:"8번 타석",    store:"프렌즈 스크린 판교점", voucher:{name:"트레이닝 60분권", dur:"120분", left:"12회", total:"20회"}},
  {...bkMk(7),   t:"오전 9시",       time:"09:00 - 11:00 (120분)", type:"타석",   status:"예약완료",     bay:"3번 타석",    store:"프렌즈 스크린 판교점", voucher:{name:"트레이닝 60분권", dur:"120분", left:"11회", total:"20회"}},
  {...bkMk(4),   t:"오후 4시",       time:"16:00 - 16:20 (20분)",  type:"레슨",   status:"예약완료",     pro:"한진선 프로", store:"프렌즈 아카데미 판교점", voucher:{name:"일일 레슨권", dur:"20분 (1회)", left:"5회", total:"10회"}},
  {...bkMk(1),   t:"오후 1시",       time:"13:00 - 15:00 (120분)", type:"스크린", status:"예약완료",     people:"3명",     store:"프렌즈 스크린 강남점", pay:"VX머니 결제"},
  {...bkMk(-1),  t:"오전 7시",       time:"07:00 - 08:00 (60분)",  type:"타석",   status:"이용완료",     bay:"7번 타석",    store:"프렌즈 스크린 판교점", voucher:{name:"트레이닝 60분권", dur:"60분", left:"10회", total:"20회"}},
  {...bkMk(-4),  t:"오후 5시",       time:"17:00 - 17:20 (20분)",  type:"레슨",   status:"이용완료",     pro:"박은선 프로", store:"프렌즈 아카데미 판교점", voucher:{name:"2024 가나다 정기 레슨권", dur:"20분 (1회)", left:"9회", total:"10회"}},
  {...bkMk(-13), t:"오후 3시",       time:"15:00 - 17:00 (120분)", type:"스크린", status:"취소",         people:"2명",     store:"탄천종합운동장", pay:"현장 결제"},
];
// 뷰 상태 저장(상세 왕복 시 유지)
const BK_VIEW = { view:"calendar", cal:null, selDay:null, filter:"전체" };

function BookingList({ onBack, onOpenDetail }){
  const today = new Date();
  const todayY = today.getFullYear(), todayM = today.getMonth()+1, todayD = today.getDate();
  const [view, setView] = React.useState(BK_VIEW.view);         // calendar | list
  const [cal, setCal] = React.useState(BK_VIEW.cal || {y:todayY, m:todayM});
  const [selDay, setSelDay] = React.useState(BK_VIEW.selDay);
  const [filter, setFilter] = React.useState(BK_VIEW.filter);
  const [picker, setPicker] = React.useState(null);             // {y,m} 열림
  const pageSize = view==="list" ? 10 : 5;                       // 목록 10개 / 캘린더 5개
  const [visible, setVisible] = React.useState(pageSize);
  React.useEffect(()=>{ BK_VIEW.view=view; BK_VIEW.cal=cal; BK_VIEW.selDay=selDay; BK_VIEW.filter=filter; }, [view,cal,selDay,filter]);
  React.useEffect(()=>{ setVisible(view==="list"?10:5); }, [view, cal.y, cal.m, selDay, filter]);

  const shiftCal = (d)=>{ setSelDay(null); setCal(c=>{ let m=c.m+d, y=c.y; if(m<1){m=12;y--;} if(m>12){m=1;y++;} return {y,m}; }); };
  const goToday = ()=>{ setCal({y:todayY,m:todayM}); setSelDay(null); };
  const onToday = cal.y===todayY && cal.m===todayM && selDay==null;

  const byFilter = (r)=> filter==="전체" ? true : BK_CAT(r.type)===filter;
  const monthRows = BK_ROWS.filter(r=> r.y===cal.y && r.m===cal.m);
  const bySel = (r)=> selDay==null ? true : r.day===selDay;
  const list = view==="list" ? BK_ROWS.filter(byFilter) : monthRows.filter(r=> byFilter(r) && bySel(r));
  const upcoming = list.filter(r=>BK_UPCOMING(r.status));
  const past = list.filter(r=>!BK_UPCOMING(r.status));
  // 더보기: 캘린더 5개씩 / 목록 10개씩
  const ordered = [...upcoming, ...past];
  const shown = ordered.slice(0, visible);
  const hasMore = ordered.length > visible;
  const shownUp = shown.filter(r=>BK_UPCOMING(r.status));
  const shownPast = shown.filter(r=>!BK_UPCOMING(r.status));
  // 캘린더 마커: 예약 있는 날에 유형별 아이콘(아카데미=사람 / 스크린=핀), 다가오는=초록·지난=회색
  const dayMark = {};
  monthRows.filter(byFilter).forEach(r=>{ const k=BK_CAT(r.type)==="스크린"?"screen":"aca"; const up=BK_UPCOMING(r.status);
    if(!dayMark[r.day]) dayMark[r.day]={}; if(!dayMark[r.day][k]) dayMark[r.day][k]={up:false}; if(up) dayMark[r.day][k].up=true; });
  const markIcon = (kind,up)=>{ const c=up?"var(--primary)":"var(--text-mute)"; return kind==="aca"
    ? <svg key={kind} viewBox="0 0 12 12" width="9" height="9" fill={c}><circle cx="6" cy="3.3" r="2"/><path d="M2 11c0-2.1 1.8-3.4 4-3.4s4 1.3 4 3.4z"/></svg>
    : <svg key={kind} viewBox="0 0 12 12" width="9" height="9" fill={c}><path d="M6 1a3.4 3.4 0 0 1 3.4 3.4C9.4 6.8 6 11 6 11S2.6 6.8 2.6 4.4A3.4 3.4 0 0 1 6 1z"/></svg>; };
  const DIM = new Date(cal.y, cal.m, 0).getDate();
  const first = new Date(cal.y, cal.m-1, 1).getDay();
  const cells = []; for(let i=0;i<first;i++) cells.push(null); for(let d=1;d<=DIM;d++) cells.push(d);
  const years = [todayY-2, todayY-1, todayY, todayY+1];

  const Card = (r, i)=>{
    const up = BK_UPCOMING(r.status);
    return (
      <button key={r.status+i+r.day} onClick={()=>onOpenDetail(r)} style={{display:"block",width:"100%",textAlign:"left",padding:"16px 16px",background:up?"var(--primary-tint)":"var(--bg-soft)",borderRadius:14,border:"none",marginBottom:10,
        borderLeft:up?"3px solid var(--primary)":"3px solid transparent"}}>
        <div style={{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:8}}>
          <span style={{fontSize:12.5,color:"var(--text-sub)",fontWeight:600}}>{r.d}</span>
          <span style={{display:"flex",alignItems:"center",gap:5,fontSize:12,fontWeight:700}}>
            <span style={{display:"inline-flex",color:"var(--text-mute)"}}><BkTypeIcon t={r.type}/></span>
            <span style={{color:"var(--text-sub)"}}>{r.type}</span>
            <span style={{color:BK_STATUS_COLOR(r.status)}}>{r.status}</span>
          </span>
        </div>
        <div style={{display:"flex",alignItems:"baseline",justifyContent:"space-between",gap:10}}>
          <span style={{fontSize:18,fontWeight:800,letterSpacing:"-.02em"}}>{r.t}</span>
          <span style={{fontSize:16,fontWeight:800}}>{bkValue(r)}</span>
        </div>
        <div style={{display:"flex",alignItems:"center",gap:5,marginTop:9,fontSize:12,color:"var(--text-sub)"}}>
          <Icon name="location" size={13} style={{color:"var(--text-mute)"}}/>{r.store}
        </div>
      </button>
    );
  };
  // 뷰 토글 아이콘
  const viewBtn = (v, svg)=>(
    <button onClick={()=>setView(v)} style={{width:30,height:26,borderRadius:6,display:"flex",alignItems:"center",justifyContent:"center",border:"none",background:view===v?"#fff":"transparent",color:view===v?"var(--text)":"var(--text-mute)",boxShadow:view===v?"0 1px 3px rgba(0,0,0,.12)":"none"}}>{svg}</button>
  );

  return (
    <div className="screen">
      <StatusBar/>
      <Appbar title="예약 내역" onBack={onBack}
        right={<div style={{display:"flex",background:"var(--bg-soft)",borderRadius:8,padding:2}}>
          {viewBtn("calendar", <svg viewBox="0 0 20 20" width="16" height="16" fill="none" stroke="currentColor" strokeWidth="1.6"><rect x="3" y="4" width="14" height="13" rx="2"/><path d="M3 8h14M7 2v3M13 2v3"/></svg>)}
          {viewBtn("list", <svg viewBox="0 0 20 20" width="16" height="16" fill="none" stroke="currentColor" strokeWidth="1.6"><path d="M7 5h10M7 10h10M7 15h10"/><circle cx="3.5" cy="5" r="1"/><circle cx="3.5" cy="10" r="1"/><circle cx="3.5" cy="15" r="1"/></svg>)}
        </div>}/>
      <div className="scroll" style={{paddingBottom:24}}>
        {view==="calendar" && (<>
          {/* 월 헤더(탭→년월 선택) + 캘린더 */}
          <div style={{padding:"6px 20px 4px"}}>
            <div style={{display:"flex",alignItems:"center",justifyContent:"center",gap:12,padding:"8px 0 10px"}}>
              <button onClick={()=>shiftCal(-1)} className="icon-btn" style={{width:26,height:26}}><Icon name="back" size={15}/></button>
              <button onClick={()=>setPicker({...cal})} style={{display:"flex",alignItems:"center",gap:4,fontSize:15,fontWeight:700,background:"transparent"}}>{cal.y}년 {cal.m}월 <Icon name="chev-d" size={14} style={{color:"var(--text-mute)"}}/></button>
              <button onClick={()=>shiftCal(1)} className="icon-btn" style={{width:26,height:26}}><Icon name="chev-r" size={15}/></button>
            </div>
            <div style={{display:"grid",gridTemplateColumns:"repeat(7,1fr)",textAlign:"center"}}>
              {["일","월","화","수","목","금","토"].map((w,i)=><div key={w} style={{fontSize:11,fontWeight:600,color:i===0?"var(--danger)":"var(--text-mute)",padding:"2px 0 6px"}}>{w}</div>)}
              {cells.map((d,i)=>{ const isToday=d!=null&&cal.y===todayY&&cal.m===todayM&&d===todayD; const isSel=d!=null&&selDay===d; const mk=d!=null?dayMark[d]:null; return (
                <button key={i} disabled={!d} onClick={()=>d&&setSelDay(isSel?null:d)} style={{aspectRatio:"1",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",gap:1,background:isSel?"var(--primary-tint)":"transparent",border:"none",borderRadius:10}}>
                  {d && <>
                    <span style={{width:24,height:24,borderRadius:"50%",display:"flex",alignItems:"center",justifyContent:"center",fontSize:13,fontWeight:isSel||isToday?800:500,color:isToday?"#fff":i%7===0?"var(--danger)":"var(--text)",background:isToday&&!isSel?"var(--text)":"transparent"}}>{d}</span>
                    <span style={{display:"flex",gap:2,height:9,alignItems:"center"}}>{mk&&mk.aca&&markIcon("aca",mk.aca.up)}{mk&&mk.screen&&markIcon("screen",mk.screen.up)}</span>
                  </>}
                </button>
              ); })}
            </div>
          </div>
          <div style={{height:8,background:"var(--bg-soft)",margin:"8px 0 0"}}/>
        </>)}

        {/* 카운트 + 오늘 버튼 */}
        <div style={{display:"flex",alignItems:"center",gap:6,padding:"16px 20px 10px"}}>
          <span style={{fontSize:16,fontWeight:800}}>예약 정보</span>
          <span style={{fontSize:16,fontWeight:700,color:"var(--primary)"}}>{list.length}</span>
          {view==="calendar" && !onToday && (
            <button onClick={goToday} style={{marginLeft:"auto",display:"flex",alignItems:"center",gap:4,fontSize:12.5,fontWeight:700,color:"var(--primary)",background:"var(--primary-tint)",border:"none",borderRadius:14,padding:"5px 12px"}}>
              <svg viewBox="0 0 16 16" width="12" height="12" fill="none" stroke="currentColor" strokeWidth="1.7"><path d="M9 3L4 8l5 5" strokeLinecap="round" strokeLinejoin="round"/><path d="M4 8h9" strokeLinecap="round"/></svg>오늘
            </button>
          )}
        </div>
        <div style={{display:"flex",gap:8,padding:"0 20px 8px"}}>
          {["전체","스크린","아카데미"].map(f=>(
            <button key={f} onClick={()=>setFilter(f)} style={{fontSize:13,fontWeight:filter===f?700:600,padding:"7px 15px",borderRadius:18,border:filter===f?"none":"1px solid var(--line-strong)",background:filter===f?"#1A1C1F":"#fff",color:filter===f?"#fff":"var(--text-sub)"}}>{f}</button>
          ))}
        </div>

        {list.length===0 ? (
          <div style={{padding:"48px 30px",textAlign:"center"}}>
            <img src="assets/course-empty.png" alt="" style={{width:110,height:116,objectFit:"contain"}}/>
            <div style={{fontSize:14,fontWeight:600,color:"var(--text-mute)",marginTop:12}}>예약 내역이 없어요.</div>
          </div>
        ) : (
          <div style={{padding:"4px 20px 0"}}>
            {shownUp.length>0 && <div style={{fontSize:13,fontWeight:800,color:"var(--primary)",margin:"4px 0 10px"}}>다가오는 예약 {upcoming.length}</div>}
            {shownUp.map((r,i)=>Card(r,i))}
            {shownPast.length>0 && <div style={{fontSize:13,fontWeight:800,color:"var(--text-sub)",margin:"8px 0 10px"}}>지난 예약 {past.length}</div>}
            {shownPast.map((r,i)=>Card(r,i))}
            {hasMore && (
              <button onClick={()=>setVisible(v=>v+pageSize)} style={{width:"100%",padding:"13px 0",margin:"2px 0 6px",fontSize:14,fontWeight:700,color:"var(--text-sub)",background:"var(--bg-soft)",border:"1px solid var(--line)",borderRadius:12,display:"flex",alignItems:"center",justifyContent:"center",gap:5}}>더보기 <Icon name="chev-d" size={14}/></button>
            )}
          </div>
        )}
      </div>

      {/* 년/월 선택 */}
      {picker && (
        <div onClick={()=>setPicker(null)} style={{position:"absolute",inset:0,background:"rgba(0,0,0,.4)",zIndex:50,display:"flex",alignItems:"center",justifyContent:"center",padding:"0 32px"}}>
          <div onClick={e=>e.stopPropagation()} style={{width:"100%",maxWidth:320,background:"#fff",borderRadius:16,padding:"18px 18px 16px"}}>
            <div style={{display:"flex",gap:10}}>
              {[["y",years.map(String)],["m",Array.from({length:12},(_,i)=>String(i+1))]].map(([k,opts])=>(
                <div key={k} style={{flex:1,height:150,overflowY:"auto",scrollbarWidth:"none",border:"1px solid var(--line)",borderRadius:10}}>
                  {opts.map(o=>{ const on=String(picker[k])===o; return (
                    <button key={o} onClick={()=>setPicker(p=>({...p,[k]:Number(o)}))} style={{display:"block",width:"100%",padding:"12px 0",textAlign:"center",fontSize:15,fontWeight:on?800:500,color:on?"var(--primary)":"var(--text-sub)",background:on?"var(--primary-tint)":"transparent",border:"none"}}>{o}{k==="y"?"년":"월"}</button>
                  ); })}
                </div>
              ))}
            </div>
            <div style={{display:"flex",gap:8,marginTop:16}}>
              <button className="btn btn-soft" style={{flex:1}} onClick={()=>setPicker(null)}>취소</button>
              <button className="btn btn-primary" style={{flex:1}} onClick={()=>{ setCal({y:picker.y,m:picker.m}); setSelDay(null); setPicker(null); }}>확인</button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

function BookingDetail({ onBack, row, onModify, onOpenCancel }){
  const [modifyOpen, setModifyOpen] = React.useState(false);
  const r = row || {};
  const type = r.type || "레슨";
  const status = r.status || "이용완료";
  const canManage = status==="예약완료" || status==="현장결제 대기";  // 이용 전만 변경/취소
  const isScreen = type==="스크린";
  const val = bkValue(r) || (isScreen?"2명":type==="레슨"?"박은선 프로":"12번 타석");
  const vc = r.voucher || {name:"2024 가나다 정기 레슨권", dur:"20분 (1회)", left:"1회", total:"10회"};

  return (
    <div className="screen">
      <StatusBar/>
      <Appbar title="예약 상세 조회" onBack={onBack}/>

      <div className="scroll" style={{paddingBottom: canManage ? 96 : 24}}>
        {/* 헤더 (유형 아이콘 + 상태) */}
        <div style={{padding:"16px 20px"}}>
          <div style={{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:10}}>
            <div style={{display:"flex",alignItems:"center",gap:6,fontSize:13,fontWeight:700,color:"var(--text-sub)"}}>
              <span style={{color:"var(--text-mute)"}}><BkTypeIcon t={type} size={15}/></span> {type}
            </div>
            <div style={{fontSize:13,color:BK_STATUS_COLOR(status),fontWeight:700}}>{status}</div>
          </div>
          <div style={{fontSize:13,color:"var(--text-sub)"}}>{r.d || "12월 29일"}</div>
          <div style={{display:"flex",alignItems:"baseline",gap:10,marginTop:4}}>
            <div style={{fontSize:22,fontWeight:800,letterSpacing:"-.02em"}}>{r.t || "오후 11시 15분"}</div>
            <div style={{fontSize:18,fontWeight:700,flex:1,textAlign:"right"}}>{val}</div>
          </div>
        </div>

        <div style={{height:10,background:"var(--bg-soft)"}}/>

        <div style={{padding:"20px 20px 8px"}}>
          <div className="h3" style={{fontSize:15,marginBottom:6}}>예약 정보</div>
          <div className="info-table">
            <div className="ir"><div className="k">이용 매장</div><div className="v">{r.store || "프렌즈 아카데미 판교 파미어스몰"}</div></div>
            <div className="ir"><div className="k">예약 날짜</div><div className="v">{r.date || "2024.12.29"}</div></div>
            <div className="ir"><div className="k">예약 시간</div><div className="v">{r.time || "23:15 - 익일 01:00 (45분)"}</div></div>
            {isScreen && <div className="ir"><div className="k">예약 인원</div><div className="v">{r.people || "2명"}</div></div>}
          </div>
        </div>

        <div style={{height:10,background:"var(--bg-soft)"}}/>

        {isScreen ? (
          <div style={{padding:"20px 20px"}}>
            <div className="h3" style={{fontSize:15,marginBottom:6}}>결제 정보</div>
            <div className="info-table">
              <div className="ir"><div className="k">결제 수단</div><div className="v">{r.pay || "현장 결제"}</div></div>
              <div className="ir"><div className="k">타석 유형</div><div className="v">스크린 골프</div></div>
            </div>
          </div>
        ) : (
          <div style={{padding:"20px 20px"}}>
            <div className="h3" style={{fontSize:15,marginBottom:6}}>이용권 정보</div>
            <div className="info-table">
              <div className="ir"><div className="k">{type==="레슨"?"레슨권명":"이용권명"}</div><div className="v">{vc.name}</div></div>
              <div className="ir"><div className="k">{type==="레슨"?"레슨 시간":"이용 시간"}</div><div className="v">{vc.dur}</div></div>
              <div className="ir"><div className="k">{type==="레슨"?"레슨 가능 횟수":"이용 가능 횟수"}</div><div className="v"><span style={{color:"var(--primary)"}}>{vc.left}</span> / {vc.total}</div></div>
            </div>
          </div>
        )}

        {canManage ? (
          <div style={{padding:"0 20px"}}>
            <div style={{display:"flex",gap:8,alignItems:"flex-start",padding:"12px 14px",background:"var(--bg-soft)",borderRadius:10,fontSize:12,color:"var(--text-sub)",lineHeight:1.6}}>
              <Icon name="info" size={14} style={{color:"var(--text-mute)",marginTop:1,flexShrink:0}}/>
              <span>무료 취소 마감은 <b style={{color:"var(--text)"}}>예약 시간 60분 전</b>입니다. 이후 취소는 환불이 불가하며 이용권은 차감 유지됩니다. 예약 변경은 이용 시작 1시간 전까지 가능합니다.</span>
            </div>
          </div>
        ) : (status==="취소"||status==="노쇼") && (
          <div style={{padding:"4px 20px 0"}}>
            <div style={{padding:"14px 16px",background:"#FEF2F2",border:"1px solid #FECACA",borderRadius:10,fontSize:13,color:"var(--danger)",fontWeight:600,textAlign:"center"}}>
              {status==="취소" ? "취소된 예약입니다 · 환불/이용권 복구 처리" : "노쇼 처리된 예약입니다 · 이용권 차감 유지"}
            </div>
          </div>
        )}
      </div>

      {canManage && (
        <div style={{position:"absolute",bottom:0,left:0,right:0,padding:"12px 20px 24px",background:"#fff",borderTop:"1px solid var(--line)",display:"flex",gap:8}}>
          <button className="btn btn-outline" style={{flex:1}} onClick={()=>setModifyOpen(true)}>예약 변경</button>
          <button className="btn btn-primary" style={{flex:1}} onClick={()=>onOpenCancel&&onOpenCancel(row)}>예약 취소</button>
        </div>
      )}

      {modifyOpen && (
        <>
          <div className="sheet-back" onClick={()=>setModifyOpen(false)}/>
          <div style={{position:"absolute",left:32,right:32,top:"34%",background:"#fff",borderRadius:16,padding:24,zIndex:200}}>
            <div style={{fontSize:17,fontWeight:800,marginBottom:8}}>예약을 변경하시겠어요?</div>
            <div style={{fontSize:13,color:"var(--text-sub)",lineHeight:1.6,marginBottom:18}}>
              변경은 현재 <b style={{color:"var(--text)"}}>취소 후 재예약</b>으로 처리되어 결제 취소·재결제가 발생할 수 있습니다. (이용 시작 1시간 전까지 변경 가능)
            </div>
            <div style={{display:"flex",gap:8}}>
              <button className="btn btn-outline" style={{flex:1,height:48}} onClick={()=>setModifyOpen(false)}>닫기</button>
              <button className="btn btn-primary" style={{flex:1,height:48}} onClick={()=>{ setModifyOpen(false); onModify && onModify(); }}>변경하기</button>
            </div>
          </div>
        </>
      )}
    </div>
  );
}

// 예약 취소 — 사유 선택 화면 (Figma) + 정책 안내 문구(프로토)
function BookingCancel({ onBack, row, onDone }){
  const reasons = ["예약 날짜 변경 및 시간 변경","예약 조건 변경","개인 사정으로 인한 취소","기타 (직접입력)"];
  const [sel, setSel] = React.useState(null);
  const [text, setText] = React.useState("");
  const [toast, setToast] = React.useState(false);
  const etc = sel===reasons.length-1;
  const valid = sel!=null && (!etc || !!text.trim());
  const submit = ()=>{ if(!valid) return; setToast(true); window.setTimeout(()=>{ onDone&&onDone(); }, 1100); };
  return (
    <div className="screen">
      <StatusBar/>
      <Appbar title="예약 취소" onBack={onBack} right={<button className="icon-btn" onClick={onBack}><Icon name="x" size={20}/></button>}/>
      {toast && <div className="toast"><span>예약이 취소되었습니다.</span></div>}
      <div className="scroll" style={{padding:"18px 20px 100px"}}>
        <div style={{fontSize:19,fontWeight:800,lineHeight:1.35,letterSpacing:"-.02em"}}>예약을 취소하는 이유를<br/>선택해주세요.</div>
        <div style={{marginTop:22}}>
          {reasons.map((rz,i)=>{ const on=sel===i; return (
            <button key={i} onClick={()=>setSel(i)} style={{display:"flex",alignItems:"center",gap:12,width:"100%",padding:"14px 0",background:"transparent",border:"none",textAlign:"left"}}>
              <span style={{width:22,height:22,borderRadius:"50%",border:"2px solid "+(on?"var(--primary)":"var(--line-strong)"),display:"flex",alignItems:"center",justifyContent:"center",flexShrink:0}}>{on && <span style={{width:11,height:11,borderRadius:"50%",background:"var(--primary)"}}/>}</span>
              <span style={{fontSize:15,fontWeight:on?700:500,color:on?"var(--text)":"var(--text-sub)"}}>{rz}</span>
            </button>
          ); })}
          {etc && (
            <div style={{marginTop:6}}>
              <textarea value={text} onChange={e=>setText(e.target.value.slice(0,20))} placeholder="취소 사유를 20자 이내로 입력해주세요." style={{width:"100%",height:120,border:"1px solid var(--line)",borderRadius:10,padding:"12px 14px",fontSize:14,outline:"none",resize:"none",fontFamily:"inherit"}}/>
              <div style={{textAlign:"right",fontSize:11,color:"var(--text-mute)",marginTop:4}}>{text.length}/20자</div>
            </div>
          )}
        </div>
        <div style={{display:"flex",gap:8,alignItems:"flex-start",marginTop:18,padding:"12px 14px",background:"var(--bg-soft)",borderRadius:10,fontSize:12,color:"var(--text-sub)",lineHeight:1.6}}>
          <Icon name="info" size={14} style={{color:"var(--text-mute)",marginTop:1,flexShrink:0}}/>
          <span>무료 취소 마감(<b style={{color:"var(--text)"}}>예약 60분 전</b>) 이내 취소 시 결제 취소·이용권이 복구됩니다. 이후에는 환불이 불가하며 이용권은 차감 유지됩니다. 노쇼 반복 시 예약 제한 등 패널티가 부여될 수 있습니다.</span>
        </div>
      </div>
      <div style={{position:"absolute",left:0,right:0,bottom:0,padding:"14px 20px 24px",background:"#fff",borderTop:"1px solid var(--line)"}}>
        <button className={"btn "+(valid?"btn-primary":"btn-soft")} disabled={!valid} style={{width:"100%",opacity:valid?1:.6}} onClick={submit}>취소하기</button>
      </div>
    </div>
  );
}

// MyInfo — 주소 검색 (empty + ing), 비번변경, 탈퇴 팝업
function AddressSearch({ onBack }){
  const [q, setQ] = React.useState("");
  const [focused, setFocused] = React.useState(false);
  const results = q ? [
    {p:"25435",a:"강원특별자치도 강릉시 사천면 중앙동로 71 (판교리, 판교리마을회관)"},
    {p:"12772",a:"경기도 광주시 대명대길 57 (능평동, 판교공원묘지)"},
    {p:"13609",a:"경기도 성남시 내정로 113번길 4"},
    {p:"13550",a:"경기도 성남시 분당구 대왕판교로 228"},
    {p:"13480",a:"경기도 성남시 분당구 대왕판교로 477 (판교동, 낙생고등학교)"},
    {p:"13543",a:"경기도 성남시 분당구 대왕판교로385번길 13-9 (백현동, 판교테라스솔헤1)"},
  ] : [];

  return (
    <div className="screen">
      <StatusBar/>
      <div className="appbar" style={{padding:"0 8px"}}>
        <div className="side">
          <button className="icon-btn" onClick={onBack}><Icon name="back" size={20}/></button>
        </div>
        <div style={{flex:1,padding:"0 4px"}}>
          <input value={q} onChange={e=>setQ(e.target.value)} onFocus={()=>setFocused(true)}
            placeholder="주소 검색" autoFocus
            style={{width:"100%",height:40,fontSize:15,fontWeight:600,border:0,outline:"none",background:"transparent"}}/>
        </div>
        <div className="side">
          {q && <button className="icon-btn" onClick={()=>setQ("")}><div style={{width:20,height:20,borderRadius:"50%",background:"#E5E7EB",display:"flex",alignItems:"center",justifyContent:"center"}}><Icon name="x" size={12}/></div></button>}
        </div>
      </div>
      <div style={{height:1,background:"var(--line)"}}/>

      <div className="scroll" style={{paddingBottom:20}}>
        {results.map((r,i)=>(
          <div key={i} style={{padding:"16px 20px",display:"grid",gridTemplateColumns:"60px 1fr",gap:12,borderBottom:"1px solid var(--line)",fontSize:13}}>
            <div className="mono" style={{color:"var(--text-sub)",fontWeight:600}}>{r.p}</div>
            <div style={{lineHeight:1.5}}>{r.a}</div>
          </div>
        ))}
        {!q && (
          <div style={{padding:"40px 20px",textAlign:"center",color:"var(--text-sub)",fontSize:13}}>
            검색어를 입력해주세요
          </div>
        )}
      </div>

      {/* iOS Korean keyboard */}
      {focused && (
        <div style={{background:"#D1D4DB",padding:"10px 4px 0"}}>
          <div style={{display:"grid",gridTemplateColumns:"repeat(10,1fr)",gap:4,marginBottom:6}}>
            {["ㅂ","ㅈ","ㄷ","ㄱ","ㅅ","ㅛ","ㅕ","ㅑ","ㅐ","ㅔ"].map(k=><div key={k} className="keycap" style={{background:"#fff",borderRadius:6,padding:"10px 0",textAlign:"center",fontSize:18,fontWeight:500,boxShadow:"0 1px 0 rgba(0,0,0,.2)"}}>{k}</div>)}
          </div>
          <div style={{display:"grid",gridTemplateColumns:"repeat(9,1fr)",gap:4,marginBottom:6,padding:"0 16px"}}>
            {["ㅁ","ㄴ","ㅇ","ㄹ","ㅎ","ㅗ","ㅓ","ㅏ","ㅣ"].map(k=><div key={k} style={{background:"#fff",borderRadius:6,padding:"10px 0",textAlign:"center",fontSize:18,fontWeight:500,boxShadow:"0 1px 0 rgba(0,0,0,.2)"}}>{k}</div>)}
          </div>
          <div style={{display:"grid",gridTemplateColumns:"1.5fr repeat(7,1fr) 1.5fr",gap:4,marginBottom:6}}>
            <div style={{background:"#ACB0BA",borderRadius:6,padding:"10px 0",textAlign:"center",fontSize:12,fontWeight:600}}>⇧</div>
            {["ㅋ","ㅌ","ㅊ","ㅍ","ㅠ","ㅜ","ㅡ"].map(k=><div key={k} style={{background:"#fff",borderRadius:6,padding:"10px 0",textAlign:"center",fontSize:18,fontWeight:500,boxShadow:"0 1px 0 rgba(0,0,0,.2)"}}>{k}</div>)}
            <div style={{background:"#ACB0BA",borderRadius:6,padding:"10px 0",textAlign:"center",fontSize:14,fontWeight:600}}>⌫</div>
          </div>
          <div style={{display:"grid",gridTemplateColumns:"1fr 1fr 4fr 1fr 1fr",gap:4,marginBottom:0}}>
            <div style={{background:"#ACB0BA",borderRadius:6,padding:"10px 0",textAlign:"center",fontSize:12,fontWeight:600}}>123</div>
            <div style={{background:"#ACB0BA",borderRadius:6,padding:"10px 0",textAlign:"center",fontSize:16}}>😊</div>
            <div style={{background:"#fff",borderRadius:6,padding:"10px 0",textAlign:"center",fontSize:14,fontWeight:500}}>스페이스</div>
            <div style={{background:"#ACB0BA",borderRadius:6,padding:"10px 0",textAlign:"center",fontSize:12,fontWeight:600}}>,</div>
            <div style={{background:"#3B82F6",color:"#fff",borderRadius:6,padding:"10px 0",textAlign:"center",fontSize:14,fontWeight:600}}>검색</div>
          </div>
          <div style={{display:"flex",justifyContent:"space-between",padding:"8px 16px 4px"}}>
            <div>🌐</div>
            <div>🎙</div>
          </div>
        </div>
      )}
    </div>
  );
}

function PasswordChange({ onBack, error=true }){
  const [val, setVal] = React.useState("wrong123");
  return (
    <div className="screen">
      <StatusBar/>
      <Appbar title="비밀번호 변경" onBack={onBack}/>

      <div style={{padding:"20px 20px",flex:1}}>
        <div style={{fontSize:13,color:"var(--text-sub)",marginBottom:6}}>현재 비밀번호</div>
        <div style={{padding:"12px 0",borderBottom:"1.5px solid "+(error?"var(--danger)":"var(--line-strong)")}}>
          <input type="password" value={val} onChange={e=>setVal(e.target.value)}
            style={{width:"100%",fontSize:16,fontWeight:500,border:0,outline:"none",background:"transparent"}}/>
        </div>
        {error && <div style={{fontSize:12,color:"var(--danger)",marginTop:8,display:"flex",alignItems:"center",gap:6}}>
          <Icon name="info" size={14}/> 비밀번호가 3회 불일치합니다. 3회 이상 불일치 시 로그인이 제한됩니다.
        </div>}

        <div style={{marginTop:28,fontSize:13,color:"var(--text-sub)",marginBottom:6}}>새 비밀번호</div>
        <div style={{padding:"12px 0",borderBottom:"1.5px solid var(--line-strong)"}}>
          <input type="password" placeholder="영문, 숫자, 특수문자 포함 8-20자"
            style={{width:"100%",fontSize:16,fontWeight:500,border:0,outline:"none",background:"transparent"}}/>
        </div>

        <div style={{marginTop:28,fontSize:13,color:"var(--text-sub)",marginBottom:6}}>새 비밀번호 확인</div>
        <div style={{padding:"12px 0",borderBottom:"1.5px solid var(--line-strong)"}}>
          <input type="password" placeholder="새 비밀번호 재입력"
            style={{width:"100%",fontSize:16,fontWeight:500,border:0,outline:"none",background:"transparent"}}/>
        </div>
      </div>

      <div style={{padding:"12px 20px 24px",background:"#fff"}}>
        <button className="btn btn-disabled" style={{width:"100%"}}>변경 완료</button>
      </div>
    </div>
  );
}

function Withdraw({ onBack }){
  const [popup, setPopup] = React.useState(false);
  // 이용권 보유 시 탈퇴 불가 — 정책 §12 (데모: 보유/미보유 토글)
  const [hasTickets, setHasTickets] = React.useState(true);
  const heldTickets = [
    {kind:"정기 이용권", name:"퀀텀 아카데미 판교점 3개월 정기 이용권"},
    {kind:"레슨권", name:"조현진 프로 레슨권"},
  ];

  return (
    <div className="screen">
      <StatusBar/>
      <Appbar title="탈퇴하기" onBack={onBack}
        right={
          <button className="icon-btn" onClick={()=>setHasTickets(v=>!v)}
            style={{fontSize:10,fontWeight:600,color:"var(--text-mute)",padding:"4px 6px"}}>
            (데모 {hasTickets?"보유":"미보유"})
          </button>
        }/>

      <div className="scroll" style={{padding:"16px 20px",paddingBottom:120}}>
        {hasTickets ? (
          <>
            <div style={{fontSize:18,fontWeight:800,lineHeight:1.5,letterSpacing:"-.01em"}}>
              보유 중인 이용권이 있어<br/>탈퇴할 수 없어요.
            </div>
            <div style={{marginTop:14,padding:"14px 16px",background:"#FEF2F2",border:"1px solid #FECACA",borderRadius:10,fontSize:13,color:"var(--text-sub)",lineHeight:1.6}}>
              이용권을 모두 사용하거나, 매장에 문의해 환불·삭제 처리한 후 탈퇴할 수 있습니다.
            </div>
            <div style={{marginTop:18,fontSize:14,fontWeight:700,marginBottom:10}}>보유 이용권 {heldTickets.length}</div>
            <div style={{display:"flex",flexDirection:"column",gap:10}}>
              {heldTickets.map((t,i)=>(
                <div key={i} style={{padding:"14px 16px",background:"var(--bg-soft)",borderRadius:10}}>
                  <div style={{fontSize:11,color:"var(--text-sub)",marginBottom:4}}>{t.kind}</div>
                  <div style={{fontSize:14,fontWeight:700,letterSpacing:"-.01em"}}>{t.name}</div>
                </div>
              ))}
            </div>
          </>
        ) : (
          <>
            <div style={{fontSize:18,fontWeight:800,lineHeight:1.5,letterSpacing:"-.01em"}}>
              탈퇴 시 회원님의 모든 정보가 소멸되며,<br/>이전으로 복구가 불가합니다.
            </div>
            <div style={{marginTop:24,padding:"18px",background:"var(--bg-soft)",borderRadius:10}}>
              <div style={{fontSize:14,fontWeight:700,marginBottom:10}}>카카오 VX의 통합 계정 탈퇴 유의사항</div>
              <ul style={{margin:0,padding:"0 0 0 16px",fontSize:13,color:"var(--text-sub)",lineHeight:1.8}}>
                <li>나의 업적미션 기록</li>
                <li>나의 포인트</li>
                <li>나의 스윙영상 기록</li>
                <li>가입 시 등록한 개인정보</li>
              </ul>
              <div style={{fontSize:14,fontWeight:700,margin:"16px 0 8px"}}>퀀텀 아카데미 회원정보 삭제 내용</div>
              <ul style={{margin:0,padding:"0 0 0 16px",fontSize:13,color:"var(--text-sub)",lineHeight:1.8}}>
                <li>클럽 측정 기록</li>
                <li>레슨 기록</li>
                <li>이용권 사용 기록</li>
              </ul>
            </div>
            <div style={{marginTop:14,fontSize:12,color:"var(--text-mute)",lineHeight:1.6}}>
              ※ 게임·대회 참여 기록 및 제세공과금 관련 기록은 관련 법령에 따라 별도 기간 보관 후 삭제됩니다.
            </div>
          </>
        )}
      </div>

      <div style={{position:"absolute",bottom:0,left:0,right:0,padding:"12px 20px 24px",background:"#fff",borderTop:"1px solid var(--line)"}}>
        {hasTickets ? (
          <button className="btn btn-disabled" style={{width:"100%"}} disabled>이용권 소진 후 탈퇴 가능</button>
        ) : (
          <button className="btn btn-primary" style={{width:"100%"}} onClick={()=>setPopup(true)}>다음</button>
        )}
      </div>

      {popup && (
        <>
          <div className="sheet-back" onClick={()=>setPopup(false)}/>
          <div style={{position:"absolute",left:32,right:32,top:"35%",background:"#fff",borderRadius:16,padding:24,zIndex:200}}>
            <div style={{fontSize:17,fontWeight:800,marginBottom:8}}>정말 탈퇴하시겠어요?</div>
            <div style={{fontSize:13,color:"var(--text-sub)",lineHeight:1.5,marginBottom:18}}>
              탈퇴 버튼 선택 시, 계정이 삭제되며<br/>복구가 불가능합니다.
            </div>
            <div style={{display:"flex",gap:8}}>
              <button className="btn btn-outline" style={{flex:1,height:48}} onClick={()=>setPopup(false)}>취소</button>
              <button className="btn btn-primary" style={{flex:1,height:48}}>탈퇴하기</button>
            </div>
          </div>
        </>
      )}
    </div>
  );
}

// 알림함 — 정책 §14 알림 정책
// 7개 상황(예약완료·변경·취소·리마인드·결제실패·노쇼·매장사유취소) + 채널(App Push·알림톡·SMS) + Push 실패 시 알림톡 재발송
function Notifications({ onBack, onOpenDetail }){
  const NT = {
    reminder:    {label:"리마인드",     icon:"clock",  color:"#16A34A", bg:"var(--primary-tint)"},
    done:        {label:"예약 완료",     icon:"check",  color:"#16A34A", bg:"var(--primary-tint)"},
    change:      {label:"예약 변경",     icon:"refresh",color:"#2563EB", bg:"#E8F0FE"},
    cancel:      {label:"예약 취소",     icon:"x",      color:"#DC2626", bg:"#FEECEA"},
    payfail:     {label:"결제 실패",     icon:"card",   color:"#D97706", bg:"#FEF3C7"},
    noshow:      {label:"노쇼 처리",     icon:"info",   color:"#DC2626", bg:"#FEECEA"},
    storecancel: {label:"매장 사유 취소", icon:"store",  color:"#D97706", bg:"#FEF3C7"},
  };
  const INIT = [
    {id:1, type:"reminder", group:"오늘", time:"방금 전", via:["push","alimtalk"],
      title:"이용 1시간 전이에요",
      body:"퀀텀 아카데미 판교점 · 오늘 19:00 · 라이언석. 시간 맞춰 방문해 주세요.",
      unread:true, res:{d:"오늘",t:"오후 07:00",pro:"라이언석",tag:"연습",status:"예약완료",store:"퀀텀 아카데미 판교점"}},
    {id:2, type:"done", group:"오늘", time:"2시간 전", via:["push"],
      title:"예약이 완료되었어요",
      body:"퀀텀 아카데미 판교점 · 오늘 19:00 · 라이언석 · App 결제 완료",
      unread:true, res:{d:"오늘",t:"오후 07:00",pro:"라이언석",tag:"연습",status:"예약완료",store:"퀀텀 아카데미 판교점"}},
    {id:3, type:"payfail", group:"오늘", time:"5시간 전", via:["push"],
      title:"결제에 실패했어요",
      body:"카드 승인이 거절되었습니다. 10분 내 재결제하면 예약이 유지돼요.",
      unread:false},
    {id:4, type:"change", group:"어제", time:"어제 18:20", via:["push","alimtalk"],
      title:"예약 시간이 변경되었어요",
      body:"광교점 조현진 프로 레슨 · 14:00 → 15:00 으로 변경되었습니다.",
      unread:false, res:{d:"내일",t:"오후 03:00",pro:"조현진 프로",tag:"레슨",status:"예약완료",store:"퀀텀 아카데미 광교점"}},
    {id:5, type:"storecancel", group:"어제", time:"어제 10:05", via:["push","alimtalk","sms"],
      title:"매장 사정으로 예약이 취소되었어요",
      body:"장비 점검으로 강남점 12:00 예약이 취소되었습니다. 전액 환불(이용권 복구) 처리되며 패널티는 없어요.",
      unread:false},
    {id:6, type:"noshow", group:"이전", time:"12월 18일", via:["push","alimtalk"],
      title:"노쇼로 처리되었어요",
      body:"로엘이 프로 레슨 미방문 · 이용권은 차감 유지됩니다. 누적 노쇼 2회 (3회 시 선결제 전환)",
      unread:false},
    {id:7, type:"cancel", group:"이전", time:"12월 15일", via:["push"],
      title:"예약이 취소되었어요",
      body:"판교점 5번 타석 12/15 20:00 예약 취소 · 환불/이용권 복구가 완료되었습니다.",
      unread:false},
  ];

  const [items, setItems] = React.useState(INIT);
  const [empty, setEmpty] = React.useState(false);
  const unread = items.filter(i=>i.unread).length;
  const readAll = ()=> setItems(items.map(i=>({...i, unread:false})));
  const open = (it)=>{
    setItems(items.map(i=> i.id===it.id ? {...i, unread:false} : i));
    if (it.res && onOpenDetail) onOpenDetail(it.res);
  };
  const groups = ["오늘","어제","이전"].map(g=>({g, rows: items.filter(i=>i.group===g)})).filter(x=>x.rows.length);
  const viaLabel = {push:"App Push", alimtalk:"알림톡", sms:"SMS"};

  return (
    <div className="screen">
      <StatusBar/>
      <Appbar title="알림" onBack={onBack}
        right={
          <button onClick={()=>setEmpty(v=>!v)} className="icon-btn"
            style={{fontSize:10,fontWeight:600,color:"var(--text-mute)",padding:"4px 6px",width:"auto"}}>
            (데모 {empty?"빈상태":"보유"})
          </button>
        }/>

      {empty || groups.length===0 ? (
        <div style={{flex:1,display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",padding:"0 20px"}}>
          <div className="empty-ill" style={{width:72,height:72,marginBottom:16}}><Icon name="bell" size={30}/></div>
          <div style={{fontSize:14,color:"var(--text-mute)"}}>새로운 알림이 없어요.</div>
        </div>
      ) : (
        <>
          {/* 읽음 처리 바 */}
          <div style={{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"10px 20px 6px"}}>
            <div style={{fontSize:12.5,color:"var(--text-sub)",fontWeight:600}}>
              안 읽은 알림 <span style={{color:"var(--primary)",fontWeight:800}}>{unread}</span>
            </div>
            <button onClick={readAll} disabled={!unread}
              style={{fontSize:12.5,fontWeight:700,color:unread?"var(--primary)":"var(--text-mute)",background:"transparent"}}>
              모두 읽음
            </button>
          </div>

          <div className="scroll" style={{paddingBottom:24}}>
            {groups.map(({g,rows})=>(
              <div key={g}>
                <div style={{padding:"10px 20px 4px",fontSize:12,fontWeight:800,color:"var(--text-mute)",letterSpacing:".02em"}}>{g}</div>
                {rows.map(it=>{
                  const t = NT[it.type];
                  return (
                    <button key={it.id} onClick={()=>open(it)}
                      style={{display:"flex",gap:12,width:"100%",textAlign:"left",padding:"14px 20px",
                        background: it.unread ? "rgba(34,197,94,.045)" : "transparent",
                        borderBottom:"1px solid var(--line)"}}>
                      <div style={{width:38,height:38,borderRadius:11,background:t.bg,color:t.color,
                        display:"flex",alignItems:"center",justifyContent:"center",flexShrink:0}}>
                        <Icon name={t.icon} size={18}/>
                      </div>
                      <div style={{flex:1,minWidth:0}}>
                        <div style={{display:"flex",alignItems:"center",gap:6,marginBottom:3}}>
                          <span style={{fontSize:10.5,fontWeight:800,color:t.color}}>{t.label}</span>
                          {it.unread && <span style={{width:6,height:6,borderRadius:"50%",background:"var(--danger)"}}/>}
                          <span style={{flex:1}}/>
                          <span style={{fontSize:11,color:"var(--text-mute)",flexShrink:0}}>{it.time}</span>
                        </div>
                        <div style={{fontSize:14,fontWeight:700,letterSpacing:"-.01em",marginBottom:2}}>{it.title}</div>
                        <div style={{fontSize:12.5,color:"var(--text-sub)",lineHeight:1.5}}>{it.body}</div>
                        <div style={{display:"flex",gap:4,marginTop:7}}>
                          {it.via.map(v=>(
                            <span key={v} style={{fontSize:9.5,fontWeight:700,color:"var(--text-sub)",background:"var(--bg-soft)",padding:"2px 7px",borderRadius:5}}>{viaLabel[v]}</span>
                          ))}
                          {it.res && <span style={{fontSize:9.5,fontWeight:700,color:"var(--primary)",background:"var(--primary-tint)",padding:"2px 7px",borderRadius:5}}>예약 보기 ›</span>}
                        </div>
                      </div>
                    </button>
                  );
                })}
              </div>
            ))}

            {/* 발송 정책 안내 — 정책 §14 */}
            <div style={{margin:"14px 20px 0",padding:"12px 14px",background:"var(--bg-soft)",borderRadius:10,
              fontSize:11.5,color:"var(--text-sub)",lineHeight:1.6,display:"flex",gap:8,alignItems:"flex-start"}}>
              <Icon name="info" size={14} style={{color:"var(--text-mute)",marginTop:1,flexShrink:0}}/>
              <span>알림은 <b style={{color:"var(--text)"}}>App Push · 알림톡 · SMS</b>로 발송돼요. Push가 실패하면 예약 확정·취소·리마인드 같은 중요 알림은 <b style={{color:"var(--text)"}}>알림톡으로 재발송</b>됩니다. 수신 설정은 <b style={{color:"var(--text)"}}>앱 설정 &gt; 예약 알림</b>에서 변경할 수 있어요.</span>
            </div>
          </div>
        </>
      )}
    </div>
  );
}

// Generic menu / settings hub (surfaced via appbar menu btn)
// 메뉴 아이콘 타일 (인라인 SVG)
function MIcon({ type, size=22 }){
  const c = {star:"#16A34A",calendar:"#16A34A",attend:"#16A34A",ticket:"#F59E0B",gift:"#EC4899",noshow:"#EF4444",won:"#16A34A",scorecard:"#3B82F6",cert:"#8B5CF6",buy:"#0EA5E9",locker:"#F97316",club:"#475569",game:"#475569",settings:"#6B7280"}[type] || "#6B7280";
  const g = {
    star:<path d="M12 3.5l2.6 5.3 5.9.9-4.2 4.1 1 5.8L12 17l-5.3 2.6 1-5.8L3.5 9.7l5.9-.9z"/>,
    calendar:<><rect x="4" y="6" width="16" height="14" rx="2"/><path d="M4 10h16M9 4v4M15 4v4"/></>,
    attend:<><rect x="4" y="5" width="16" height="15" rx="2"/><path d="M4 9h16M9 3v4M15 3v4"/><path d="M9 14.5l2 2 4-4.5"/></>,
    ticket:<><path d="M4 8v3a1.5 1.5 0 0 1 0 3v3h16v-3a1.5 1.5 0 0 1 0-3V8z"/><path d="M12 9v6" strokeDasharray="2 2"/></>,
    gift:<><path d="M19 12v8H5v-8"/><rect x="3" y="8" width="18" height="4" rx="1"/><path d="M12 8v12"/><path d="M12 8S10.5 4 8.5 4a2 2 0 0 0 0 4zM12 8s1.5-4 3.5-4a2 2 0 0 1 0 4z"/></>,
    noshow:<><path d="M12 4l9 16H3z"/><path d="M12 10v4M12 17v.5"/></>,
    won:<><circle cx="12" cy="12" r="8"/><path d="M8 9l1.5 6L12 10l2.5 5L16 9M7.5 11.5h9"/></>,
    scorecard:<><rect x="5" y="4" width="14" height="16" rx="2"/><path d="M8 9h8M8 13h8M8 17h5"/></>,
    cert:<><circle cx="12" cy="9" r="5"/><path d="M9 13l-2 7 5-3 5 3-2-7"/></>,
    buy:<><path d="M4 8h16l-1.2 11H5.2z"/><path d="M8.5 8a3.5 3.5 0 0 1 7 0"/></>,
    locker:<><rect x="6" y="3" width="12" height="18" rx="2"/><path d="M14 10.5v3"/><circle cx="14" cy="9" r="1"/></>,
    club:<><path d="M9 4v11a3 3 0 1 0 2 2.8"/><path d="M9 4l5 2-5 2"/></>,
    game:<><rect x="4" y="5" width="16" height="14" rx="3"/><path d="M8 12h3M9.5 10.5v3M15 11h.01M17 13h.01"/></>,
    settings:<><circle cx="12" cy="12" r="3"/><path d="M12 3v3M12 18v3M4.2 12h3M16.8 12h3M5.6 5.6l2.1 2.1M16.3 16.3l2.1 2.1M18.4 5.6l-2.1 2.1M7.7 16.3l-2.1 2.1"/></>,
  }[type];
  return (
    <div style={{width:40,height:40,borderRadius:11,background:c+"1A",display:"flex",alignItems:"center",justifyContent:"center",flexShrink:0}}>
      <svg viewBox="0 0 24 24" width={size} height={size} fill="none" stroke={c} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">{g}</svg>
    </div>
  );
}

// 토글 스위치
function Switch({ on, onChange }){
  return (
    <button onClick={onChange} style={{width:42,height:25,borderRadius:13,background:on?"var(--primary)":"#D1D5DB",position:"relative",border:"none",flexShrink:0,transition:"background .15s"}}>
      <span style={{position:"absolute",top:2.5,left:on?19.5:2.5,width:20,height:20,borderRadius:"50%",background:"#fff",boxShadow:"0 1px 2px rgba(0,0,0,.25)",transition:"left .15s"}}/>
    </button>
  );
}

function MenuScreen({ onBack, onOpenBooking, onOpenTicket, onOpenGift, onOpenPoints, onOpenNoShow, onOpenReport, onOpenCert, onOpenBuyTicket, onOpenLocker, onOpenClub, onOpenAttendance, onOpenGameSettings, onOpenAppSettings, onOpenSubscribe, subActive, onOpenProfile }){
  const [hasRes, setHasRes] = React.useState(true); // 데모: 다가오는 예약 유무

  const groups = [
    {title:"MY", items:[
      {label:"구독 관리", type:"star", onClick:onOpenSubscribe, badge:subActive?"구독중":"미구독"},
      {label:"예약 내역", type:"calendar", onClick:onOpenBooking},
      {label:"이용권 관리", type:"ticket", onClick:onOpenTicket},
      {label:"이용권 선물하기", type:"gift", onClick:onOpenGift},
      {label:"포인트 · 캐시", type:"won", onClick:onOpenPoints},
      {label:"노쇼 현황", type:"noshow", onClick:onOpenNoShow},
    ]},
    {title:"스크린", items:[
      {label:"라운드 기록", type:"scorecard", onClick:onOpenReport},
      {label:"증서 관리", type:"cert", onClick:onOpenCert},
    ]},
    {title:"트레이닝", items:[
      {label:"출석 체크", type:"attend", onClick:onOpenAttendance},
      {label:"이용권 구매", type:"buy", onClick:onOpenBuyTicket},
      {label:"라커 관리", type:"locker", onClick:onOpenLocker},
      {label:"클럽 측정", type:"club", onClick:onOpenClub},
    ]},
    {title:"설정", items:[
      {label:"게임 설정", type:"game", onClick:onOpenGameSettings},
      {label:"앱 설정", type:"settings", onClick:onOpenAppSettings},
    ]},
  ];

  return (
    <div className="screen navy-top" style={{background:"#1A1C1F"}}>
      <StatusBar onNavy/>
      {/* 다크 헤더 — 프로필 (.screen padding-top:48이 상태바 아래로 자동 배치) */}
      <div style={{color:"#fff"}}>
        <div style={{padding:"2px 18px 0",display:"flex",alignItems:"center",justifyContent:"space-between"}}>
          <div style={{display:"flex",alignItems:"center",gap:12}}>
            <div style={{width:40,height:40,borderRadius:"50%",background:"#fff",display:"flex",alignItems:"center",justifyContent:"center",fontSize:20}}>🐻</div>
            <div style={{fontSize:19,fontWeight:800,letterSpacing:"-.02em"}}>라이언</div>
          </div>
          <button onClick={onBack} style={{background:"transparent",color:"#fff",padding:6}}><Icon name="x" size={22}/></button>
        </div>
        <div style={{padding:"12px 18px 14px",display:"flex",gap:8}}>
          <button onClick={onOpenProfile} style={{fontSize:12.5,fontWeight:600,color:"#fff",background:"transparent",border:"1px solid rgba(255,255,255,.3)",borderRadius:8,padding:"8px 12px"}}>내 정보 수정하기</button>
          <button onClick={onOpenPoints} style={{fontSize:12.5,fontWeight:600,color:"#fff",background:"rgba(255,255,255,.12)",border:"none",borderRadius:8,padding:"8px 12px"}}>보유 <b>2,800C</b> · <b>170P</b></button>
        </div>
      </div>

      {/* 다가오는 예약 배너 — 예약 있을 때만 (우측 이미지) */}
      {hasRes && (
        <button onClick={onOpenBooking} style={{width:"100%",background:"var(--primary)",color:"#fff",border:"none",padding:"16px 20px",display:"flex",alignItems:"center",gap:10,textAlign:"left"}}>
          <Icon name="bell" size={18}/>
          <span style={{flex:1,fontSize:15,fontWeight:800,letterSpacing:"-.01em"}}>다가오는 예약이 있어요!</span>
          <span style={{fontSize:14,fontWeight:800}}>3월 11일</span>
          <Icon name="chev-r" size={16}/>
        </button>
      )}

      <div className="scroll" style={{background:"#fff",padding:"0 0 40px"}}>
        {/* 데모: 예약 유무 토글 */}
        <div style={{display:"flex",justifyContent:"flex-end",padding:"8px 16px 0"}}>
          <button onClick={()=>setHasRes(v=>!v)} style={{fontSize:9,color:"var(--text-mute)",background:"transparent",border:"1px dashed var(--line)",borderRadius:4,padding:"3px 6px",fontWeight:600}}>데모: 예약 {hasRes?"없음":"있음"}</button>
        </div>

        {groups.map((g,gi)=>(
          <React.Fragment key={gi}>
            {gi===1 && (
              <div style={{margin:"8px 20px 4px",borderRadius:14,overflow:"hidden",background:"linear-gradient(110deg,#FDE047 0%,#FACC15 100%)",position:"relative",height:96,display:"flex",alignItems:"center",padding:"0 20px"}}>
                <div>
                  <div style={{fontSize:13,fontWeight:600,color:"#713F12"}}>주목도 높은 골퍼 타겟 광고</div>
                  <div style={{fontSize:17,fontWeight:800,color:"#422006",marginTop:2,letterSpacing:"-.02em"}}>카카오 VX 광고가 답이에요!</div>
                </div>
                <svg viewBox="0 0 80 60" width="80" height="60" style={{position:"absolute",right:14,bottom:8}}><ellipse cx="40" cy="52" rx="38" ry="7" fill="#16A34A"/><rect x="20" y="30" width="34" height="14" rx="3" fill="#1F2937"/><circle cx="28" cy="46" r="5" fill="#111827"/><circle cx="48" cy="46" r="5" fill="#111827"/><path d="M54 32l8-3v15h-8z" fill="#374151"/></svg>
              </div>
            )}
            {gi>1 && <div style={{height:1,background:"var(--line)",margin:"6px 20px"}}/>}
            <div style={{padding:"16px 20px 2px",fontSize:17,fontWeight:800,letterSpacing:"-.02em"}}>{g.title}</div>
            {g.items.map((it,j)=>(
              <button key={j} onClick={it.onClick} style={{display:"flex",alignItems:"center",gap:14,width:"100%",textAlign:"left",padding:"13px 20px",background:"transparent"}}>
                <MIcon type={it.type}/>
                <div style={{flex:1,fontSize:15,fontWeight:600}}>{it.label}</div>
                {it.badge && <span style={{fontSize:11,fontWeight:700,padding:"3px 8px",borderRadius:6,background:it.badge==="구독중"?"var(--primary-tint)":"var(--bg-soft)",color:it.badge==="구독중"?"var(--primary)":"var(--text-mute)"}}>{it.badge}</span>}
                <Icon name="chev-r" size={15} style={{color:"var(--text-mute)"}}/>
              </button>
            ))}
          </React.Fragment>
        ))}
      </div>
    </div>
  );
}

// 포인트 · 캐시 (적립/이용 내역)
function PointsCash({ onBack }){
  const [tab, setTab] = React.useState("all");
  const tx = [
    {d:"03.10", t:"스크린 예약 결제", amt:"-1,000C", kind:"use"},
    {d:"03.08", t:"라운드 적립", amt:"+50P", kind:"earn"},
    {d:"03.02", t:"캐시 충전", amt:"+5,000C", kind:"earn"},
    {d:"02.27", t:"이벤트 적립", amt:"+120P", kind:"earn"},
    {d:"02.20", t:"트레이닝 이용권 결제", amt:"-3,200C", kind:"use"},
  ];
  const rows = tx.filter(r=> tab==="all" || (tab==="earn"?r.kind==="earn":r.kind==="use"));
  return (
    <div className="screen">
      <StatusBar/>
      <Appbar title="포인트 · 캐시" onBack={onBack}/>
      <div className="scroll" style={{paddingBottom:30}}>
        <div style={{display:"flex",gap:10,padding:"12px 20px"}}>
          {[["캐시","2,800","C"],["포인트","170","P"]].map(([k,v,u],i)=>(
            <div key={i} className="card" style={{flex:1,padding:"16px"}}>
              <div style={{fontSize:12,color:"var(--text-sub)",fontWeight:600}}>{k}</div>
              <div style={{fontSize:24,fontWeight:800,marginTop:4,letterSpacing:"-.02em"}}>{v}<span style={{fontSize:14,fontWeight:700,marginLeft:1}}>{u}</span></div>
            </div>
          ))}
        </div>
        <div style={{padding:"0 20px",borderBottom:"1px solid var(--line)",display:"flex",gap:20}}>
          {[["all","전체"],["earn","적립"],["use","사용"]].map(([k,v])=>(
            <button key={k} onClick={()=>setTab(k)} style={{padding:"12px 0",fontSize:14,fontWeight:700,background:"transparent",color:tab===k?"var(--text)":"var(--text-mute)",borderBottom:tab===k?"2px solid var(--text)":"2px solid transparent",marginBottom:-1}}>{v}</button>
          ))}
        </div>
        {rows.map((r,i)=>(
          <div key={i} style={{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"15px 20px",borderBottom:"1px solid var(--line)"}}>
            <div>
              <div style={{fontSize:14,fontWeight:600}}>{r.t}</div>
              <div className="mono" style={{fontSize:11,color:"var(--text-sub)",marginTop:3}}>{r.d}</div>
            </div>
            <div className="mono" style={{fontSize:15,fontWeight:800,color:r.kind==="earn"?"var(--primary)":"var(--text)"}}>{r.amt}</div>
          </div>
        ))}
      </div>
    </div>
  );
}

// 증서 관리 (받은 인증서)
// 증서 타입 (FS CertType: 이글/홀인원/콘도르/알바트로스 — 홀 성취) + 색/약어
const CERT_TYPES = {
  holeinone: {ko:"홀인원",   en:"HOLE IN ONE", color:"#F59E0B", tag:"1타"},
  eagle:     {ko:"이글",     en:"EAGLE",       color:"#8B5CF6", tag:"2언더"},
  albatross: {ko:"알바트로스", en:"ALBATROSS",  color:"#0EA5E9", tag:"3언더"},
  condor:    {ko:"콘도르",   en:"CONDOR",       color:"#16A34A", tag:"4언더"},
};
const CERTS = [
  {type:"holeinone", cc:"소피아그린",  course:"OUT", hole:7,  branch:"프렌즈 스크린 판교점", date:"2026.06.20", deed:"20260620-S-118", machine:"Q",  team:""},
  {type:"eagle",     cc:"비에이비스타", course:"IN",  hole:12, branch:"프렌즈 스크린 판교점", date:"2026.05.15", deed:"20260515-S-072", machine:"Q",  team:"버디사냥꾼"},
  {type:"albatross", cc:"소피아그린",  course:"OUT", hole:15, branch:"프렌즈 스크린 강남점", date:"2026.03.31", deed:"20260331-S-045", machine:"T2", team:""},
];

function Certificates({ onBack, onOpenDetail }){
  const [machine, setMachine] = React.useState("전체"); // 전체 | Q | T2 (FS: 기기 타입 필터)
  const [empty, setEmpty] = React.useState(false);
  const list = empty ? [] : CERTS.filter(c=> machine==="전체" ? true : c.machine===machine);
  const mFmt = (d)=>{ const [y,m,day]=d.split("."); return `${+m}월 ${+day}일`; };
  return (
    <div className="screen">
      <StatusBar/>
      <Appbar title="증서 관리" onBack={onBack}
        right={<button onClick={()=>setEmpty(v=>!v)} className="icon-btn" style={{fontSize:9,fontWeight:600,color:"var(--text-mute)",width:"auto",padding:"4px 6px"}}>데모:{empty?"빈":"보유"}</button>}/>
      <div className="scroll" style={{padding:"0 0 30px"}}>
        {/* 헤더 — 트로피 + 안내 */}
        <div style={{display:"flex",alignItems:"center",gap:14,padding:"18px 20px 16px",background:"linear-gradient(135deg,#1F2430 0%,#2B3242 100%)",color:"#fff"}}>
          <img src="assets/cert-01.png" alt="" style={{width:64,height:64,objectFit:"contain",flexShrink:0}}/>
          <div style={{fontSize:14,fontWeight:600,lineHeight:1.5}}>증서 이미지를 다운로드 받아서<br/>친구들에게 자랑해보세요.</div>
        </div>

        {/* 기기 타입 필터 */}
        <div style={{display:"flex",gap:6,padding:"14px 20px 6px"}}>
          {["전체","Q","T2"].map(m=>(
            <button key={m} onClick={()=>setMachine(m)} style={{fontSize:12.5,fontWeight:700,padding:"7px 15px",borderRadius:16,border:"none",background:machine===m?"var(--primary)":"var(--bg-soft)",color:machine===m?"#fff":"var(--text-sub)"}}>{m}</button>
          ))}
        </div>

        {list.length===0 ? (
          <div style={{display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",padding:"70px 0",color:"var(--text-mute)"}}>
            <img src="assets/course-empty.png" alt="" style={{width:120,opacity:.9,marginBottom:14}}/>
            <div style={{fontSize:14}}>아직 받은 인증서가 없어요.</div>
          </div>
        ) : (
          <div style={{padding:"8px 20px 0",display:"flex",flexDirection:"column",gap:12}}>
            {list.map((c,i)=>{
              const t = CERT_TYPES[c.type];
              return (
                <button key={i} onClick={()=>onOpenDetail&&onOpenDetail(c)} className="card" style={{padding:0,overflow:"hidden",display:"flex",textAlign:"left",border:"1px solid var(--line)"}}>
                  <div style={{width:6,background:t.color,flexShrink:0}}/>
                  <div style={{flex:1,padding:"15px 16px",minWidth:0}}>
                    <div style={{display:"flex",alignItems:"center",gap:6,marginBottom:6}}>
                      <span style={{width:7,height:7,borderRadius:"50%",background:t.color}}/>
                      <span style={{fontSize:11.5,fontWeight:800,color:t.color,letterSpacing:".02em"}}>{t.en}</span>
                      <span style={{fontSize:10.5,fontWeight:700,color:"var(--text-mute)",background:"var(--bg-soft)",borderRadius:4,padding:"1px 6px"}}>{c.machine}</span>
                    </div>
                    <div style={{fontSize:15,fontWeight:800,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}}>{c.cc}</div>
                    <div style={{fontSize:12.5,color:"var(--text-sub)",marginTop:2}}>{c.course} · {c.hole}H · <span className="mono">{mFmt(c.date)}</span></div>
                  </div>
                  <div style={{alignSelf:"center",marginRight:12,display:"flex",alignItems:"center",color:"var(--text-mute)"}}><Icon name="chev-r" size={16}/></div>
                </button>
              );
            })}
          </div>
        )}
      </div>
    </div>
  );
}

// 증서 상세 — 인증서 카드(템플릿 스와이프) + 저장/공유
const CERT_TPL = [
  {name:"클래식", bg:"#FFFDF6", ink:"#3A3320", accent:"#B8862F", sub:"#8A7B4E", frame:"gold"},
  {name:"그린",   bg:"#F0FDF4", ink:"#14432A", accent:"#16A34A", sub:"#4B7C5C", frame:"green"},
  {name:"네이비", bg:"#1B2233", ink:"#EAF0FF", accent:"#E5C558", sub:"#9FB0D0", frame:"dark"},
  {name:"오렌지", bg:"#FFF7ED", ink:"#5A3312", accent:"#EA580C", sub:"#A9744A", frame:"orange"},
];
function CertificateDetail({ cert, onBack }){
  const c = cert || CERTS[0];
  const t = CERT_TYPES[c.type];
  const [tpl, setTpl] = React.useState(0);
  const [toast, setToast] = React.useState(null);
  const th = CERT_TPL[tpl];
  const dark = th.frame==="dark";
  const pop = (m)=>{ setToast(m); window.clearTimeout(pop._t); pop._t=window.setTimeout(()=>setToast(null),2000); };
  const down = React.useRef(0);
  const onDown = (e)=>{ down.current = e.clientX; };
  const onUp = (e)=>{ const dx=e.clientX-down.current; if(dx<-40) setTpl(v=>(v+1)%CERT_TPL.length); else if(dx>40) setTpl(v=>(v+CERT_TPL.length-1)%CERT_TPL.length); };
  return (
    <div className="screen" style={{background:"var(--bg-soft)"}}>
      <StatusBar/>
      <Appbar title={`${t.ko} 증서`} onBack={onBack}/>
      {toast && <div className="toast"><span>{toast}</span></div>}
      <div className="scroll" style={{padding:"18px 20px 100px"}}>
        {/* 인증서 카드 */}
        <div onPointerDown={onDown} onPointerUp={onUp}
          style={{position:"relative",aspectRatio:"3/4",borderRadius:14,overflow:"hidden",background:th.bg,color:th.ink,
            boxShadow:"0 12px 30px rgba(20,25,40,.16)",border:`1px solid ${dark?"rgba(255,255,255,.12)":"rgba(0,0,0,.06)"}`,userSelect:"none",WebkitUserSelect:"none"}}>
          {/* 장식 프레임 */}
          <div style={{position:"absolute",inset:12,border:`1.5px solid ${th.accent}`,borderRadius:8,opacity:dark?.5:.6}}/>
          <div style={{position:"absolute",inset:17,border:`0.8px solid ${th.accent}`,borderRadius:6,opacity:dark?.3:.4}}/>
          <div style={{position:"relative",height:"100%",display:"flex",flexDirection:"column",alignItems:"center",padding:"30px 26px 22px",textAlign:"center"}}>
            {/* 엠블럼 */}
            <span style={{width:58,height:58,borderRadius:"50%",background:th.accent+"1F",display:"flex",alignItems:"center",justifyContent:"center",marginBottom:10}}>
              <svg viewBox="0 0 24 24" width="30" height="30" fill="none" stroke={th.accent} strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"><path d="M8 4h8v3a4 4 0 0 1-8 0z"/><path d="M8 5H5v1.5A2.5 2.5 0 0 0 8 9M16 5h3v1.5A2.5 2.5 0 0 1 16 9"/><path d="M10 12h4M12 9v6M9 19h6M12 15v4"/></svg>
            </span>
            <div style={{fontSize:11,fontWeight:800,letterSpacing:".18em",color:th.accent}}>{t.en}</div>
            <div style={{fontSize:19,fontWeight:800,marginTop:4,letterSpacing:"-.01em"}}>{t.ko} 증서</div>
            <div style={{width:38,height:2,background:th.accent,borderRadius:2,margin:"12px 0 14px",opacity:.7}}/>
            {/* 수상자 */}
            <div style={{fontSize:12.5,color:th.sub}}>{c.team && `${c.team} · `}플레이어</div>
            <div style={{fontSize:24,fontWeight:800,marginTop:3,letterSpacing:"-.02em"}}>라이언</div>
            <div style={{fontSize:12.5,color:th.sub,marginTop:10,lineHeight:1.6}}>
              위 플레이어가 <b style={{color:th.ink}}>{c.cc}</b>에서<br/>
              <b style={{color:th.ink}}>{c.course} {c.hole}번 홀 {t.ko}</b>을 달성하였기에<br/>이 증서를 수여합니다.
            </div>
            <div style={{flex:1}}/>
            {/* 서명 + 로고 */}
            <div style={{display:"flex",alignItems:"flex-end",justifyContent:"space-between",width:"100%",marginTop:14}}>
              <div style={{textAlign:"left"}}>
                <div style={{fontSize:9.5,color:th.sub}}>증서번호</div>
                <div className="mono" style={{fontSize:10.5,fontWeight:700}}>{c.deed}</div>
              </div>
              <div style={{textAlign:"right"}}>
                <img src="assets/cert-sign.png" alt="" style={{height:26,objectFit:"contain",opacity:dark?.85:.6,filter:dark?"invert(1)":"none",marginBottom:2}}/>
                <div style={{fontSize:10,fontWeight:700,color:th.accent}}>FRIENDS SCREEN</div>
              </div>
            </div>
            <div style={{display:"flex",justifyContent:"space-between",width:"100%",marginTop:8,fontSize:10.5,color:th.sub}}>
              <span>{c.branch}</span><span className="mono">{c.date}</span>
            </div>
          </div>
        </div>

        {/* 템플릿 인디케이터 */}
        <div style={{display:"flex",justifyContent:"center",alignItems:"center",gap:7,marginTop:14}}>
          {CERT_TPL.map((_,i)=>(
            <button key={i} onClick={()=>setTpl(i)} style={{width:i===tpl?18:7,height:7,borderRadius:99,border:"none",background:i===tpl?"var(--primary)":"var(--line-strong)",transition:"width .2s"}}/>
          ))}
        </div>
        <div style={{textAlign:"center",fontSize:11.5,color:"var(--text-mute)",marginTop:8}}>좌우로 넘겨 디자인을 바꿔보세요 · {th.name}</div>
      </div>

      {/* 하단 저장/공유 */}
      <div style={{position:"absolute",left:0,right:0,bottom:0,padding:"12px 20px 22px",background:"#fff",borderTop:"1px solid var(--line)",display:"flex",gap:8}}>
        <button onClick={()=>pop("갤러리에 저장했어요.")} className="btn btn-soft" style={{flex:1,height:48,display:"flex",alignItems:"center",justifyContent:"center",gap:6}}>
          <svg viewBox="0 0 20 20" width="17" height="17" fill="none" stroke="currentColor" strokeWidth="1.7"><path d="M10 3v10M6 9l4 4 4-4M4 16h12" strokeLinecap="round" strokeLinejoin="round"/></svg>저장하기
        </button>
        <button onClick={()=>pop("공유 링크를 복사했어요.")} className="btn btn-primary" style={{flex:1,height:48,display:"flex",alignItems:"center",justifyContent:"center",gap:6}}>
          <Icon name="share" size={17}/>공유
        </button>
      </div>
    </div>
  );
}

// 라커 관리 (이용 중 / 만료 임박 / 이용 완료 · 남은 기간·진행률 표시)
function LockerCard({ l }){
  // 상태별 색: 만료 임박=빨강 / 이용 중=primary / 이용 완료=뮤트
  const accent = l.soon ? "#EF4444" : (l.active ? "var(--primary)" : "var(--text-mute)");
  const tint   = l.soon ? "#FEECEC" : (l.active ? "var(--primary-tint)" : "#F1F3F5");
  const label  = l.active ? (l.soon ? "만료 임박" : "이용 중") : "이용 완료";
  const dText  = l.daysLeft===0 ? "오늘 만료" : (l.daysLeft>0 ? `${l.daysLeft}일 남음` : `${-l.daysLeft}일 전 종료`);
  return (
    <div className="card" style={{padding:0,overflow:"hidden",opacity:l.active?1:.72,borderColor:l.soon?"#F7C6C6":"var(--line)"}}>
      {/* 헤더: 상태 배지 + D-day */}
      <div style={{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"13px 16px 0"}}>
        <span style={{fontSize:11.5,fontWeight:800,padding:"3px 9px",borderRadius:5,background:tint,color:accent}}>{label}</span>
        {l.active
          ? <span style={{fontSize:12.5,fontWeight:800,color:accent}}>{l.daysLeft===0?"D-DAY":`D-${l.daysLeft}`}</span>
          : <span style={{fontSize:12,fontWeight:600,color:"var(--text-mute)"}}>{dText}</span>}
      </div>
      {/* 본문: 라커 아이콘 + 번호 + 매장 */}
      <div style={{display:"flex",alignItems:"center",gap:12,padding:"10px 16px 0"}}>
        <span style={{width:44,height:44,borderRadius:12,background:tint,display:"flex",alignItems:"center",justifyContent:"center",flexShrink:0,color:accent}}>
          <svg viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><rect x="6" y="3" width="12" height="18" rx="2"/><path d="M14 10.5v3"/><circle cx="14" cy="9" r="1"/></svg>
        </span>
        <div style={{flex:1,minWidth:0}}>
          <div style={{display:"flex",alignItems:"baseline",gap:6}}>
            <span style={{fontSize:18,fontWeight:800,letterSpacing:"-0.02em"}}>{l.no}</span>
            <span style={{fontSize:12,color:"var(--text-mute)",fontWeight:600}}>{l.plan}</span>
          </div>
          <div style={{fontSize:13.5,fontWeight:600,color:"var(--text-sub)",marginTop:2,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}}>{l.store}</div>
        </div>
      </div>
      {/* 이용 기간 */}
      <div style={{display:"flex",alignItems:"center",gap:6,padding:"11px 16px 0",color:"var(--text-sub)"}}>
        <Icon name="calendar" size={14} style={{color:"var(--text-mute)"}}/>
        <span className="mono" style={{fontSize:12}}>{l.periodText}</span>
      </div>
      {/* 진행률 바 (이용 중일 때만) + 남은 기간 */}
      {l.active ? (
        <div style={{padding:"10px 16px 14px"}}>
          <div style={{height:6,borderRadius:99,background:"#EDEFF2",overflow:"hidden"}}>
            <div style={{height:"100%",width:`${l.pct}%`,background:accent,borderRadius:99,transition:"width .3s"}}/>
          </div>
          <div style={{display:"flex",justifyContent:"space-between",marginTop:6,fontSize:11.5}}>
            <span style={{color:"var(--text-mute)"}}>{l.used} / {l.total}일 이용</span>
            <span style={{fontWeight:700,color:accent}}>{dText}</span>
          </div>
          {l.soon && (
            <button className="btn btn-primary" style={{width:"100%",marginTop:12,height:40}}>라커 연장하기</button>
          )}
        </div>
      ) : (
        <div style={{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"11px 16px 14px"}}>
          <span style={{fontSize:12,color:"var(--text-mute)"}}>이용이 종료된 라커예요.</span>
          <button style={{fontSize:12.5,fontWeight:700,color:"var(--primary)",background:"none",border:"none",display:"flex",alignItems:"center",gap:2}}>다시 신청<Icon name="chev-r" size={13}/></button>
        </div>
      )}
    </div>
  );
}

function Lockers({ onBack }){
  const DAY = 86400000;
  const today = new Date(); today.setHours(0,0,0,0);
  const fmt = (d)=>`${d.getFullYear()}.${String(d.getMonth()+1).padStart(2,"0")}.${String(d.getDate()).padStart(2,"0")}`;
  const mk = (startOff, len)=>{ const s=new Date(today.getTime()+startOff*DAY); const e=new Date(s.getTime()+(len-1)*DAY); return {s,e}; };
  const raw = [
    {store:"프렌즈 아카데미 판교점", no:"A-12", plan:"3개월권", ...mk(-41, 90)},  // 이용 중 (D-48)
    {store:"프렌즈 아카데미 판교점", no:"C-03", plan:"3개월권", ...mk(-85, 90)},  // 만료 임박 (D-4)
    {store:"프렌즈 아카데미 강남점", no:"B-08", plan:"3개월권", ...mk(-131, 90)}, // 이용 완료
  ];
  const lockers = raw.map(l=>{
    const daysLeft = Math.round((l.e - today)/DAY);
    const active = today>=l.s && daysLeft>=0;
    const total = Math.round((l.e - l.s)/DAY)+1;
    const used = Math.max(0, Math.min(total, Math.round((today - l.s)/DAY)+1));
    const pct = Math.max(2, Math.min(100, Math.round(used/total*100)));
    return {...l, daysLeft, active, total, used, pct, soon: active && daysLeft<=7, periodText:`${fmt(l.s)} ~ ${fmt(l.e)}`};
  });
  const inUse = lockers.filter(l=>l.active);
  const done  = lockers.filter(l=>!l.active);
  return (
    <div className="screen">
      <StatusBar/>
      <Appbar title="라커 관리" onBack={onBack}/>
      <div className="scroll" style={{padding:"14px 20px 30px"}}>
        {inUse.length>0 && (
          <div style={{marginBottom:20}}>
            <div style={{fontSize:13,fontWeight:700,color:"var(--text-sub)",marginBottom:10}}>이용 중 <span style={{color:"var(--primary)"}}>{inUse.length}</span></div>
            <div style={{display:"flex",flexDirection:"column",gap:12}}>
              {inUse.map((l,i)=><LockerCard key={i} l={l}/>)}
            </div>
          </div>
        )}
        {done.length>0 && (
          <div>
            <div style={{fontSize:13,fontWeight:700,color:"var(--text-sub)",marginBottom:10}}>이용 완료 <span style={{color:"var(--text-mute)"}}>{done.length}</span></div>
            <div style={{display:"flex",flexDirection:"column",gap:12}}>
              {done.map((l,i)=><LockerCard key={i} l={l}/>)}
            </div>
          </div>
        )}
        {lockers.length===0 && (
          <div style={{display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",padding:"80px 0",color:"var(--text-mute)"}}>
            <img src="assets/course-empty.png" alt="" style={{width:120,opacity:.9,marginBottom:16}}/>
            <div style={{fontSize:14}}>이용 중인 라커가 없어요.</div>
          </div>
        )}
      </div>
    </div>
  );
}

// 게임 설정 (스크린/연습 · Q/T2 기기별)
function GameSettings({ onBack }){
  const [dev, setDev] = React.useState("sQ");
  const devices = [["sQ","스크린 Q"],["sT2","스크린 T2"],["pQ","연습 Q"],["pT2","연습 T2"]];
  const [sw, setSw] = React.useState({plate:true, swingPopup:true, flag:true, putting:false});
  const t = (k)=> setSw(s=>({...s,[k]:!s[k]}));
  const selects = [
    ["클럽별 비거리","설정"],["티 높이","중"],["티 박스","자동"],["난이도","프로"],["타석","오른손"],["매트 룰","기본"],
  ];
  const toggles = [["스윙 플레이트","plate"],["나의 스윙 팝업","swingPopup"],["깃대 표시","flag"],["퍼팅 가이드","putting"]];
  return (
    <div className="screen">
      <StatusBar/>
      <Appbar title="게임 설정" onBack={onBack}/>
      <div className="scroll" style={{paddingBottom:30}}>
        <div style={{display:"flex",gap:6,padding:"12px 20px",overflowX:"auto",scrollbarWidth:"none"}}>
          {devices.map(([k,v])=>(
            <button key={k} onClick={()=>setDev(k)} style={{flexShrink:0,fontSize:12.5,fontWeight:700,padding:"7px 13px",borderRadius:16,border:"none",background:dev===k?"var(--primary)":"var(--bg-soft)",color:dev===k?"#fff":"var(--text-sub)"}}>{v}</button>
          ))}
        </div>
        {selects.map(([k,v],i)=>(
          <button key={i} style={{display:"flex",alignItems:"center",justifyContent:"space-between",width:"100%",padding:"16px 20px",background:"transparent",borderBottom:"1px solid var(--line)",textAlign:"left"}}>
            <span style={{fontSize:14,fontWeight:600}}>{k}</span>
            <span style={{display:"flex",alignItems:"center",gap:6,fontSize:13,color:"var(--text-sub)",fontWeight:600}}>{v} <Icon name="chev-r" size={14} style={{color:"var(--text-mute)"}}/></span>
          </button>
        ))}
        {toggles.map(([k,key],i)=>(
          <div key={i} style={{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"14px 20px",borderBottom:"1px solid var(--line)"}}>
            <span style={{fontSize:14,fontWeight:600}}>{k}</span>
            <Switch on={sw[key]} onChange={()=>t(key)}/>
          </div>
        ))}
        <div style={{padding:"16px 20px",fontSize:12,color:"var(--text-mute)"}}>* 설정한 값은 다음 로그인 시 반영됩니다.</div>
      </div>
    </div>
  );
}

// 앱 설정
function AppSettings({ onBack, onLogout, onSwitchService }){
  const [n, setN] = React.useState({notice:true, event:true, store:false});
  // 예약 알림 — 정책 §14 (리마인드·예약상태·결제실패·노쇼)
  const [r, setR] = React.useState({reminder:true, status:true, payfail:true, noshow:true});
  const [shake, setShake] = React.useState(true);
  const [unit, setUnit] = React.useState("m");
  const tn = (k)=> setN(s=>({...s,[k]:!s[k]}));
  const tr = (k)=> setR(s=>({...s,[k]:!s[k]}));
  return (
    <div className="screen">
      <StatusBar/>
      <Appbar title="앱 설정" onBack={onBack}/>
      <div className="scroll" style={{paddingBottom:30}}>
        {/* 예약 알림 — 정책 §14 */}
        <div style={{padding:"16px 20px 4px",fontSize:13,fontWeight:800,color:"var(--text-sub)"}}>예약 알림</div>
        <div style={{display:"flex",alignItems:"flex-start",justifyContent:"space-between",padding:"14px 20px",borderBottom:"1px solid var(--line)",gap:12}}>
          <div>
            <div style={{fontSize:14,fontWeight:600}}>예약 리마인드</div>
            <div style={{fontSize:11.5,color:"var(--text-sub)",marginTop:3,lineHeight:1.5}}>이용 시작 1시간 전 1회 자동 발송</div>
          </div>
          <Switch on={r.reminder} onChange={()=>tr("reminder")}/>
        </div>
        {[["예약 상태 알림 (완료·변경·취소)","status"],["결제 실패 알림","payfail"],["노쇼 처리 알림","noshow"]].map(([k,key])=>(
          <div key={key} style={{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"14px 20px",borderBottom:"1px solid var(--line)"}}>
            <span style={{fontSize:14,fontWeight:600}}>{k}</span>
            <Switch on={r[key]} onChange={()=>tr(key)}/>
          </div>
        ))}

        <div style={{padding:"16px 20px 4px",fontSize:13,fontWeight:800,color:"var(--text-sub)"}}>앱 푸시 알림</div>
        {[["공지 알림","notice"],["이벤트 알림","event"],["신규 매장 알림","store"]].map(([k,key])=>(
          <div key={key} style={{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"14px 20px",borderBottom:"1px solid var(--line)"}}>
            <span style={{fontSize:14,fontWeight:600}}>{k}</span>
            <Switch on={n[key]} onChange={()=>tn(key)}/>
          </div>
        ))}

        <div style={{display:"flex",alignItems:"flex-start",justifyContent:"space-between",padding:"16px 20px",borderBottom:"1px solid var(--line)",gap:12}}>
          <div>
            <div style={{fontSize:14,fontWeight:600}}>쉐이크 기능</div>
            <div style={{fontSize:11.5,color:"var(--text-sub)",marginTop:3,lineHeight:1.5}}>휴대폰을 2번 흔들어 QR코드를 스캔합니다.</div>
          </div>
          <Switch on={shake} onChange={()=>setShake(v=>!v)}/>
        </div>

        <div style={{padding:"16px 20px",borderBottom:"1px solid var(--line)"}}>
          <div style={{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:4}}>
            <div style={{fontSize:14,fontWeight:600}}>단위 설정</div>
            <div style={{display:"flex",background:"var(--bg-soft)",borderRadius:8,padding:2}}>
              {[["m","미터"],["yd","야드"]].map(([k,v])=>(
                <button key={k} onClick={()=>setUnit(k)} style={{padding:"5px 14px",borderRadius:6,fontSize:12.5,fontWeight:700,border:"none",background:unit===k?"var(--primary)":"transparent",color:unit===k?"#fff":"var(--text-sub)"}}>{v}</button>
              ))}
            </div>
          </div>
          <div style={{fontSize:11,color:"var(--text-mute)"}}>앱 내 표시되는 단위가 변경됩니다. (앱에서만 적용)</div>
        </div>

        <div style={{padding:"16px 20px 4px",fontSize:13,fontWeight:800,color:"var(--text-sub)"}}>서비스</div>
        <button onClick={onSwitchService} style={{display:"flex",alignItems:"center",justifyContent:"space-between",width:"100%",padding:"14px 20px",background:"transparent",borderBottom:"1px solid var(--line)",textAlign:"left"}}>
          <div>
            <div style={{fontSize:14,fontWeight:600}}>서비스 변경 (Q / QR)</div>
            <div style={{fontSize:11.5,color:"var(--text-sub)",marginTop:3,lineHeight:1.5}}>스크린 골프 / 연습·아카데미 선택을 다시 고릅니다.</div>
          </div>
          <Icon name="chev-r" size={14} style={{color:"var(--text-mute)"}}/>
        </button>

        <div style={{padding:"16px 20px 4px",fontSize:13,fontWeight:800,color:"var(--text-sub)"}}>공지사항</div>
        {["스크린 공지","아카데미 공지"].map((k,i)=>(
          <button key={i} style={{display:"flex",alignItems:"center",justifyContent:"space-between",width:"100%",padding:"14px 20px",background:"transparent",borderBottom:"1px solid var(--line)",textAlign:"left"}}>
            <span style={{fontSize:14,fontWeight:600}}>{k}</span>
            <Icon name="chev-r" size={14} style={{color:"var(--text-mute)"}}/>
          </button>
        ))}
        <div style={{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"14px 20px",borderBottom:"1px solid var(--line)"}}>
          <span style={{fontSize:14,fontWeight:600}}>앱 버전</span>
          <span className="mono" style={{fontSize:13,color:"var(--text-sub)"}}>v1.0.0 <span style={{color:"var(--text-mute)"}}>(최신)</span></span>
        </div>
        <button onClick={onLogout} style={{display:"block",width:"100%",padding:"18px 20px",background:"transparent",textAlign:"left",fontSize:14,fontWeight:600,color:"var(--text-sub)"}}>로그아웃</button>
      </div>
    </div>
  );
}

// 내 정보 수정
// 내 정보 — FS ProfileFragment 기준 (계정 정보·연락처·약관·탈퇴 + 편집 시트/검증)
function ProfileEdit({ onBack, onOpenAddress, onWithdraw, onOpenPassword }){
  const [nickname, setNickname] = React.useState("라이언");
  const [name, setName] = React.useState("홍길동");
  const [gender, setGender] = React.useState("남성");
  const [genderChanged, setGenderChanged] = React.useState(false); // FS: 성별 1회만 변경 가능
  const [email, setEmail] = React.useState("");   // 미입력
  const [phone, setPhone] = React.useState("");   // 미인증
  const [marketing, setMarketing] = React.useState(false);
  const [sheet, setSheet] = React.useState(null); // img | nickname | name | gender | email
  const [toast, setToast] = React.useState(null);
  const pop = (m)=>{ setToast(m); window.clearTimeout(pop._t); pop._t=window.setTimeout(()=>setToast(null),2200); };

  const terms = ["통합 이용약관","개인정보처리방침","위치기반서비스 이용약관","개인정보 제3자 제공 동의"];
  const Row = ({label, value, on, empty, badge, onClick})=> (
    <button onClick={onClick} disabled={!onClick} style={{display:"flex",alignItems:"center",justifyContent:"space-between",width:"100%",padding:"15px 20px",background:"transparent",borderBottom:"1px solid var(--line)",textAlign:"left"}}>
      <span style={{fontSize:14,color:"var(--text-sub)"}}>{label}</span>
      <span style={{display:"flex",alignItems:"center",gap:6,fontSize:14,fontWeight:600,color:empty?"var(--primary)":"var(--text)"}}>
        {value}
        {badge && <span style={{fontSize:10,fontWeight:700,color:"var(--text-mute)",border:"1px solid var(--line-strong)",borderRadius:4,padding:"1px 5px"}}>{badge}</span>}
        {onClick && <Icon name="chev-r" size={14} style={{color:"var(--text-mute)"}}/>}
      </span>
    </button>
  );

  return (
    <div className="screen">
      <StatusBar/>
      <Appbar title="내 정보" onBack={onBack}/>
      {toast && <div className="toast"><span>{toast}</span></div>}
      <div className="scroll" style={{paddingBottom:30}}>
        {/* 프로필 헤더 — 이미지 + 닉네임 */}
        <div style={{display:"flex",flexDirection:"column",alignItems:"center",padding:"22px 0 6px"}}>
          <button onClick={()=>setSheet("img")} style={{position:"relative",background:"transparent",border:"none"}}>
            <div style={{width:84,height:84,borderRadius:"50%",background:"#fff",border:"1px solid var(--line)",display:"flex",alignItems:"center",justifyContent:"center",fontSize:42}}>🐻</div>
            <span style={{position:"absolute",right:0,bottom:0,width:28,height:28,borderRadius:"50%",background:"var(--primary)",color:"#fff",display:"flex",alignItems:"center",justifyContent:"center",border:"2px solid #fff"}}><Icon name="camera" size={14}/></span>
          </button>
          <button onClick={()=>setSheet("nickname")} style={{display:"flex",alignItems:"center",gap:5,marginTop:12,background:"transparent",border:"none"}}>
            <span style={{fontSize:18,fontWeight:800,letterSpacing:"-.01em"}}>{nickname}</span>
            <Icon name="chev-r" size={15} style={{color:"var(--text-mute)"}}/>
          </button>
          <div style={{fontSize:11.5,color:"var(--primary)",fontWeight:700,marginTop:5,display:"flex",alignItems:"center",gap:3}}>
            <Icon name="check" size={12}/> 본인인증 완료
          </div>
        </div>

        {/* 계정 정보 */}
        <div style={{padding:"14px 20px 2px",fontSize:13,fontWeight:800,color:"var(--text-sub)"}}>계정 정보</div>
        <Row label="아이디" value="ryan***" badge="변경불가"/>
        <Row label="카카오 회원번호" value="1234****" badge="변경불가"/>
        <Row label="이름" value={name} onClick={()=>setSheet("name")}/>
        <Row label="성별" value={gender} onClick={()=>setSheet("gender")}/>
        <Row label="생년월일" value="1990.01.01" badge="변경불가"/>

        {/* 연락처 */}
        <div style={{padding:"16px 20px 2px",fontSize:13,fontWeight:800,color:"var(--text-sub)"}}>연락처</div>
        <Row label="핸드폰 번호" value={phone||"핸드폰 번호 입력하기"} empty={!phone} onClick={()=>{ setPhone("010-1234-5678"); pop("휴대폰 인증이 완료되었어요."); }}/>
        <Row label="이메일" value={email||"이메일 입력하기"} empty={!email} onClick={()=>setSheet("email")}/>
        <Row label="주소" value="주소 입력하기" empty onClick={onOpenAddress}/>

        {/* 설정 · 약관 */}
        <div style={{padding:"16px 20px 2px",fontSize:13,fontWeight:800,color:"var(--text-sub)"}}>설정 · 약관</div>
        <Row label="비밀번호 변경" value="" onClick={onOpenPassword||(()=>pop("비밀번호 변경은 준비 중이에요."))}/>
        <div style={{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"15px 20px",borderBottom:"1px solid var(--line)"}}>
          <span style={{fontSize:14}}>마케팅 정보 수신 동의</span>
          <Switch on={marketing} onChange={()=>{ setMarketing(v=>!v); pop(!marketing?"마케팅 수신에 동의했어요.":"마케팅 수신을 해제했어요."); }}/>
        </div>
        {terms.map((t,i)=>(
          <button key={i} onClick={()=>pop("약관 보기는 준비 중이에요.")} style={{display:"flex",alignItems:"center",justifyContent:"space-between",width:"100%",padding:"14px 20px",background:"transparent",borderBottom:"1px solid var(--line)",textAlign:"left"}}>
            <span style={{fontSize:13.5,fontWeight:600,color:"var(--text-sub)"}}>{t}</span>
            <Icon name="chev-r" size={14} style={{color:"var(--text-mute)"}}/>
          </button>
        ))}

        <button onClick={onWithdraw} style={{display:"block",margin:"20px auto 0",background:"transparent",fontSize:13,color:"var(--text-mute)",textDecoration:"underline",fontWeight:600}}>탈퇴하기</button>
      </div>

      {/* 프로필 이미지 변경 시트 */}
      {sheet==="img" && (
        <Sheet title="프로필 이미지" onClose={()=>setSheet(null)}>
          {[["사진 촬영","camera"],["나의 사진첩","image"],["카카오 프로필 사용하기","kakao"]].map(([label],i)=>(
            <button key={i} onClick={()=>{ setSheet(null); pop("프로필 이미지가 변경되었어요."); }} style={{display:"flex",alignItems:"center",width:"100%",padding:"15px 20px",background:"transparent",border:"none",borderTop:i?"1px solid var(--line)":"none",fontSize:15,fontWeight:600,textAlign:"left"}}>{label}</button>
          ))}
        </Sheet>
      )}
      {/* 텍스트 편집 시트 (닉네임/이름/이메일) */}
      {(sheet==="nickname"||sheet==="name"||sheet==="email") && (
        <ProfileEditSheet
          kind={sheet}
          initial={sheet==="nickname"?nickname:sheet==="name"?name:email}
          onClose={()=>setSheet(null)}
          onSave={(val)=>{ if(sheet==="nickname")setNickname(val); else if(sheet==="name")setName(val); else setEmail(val); setSheet(null); pop(sheet==="nickname"?"닉네임이 변경되었어요.":sheet==="name"?"이름이 변경되었어요.":"이메일이 변경되었어요."); }}/>
      )}
      {/* 성별 변경 시트 (1회 제한) */}
      {sheet==="gender" && (
        <Sheet title="성별" onClose={()=>setSheet(null)}>
          {genderChanged && <div style={{padding:"2px 20px 10px",fontSize:12.5,color:"var(--danger)"}}>성별은 한 번만 변경 가능합니다.</div>}
          {["남성","여성"].map((g,i)=>(
            <button key={g} disabled={genderChanged} onClick={()=>{ setGender(g); setGenderChanged(true); setSheet(null); pop("성별이 변경되었어요."); }}
              style={{display:"flex",alignItems:"center",justifyContent:"space-between",width:"100%",padding:"15px 20px",background:"transparent",border:"none",borderTop:i?"1px solid var(--line)":"none",fontSize:15,fontWeight:g===gender?800:500,color:genderChanged?"var(--text-mute)":(g===gender?"var(--text)":"var(--text-sub)"),textAlign:"left"}}>
              {g}{g===gender && <Icon name="check" size={18} style={{color:"var(--primary)"}}/>}
            </button>
          ))}
        </Sheet>
      )}
    </div>
  );
}

// 프로필 텍스트 편집 시트 — FS 검증 규칙(닉네임 2~12자 한글·영문·숫자 / 이메일 형식)
function ProfileEditSheet({ kind, initial, onClose, onSave }){
  const [val, setVal] = React.useState(initial||"");
  const [err, setErr] = React.useState("");
  const cfg = {
    nickname:{title:"닉네임", ph:"2~12자 한글, 영문 또는 숫자", max:12},
    name:{title:"이름", ph:"이름을 입력하세요", max:20},
    email:{title:"이메일", ph:"example@friends.com", max:40},
  }[kind];
  const validate = (v)=>{
    if(kind==="nickname"){
      if(!/^[가-힣a-zA-Z0-9]{2,12}$/.test(v)) return "2~12자 한글, 영문 또는 숫자로만 작성이 가능합니다.";
      if(v==="어피치") return "이미 사용중인 닉네임입니다."; // 데모 중복
    }
    if(kind==="email" && v && !/^[a-zA-Z0-9._-]+@([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}$/.test(v)) return "이메일 형식이 아닙니다.";
    if(kind==="name" && !v.trim()) return "이름을 입력하세요.";
    return "";
  };
  const submit = ()=>{ const e=validate(val.trim()); if(e){ setErr(e); return; } onSave(val.trim()); };
  return (
    <Sheet title={cfg.title} onClose={onClose}
      footer={<button onClick={submit} className="btn btn-primary" style={{width:"100%",height:48}}>저장</button>}>
      <div style={{padding:"6px 20px 8px"}}>
        <input autoFocus value={val} maxLength={cfg.max} onChange={e=>{ setVal(e.target.value); if(err) setErr(""); }}
          placeholder={cfg.ph}
          style={{width:"100%",height:48,border:`1.5px solid ${err?"var(--danger)":"var(--line-strong)"}`,borderRadius:10,padding:"0 14px",fontSize:15,outline:"none"}}/>
        <div style={{display:"flex",justifyContent:"space-between",marginTop:7,minHeight:16}}>
          <span style={{fontSize:12,color:"var(--danger)"}}>{err}</span>
          {kind!=="email" && <span style={{fontSize:12,color:"var(--text-mute)"}}>{val.length}/{cfg.max}</span>}
        </div>
      </div>
    </Sheet>
  );
}

// 출석 체크 — 정책 §8 (일별·월별 출석체크, 연습장 · 앱 리텐션 목적)
// 매장 QR 체크인 시 자동으로 출석이 기록됨 → 월별 캘린더 + 연속/누적 출석 + 리텐션 목표
function Attendance({ onBack }){
  const base = new Date(2024, 3, 1); // 데모 기준 월: 2024년 4월
  const todayD = 16;                  // 데모 '오늘' 날짜
  const [offset, setOffset] = React.useState(0); // 0 = 기준 월
  const view = new Date(base.getFullYear(), base.getMonth() + offset, 1);
  const year = view.getFullYear(), month = view.getMonth();
  const daysInMonth = new Date(year, month + 1, 0).getDate();
  const firstDow = new Date(year, month, 1).getDay();
  const isCurrent = offset === 0;

  // 출석 일자 집합 (데모) — 실제로는 QR 체크인 이력에서 집계
  const attended = React.useMemo(()=>{
    const set = new Set();
    const last = isCurrent ? todayD : daysInMonth;
    for (let d=1; d<=last; d++){ if (((d*7 + month*3) % 5) < 3) set.add(d); }
    return set;
  }, [year, month, isCurrent]);

  const monthCount = attended.size;
  const streak = (()=>{ let s=0, d=isCurrent?todayD:daysInMonth; while(d>=1 && !attended.has(d)) d--; while(d>=1 && attended.has(d)){ s++; d--; } return s; })();
  const cumulative = 112 + monthCount; // 데모 누적
  const GOAL = 15;
  const goalPct = Math.min(100, Math.round(monthCount/GOAL*100));

  const WD = ["일","월","화","수","목","금","토"];
  const cells = [];
  for (let i=0;i<firstDow;i++) cells.push(null);
  for (let d=1; d<=daysInMonth; d++) cells.push(d);
  const recent = [...attended].sort((a,b)=>b-a).slice(0,3);

  return (
    <div className="screen">
      <StatusBar/>
      <Appbar title="출석 체크" onBack={onBack}/>
      <div className="scroll" style={{paddingBottom:30}}>

        {/* 요약 카드 — 이번 달 출석 / 연속 / 누적 */}
        <div style={{padding:"14px 20px 4px"}}>
          <div style={{borderRadius:14,padding:"18px",background:"linear-gradient(135deg,#16A34A,#22C55E)",color:"#fff"}}>
            <div style={{fontSize:12,fontWeight:600,opacity:.9}}>이번 달 출석</div>
            <div style={{display:"flex",alignItems:"baseline",gap:4,marginTop:2}}>
              <span style={{fontSize:30,fontWeight:800,letterSpacing:"-.02em"}}>{monthCount}</span>
              <span style={{fontSize:14,fontWeight:700}}>일</span>
            </div>
            <div style={{display:"flex",marginTop:14,paddingTop:14,borderTop:"1px solid rgba(255,255,255,.25)"}}>
              <div style={{flex:1}}>
                <div style={{fontSize:11,opacity:.85}}>연속 출석</div>
                <div style={{fontSize:18,fontWeight:800,marginTop:2}}>🔥 {streak}일</div>
              </div>
              <div style={{width:1,background:"rgba(255,255,255,.25)"}}/>
              <div style={{flex:1,paddingLeft:16}}>
                <div style={{fontSize:11,opacity:.85}}>누적 출석</div>
                <div style={{fontSize:18,fontWeight:800,marginTop:2}}>{cumulative}일</div>
              </div>
            </div>
          </div>
        </div>

        {/* 리텐션 목표 — 이번 달 N일 출석 시 무료 연습권 */}
        <div style={{padding:"12px 20px 4px"}}>
          <div className="card" style={{padding:"14px 16px"}}>
            <div style={{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:8}}>
              <span style={{fontSize:13,fontWeight:700}}>이번 달 {GOAL}일 출석 시 <span style={{color:"var(--primary)"}}>무료 연습권</span></span>
              <span style={{fontSize:12,fontWeight:700,color:"var(--text-sub)"}}>{monthCount}/{GOAL}일</span>
            </div>
            <div className="ubar"><span style={{width:goalPct+"%"}}/></div>
            <div style={{fontSize:11,color:"var(--text-mute)",marginTop:8}}>
              {monthCount>=GOAL ? "목표 달성! 무료 연습권이 지급되었어요." : `${GOAL-monthCount}일 더 출석하면 무료 연습권을 받아요.`}
            </div>
          </div>
        </div>

        {/* 월 네비 + 출석 캘린더 */}
        <div style={{padding:"14px 20px 4px"}}>
          <div style={{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:12}}>
            <button onClick={()=>setOffset(o=>o-1)} className="icon-btn" style={{width:32,height:32}}><Icon name="back" size={18}/></button>
            <div style={{fontSize:15,fontWeight:800}}>{year}년 {month+1}월</div>
            <button onClick={()=>setOffset(o=>Math.min(0,o+1))} disabled={isCurrent} className="icon-btn" style={{width:32,height:32,opacity:isCurrent?.3:1}}><Icon name="chev-r" size={18}/></button>
          </div>
          <div style={{display:"grid",gridTemplateColumns:"repeat(7,1fr)",gap:6,marginBottom:6}}>
            {WD.map((w,i)=><div key={w} style={{textAlign:"center",fontSize:11,fontWeight:600,color:i===0?"#EF4444":i===6?"#3B82F6":"var(--text-mute)"}}>{w}</div>)}
          </div>
          <div style={{display:"grid",gridTemplateColumns:"repeat(7,1fr)",gap:6}}>
            {cells.map((d,i)=>{
              if (d===null) return <div key={"b"+i}/>;
              const on = attended.has(d);
              const isToday = isCurrent && d===todayD;
              const future = isCurrent && d>todayD;
              return (
                <div key={d} style={{aspectRatio:"1",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",
                  borderRadius:10, background:on?"var(--primary)":"transparent",
                  border:(isToday&&!on)?"1.5px solid var(--primary)":"1.5px solid transparent",
                  color:on?"#fff":(future?"var(--text-mute)":"var(--text)")}}>
                  <span style={{fontSize:13,fontWeight:on?800:500}}>{d}</span>
                  {on && <Icon name="check" size={10} stroke={3} style={{marginTop:1}}/>}
                </div>
              );
            })}
          </div>
        </div>

        {/* QR 체크인 자동 기록 안내 — 정책 §8 */}
        <div style={{padding:"14px 20px 0"}}>
          <div style={{display:"flex",gap:8,alignItems:"flex-start",padding:"12px 14px",background:"var(--bg-soft)",borderRadius:10,fontSize:12,color:"var(--text-sub)",lineHeight:1.5}}>
            <Icon name="qr" size={15} style={{color:"var(--primary)",marginTop:1,flexShrink:0}}/>
            <span>매장 도착 후 <b style={{color:"var(--text)"}}>QR 체크인</b>하면 출석이 자동으로 기록돼요. 별도 출석 버튼은 필요 없어요.</span>
          </div>
        </div>

        {/* 최근 출석 */}
        <div style={{padding:"18px 20px 4px"}}>
          <div className="h3" style={{fontSize:15,marginBottom:8}}>최근 출석</div>
          {recent.length===0 ? (
            <div style={{padding:"18px 0",textAlign:"center",fontSize:13,color:"var(--text-mute)"}}>이번 달 출석 기록이 없어요.</div>
          ) : recent.map(d=>(
            <div key={d} style={{display:"flex",alignItems:"center",gap:12,padding:"12px 0",borderBottom:"1px solid var(--line)"}}>
              <div style={{width:38,height:38,borderRadius:10,background:"var(--primary-tint)",color:"var(--primary)",display:"flex",alignItems:"center",justifyContent:"center",flexShrink:0}}>
                <Icon name="check" size={18} stroke={2.6}/>
              </div>
              <div style={{flex:1}}>
                <div style={{fontSize:14,fontWeight:700}}>{month+1}월 {d}일 출석</div>
                <div style={{fontSize:12,color:"var(--text-sub)",marginTop:2}}>퀀텀 아카데미 판교점 · 연습 60분</div>
              </div>
            </div>
          ))}
        </div>

      </div>
    </div>
  );
}

// 노쇼 현황 — 정책 §7·§12 (회원 기준 누적 노쇼 카운트 + 반복 노쇼 시 선결제 전환)
function NoShowStatus({ onBack }){
  const LIMIT = 3; // 선결제 전환 기준 (점주 옵션, 기본 3회)
  const [count, setCount] = React.useState(2); // 데모
  const converted = count >= LIMIT;
  const accent = converted ? "var(--danger)" : (count>0 ? "#D97706" : "var(--primary)");
  const history = [
    {d:"2024.12.18", store:"퀀텀 아카데미 판교점", item:"로엘이 프로 레슨 · 15분", status:"노쇼"},
    {d:"2024.11.30", store:"퀀텀 아카데미 광교점", item:"연습 타석 · 60분", status:"노쇼"},
    {d:"2024.10.12", store:"퀀텀 아카데미 판교점", item:"연습 타석 · 60분", status:"해제됨"},
  ];

  return (
    <div className="screen">
      <StatusBar/>
      <Appbar title="노쇼 현황" onBack={onBack}
        right={<button onClick={()=>setCount(c=> c>=LIMIT ? 0 : c+1)} className="icon-btn" style={{fontSize:10,fontWeight:600,color:"var(--text-mute)",padding:"4px 6px",width:"auto"}}>(데모 {count}/{LIMIT})</button>}/>
      <div className="scroll" style={{paddingBottom:30}}>
        {/* 상태 카드 */}
        <div style={{padding:"14px 20px 4px"}}>
          <div className="card" style={{padding:"20px 18px",textAlign:"center"}}>
            <div style={{fontSize:12,color:"var(--text-sub)",fontWeight:600}}>누적 노쇼</div>
            <div style={{display:"flex",alignItems:"baseline",justifyContent:"center",gap:3,marginTop:4}}>
              <span style={{fontSize:34,fontWeight:800,color:accent,letterSpacing:"-.02em"}}>{count}</span>
              <span style={{fontSize:15,fontWeight:700,color:"var(--text-mute)"}}>/ {LIMIT}회</span>
            </div>
            <div style={{display:"flex",gap:8,justifyContent:"center",margin:"14px 0 12px"}}>
              {Array.from({length:LIMIT}).map((_,i)=>(
                <div key={i} style={{width:36,height:6,borderRadius:3,background:i<count?accent:"var(--line)"}}/>
              ))}
            </div>
            <span style={{display:"inline-flex",alignItems:"center",gap:5,padding:"6px 12px",borderRadius:999,fontSize:12.5,fontWeight:700,
              background: converted?"#FEECEA":"var(--primary-tint)", color: converted?"var(--danger)":"var(--primary)"}}>
              {converted ? "선결제 전환됨" : "정상 이용 중"}
            </span>
            <div style={{fontSize:12.5,color:"var(--text-sub)",lineHeight:1.6,marginTop:12}}>
              {converted
                ? <>반복 노쇼(누적 {LIMIT}회)로 <b style={{color:"var(--text)"}}>예약 시 사전 결제가 필요</b>해요. 노쇼 해제는 매장에서 처리할 수 있어요.</>
                : <>누적 노쇼가 <b style={{color:"var(--text)"}}>{LIMIT}회</b>가 되면 예약 시 사전 결제가 필요한 <b style={{color:"var(--text)"}}>선결제로 전환</b>돼요.</>}
            </div>
          </div>
        </div>

        {/* 정책 안내 */}
        <div style={{padding:"10px 20px 0"}}>
          <div style={{padding:"14px 16px",background:"var(--bg-soft)",borderRadius:10,fontSize:12,color:"var(--text-sub)",lineHeight:1.7}}>
            · 예약 시간 후 일정 시간(타석 10분·레슨 15분) 미방문 시 노쇼로 처리돼요.<br/>
            · 노쇼 시 환불 불가, 이용권 예약은 차감이 유지됩니다.<br/>
            · 누적 {LIMIT}회 시 선결제로 전환돼요. (전환 기준 횟수는 매장 설정)
          </div>
        </div>

        {/* 노쇼 이력 */}
        <div style={{padding:"18px 20px 4px"}}>
          <div className="h3" style={{fontSize:15,marginBottom:8}}>노쇼 이력</div>
          {history.map((h,i)=>{
            const released = h.status==="해제됨";
            return (
              <div key={i} style={{display:"flex",alignItems:"center",gap:12,padding:"13px 0",borderBottom:"1px solid var(--line)"}}>
                <div style={{width:38,height:38,borderRadius:10,background:released?"var(--bg-soft)":"#FEECEA",color:released?"var(--text-mute)":"var(--danger)",display:"flex",alignItems:"center",justifyContent:"center",flexShrink:0}}>
                  <Icon name={released?"check":"info"} size={18}/>
                </div>
                <div style={{flex:1}}>
                  <div style={{fontSize:14,fontWeight:700}}>{h.item}</div>
                  <div style={{fontSize:12,color:"var(--text-sub)",marginTop:2}}>{h.d} · {h.store}</div>
                </div>
                <span style={{fontSize:12,fontWeight:700,color:released?"var(--text-mute)":"var(--danger)"}}>{h.status}</span>
              </div>
            );
          })}
        </div>
      </div>
    </div>
  );
}

// 공지사항 — 목록 + 상세 (홈 퀵메뉴 · 하단 공지 카드 진입)
const NOTICE_CAT = { "점검":["#FEF3C7","#D97706"], "서비스":["#EEF2F8","#324365"], "이벤트":["var(--primary-tint)","var(--primary)"] };
const catStyle = (c)=> NOTICE_CAT[c] || ["var(--bg-soft)","var(--text-sub)"];
const NOTICES = [
  {id:1, cat:"점검", title:"5월 정기점검 안내", date:"2026.05.10",
    body:"안정적인 서비스 제공을 위해 아래 일정으로 시스템 정기점검을 진행합니다.\n\n· 일시: 5월 14일(수) 03:00 ~ 05:00\n· 영향: 점검 시간 동안 앱 예약·결제가 일시 중단됩니다.\n\n이용에 참고 부탁드립니다."},
  {id:2, cat:"서비스", title:"신규 프로 입사 — 김지수 프로 광교점 합류", date:"2026.05.02",
    body:"광교점에 김지수 프로가 새롭게 합류했습니다.\n\nKPGA 투어 경력의 김지수 프로에게 스윙 교정·실전 라운드 레슨을 받아보세요. 레슨 예약은 홈 > 레슨 예약에서 하실 수 있습니다."},
  {id:3, cat:"이벤트", title:"신제품 Quantum 라운드 30% 할인", date:"2026.04.28",
    body:"신제품 Quantum 타석에서 즐기는 라운드를 30% 할인가에 만나보세요.\n\n· 기간: 4월 28일 ~ 5월 31일\n· 대상: 전 매장 Quantum 타석 예약 건\n\n자세한 내용은 이벤트 페이지에서 확인해 주세요."},
  {id:4, cat:"서비스", title:"개인정보 처리방침 개정 안내", date:"2026.04.15",
    body:"개인정보 처리방침이 2026년 5월 1일자로 개정됩니다. 주요 변경 사항은 수집 항목 및 보관 기간 조정입니다. 자세한 내용은 설정 > 약관 및 정책에서 확인하실 수 있습니다."},
  {id:5, cat:"점검", title:"앱 신규 버전 업데이트 안내", date:"2026.04.01",
    body:"더 편리해진 예약 경험을 위해 앱이 업데이트되었습니다. 스토어에서 최신 버전으로 업데이트해 주세요."},
];
function NoticeScreen({ onBack, onOpenDetail }){
  const [cat, setCat] = React.useState("전체");
  const cats = ["전체","점검","서비스","이벤트"];
  const shown = cat==="전체" ? NOTICES : NOTICES.filter(n=>n.cat===cat);
  return (
    <div className="screen">
      <StatusBar/>
      <Appbar title="공지사항" onBack={onBack}/>
      <div style={{display:"flex",gap:8,padding:"6px 16px 10px",overflowX:"auto",scrollbarWidth:"none",borderBottom:"1px solid var(--line)"}}>
        {cats.map(c=>(
          <button key={c} onClick={()=>setCat(c)} style={{flexShrink:0,padding:"7px 14px",borderRadius:999,fontSize:13,fontWeight:700,background:cat===c?"#1A1C1F":"#fff",color:cat===c?"#fff":"var(--text-sub)",border:"1px solid "+(cat===c?"#1A1C1F":"var(--line)")}}>{c}</button>
        ))}
      </div>
      <div className="scroll">
        {shown.map(n=>{
          const [bg,fg] = catStyle(n.cat);
          return (
            <button key={n.id} onClick={()=>onOpenDetail(n)} style={{display:"block",width:"100%",textAlign:"left",padding:"16px 20px",borderBottom:"1px solid var(--line)",background:"transparent"}}>
              <div style={{display:"flex",alignItems:"center",gap:6,marginBottom:6}}>
                <span style={{fontSize:11,fontWeight:700,padding:"2px 8px",borderRadius:5,background:bg,color:fg}}>{n.cat}</span>
                <span style={{fontSize:11.5,color:"var(--text-mute)"}}>{n.date}</span>
              </div>
              <div style={{fontSize:14.5,fontWeight:700,letterSpacing:"-.01em",lineHeight:1.4,color:"var(--text)"}}>{n.title}</div>
            </button>
          );
        })}
        {shown.length===0 && <div style={{padding:"60px 20px",textAlign:"center",fontSize:13,color:"var(--text-mute)"}}>해당 공지가 없어요.</div>}
      </div>
    </div>
  );
}
function NoticeDetail({ onBack, notice }){
  const n = notice || {cat:"공지", title:"공지사항", date:"", body:""};
  const [bg,fg] = catStyle(n.cat);
  return (
    <div className="screen">
      <StatusBar/>
      <Appbar title="공지사항" onBack={onBack}/>
      <div className="scroll" style={{padding:"20px 20px 40px"}}>
        <span style={{fontSize:11,fontWeight:700,padding:"2px 8px",borderRadius:5,background:bg,color:fg}}>{n.cat}</span>
        <div style={{fontSize:19,fontWeight:800,letterSpacing:"-.02em",lineHeight:1.4,marginTop:10}}>{n.title}</div>
        <div style={{fontSize:12.5,color:"var(--text-mute)",marginTop:6}}>{n.date}</div>
        <div style={{height:1,background:"var(--line)",margin:"16px 0"}}/>
        <div style={{fontSize:14,color:"var(--text-sub)",lineHeight:1.75,whiteSpace:"pre-line"}}>{n.body}</div>
      </div>
    </div>
  );
}

// ===== 코스 소개 (홈 [코스] 퀵메뉴 → 목록 · 상세) — Figma 01.2/05.더보기 코스소개 =====
const CO_TEES = [
  {k:"Black",  c:"#111827", ab:"B", txt:"#fff", total:"6076m"},
  {k:"Blue",   c:"#2563EB", ab:"B", txt:"#fff", total:"5773m"},
  {k:"White",  c:"#E5E7EB", ab:"W", txt:"#374151", total:"5417m"},
  {k:"Yellow", c:"#F59E0B", ab:"Y", txt:"#fff", total:"4848m"},
  {k:"Red",    c:"#EF4444", ab:"R", txt:"#fff", total:"4203m"},
];
const CO_PARS = [4,3,5,3,4,5,3,4,4, 4,4,3,4,5,4,3,5,4];
const coDist = (hole, ti)=>{ const base={3:180,4:393,5:530}[CO_PARS[hole-1]]; const step=[0,18,38,70,108]; return base - step[ti] + ((hole*13)%20) - 10; };
const COURSES = [
  {id:1, name:"롯데스카이힐 부여", region:"전라도", sub:"계백장군, 의자왕",       machine:"Q",  cl:2, gl:3, holes:18},
  {id:2, name:"가야 컨트리클럽",   region:"수도권", sub:"신어, 낙동, 가락",       machine:"T2", cl:3, gl:3, holes:18},
  {id:3, name:"소피아그린 CC",     region:"강원도", sub:"레이크, 마운틴",         machine:"Q",  cl:4, gl:2, holes:18},
  {id:4, name:"뉴 스프링빌",       region:"경상도", sub:"록키, 올림프스",         machine:"Q",  cl:3, gl:4, holes:18},
  {id:5, name:"비에이비스타",      region:"제주도", sub:"오션, 힐",               machine:"T2", cl:2, gl:2, holes:9},
  {id:6, name:"서산수 CC",         region:"충청도", sub:"서, 산, 수",             machine:"Q",  cl:5, gl:3, holes:18},
];
const CO_REGIONS = [["전국",432],["수도권",123],["강원도",43],["충청도",432],["경상도",123],["전라도",43],["제주도",432],["해외",123]];
const CO_LEVELS = ["전체","매우 어려움","어려움","보통","쉬움","매우 쉬움"]; // 인덱스 0=전체, 5=매우쉬움(=난이도 1)
const CO_SORTS = ["최신순","마감임박순"];
// 난이도 도트
const CoDots = ({ n, color })=>(
  <span style={{display:"inline-flex",gap:3,verticalAlign:"middle"}}>
    {[0,1,2,3,4].map(i=><span key={i} style={{width:7,height:7,borderRadius:"50%",background:i<n?color:"var(--line-strong)"}}/>)}
  </span>
);
// 즐겨찾기 별
const CoStar = ({ on, color="#22C55E" })=> on
  ? <svg viewBox="0 0 24 24" width="21" height="21" fill={color}><path d="M12 2.4l2.9 6.1 6.7.6-5.1 4.4 1.6 6.5L12 17.1 5.9 20l1.6-6.5L2.4 9.1l6.7-.6z"/></svg>
  : <svg viewBox="0 0 24 24" width="21" height="21" fill="none" stroke="#CBD5E1" strokeWidth="1.7"><path d="M12 3.6l2.6 5.5 6 .5-4.5 3.9 1.4 5.9L12 16.9 6.5 19.3l1.4-5.9L3.4 9.6l6-.5z" strokeLinejoin="round"/></svg>;
// 홀 맵 (스타일라이즈 SVG — 실제 코스 렌더 에셋으로 교체 가능)
function HoleMap(){
  return (
    <svg viewBox="0 0 100 138" width="100%" height="100%" preserveAspectRatio="none" style={{display:"block"}}>
      <rect width="100" height="138" fill="#15803D"/>
      <path d="M36 134 Q27 104 45 84 Q64 62 53 40 Q49 24 60 10 Q73 18 68 42 Q60 74 52 96 Q45 118 47 134 Z" fill="#4ADE80"/>
      <path d="M40 132 Q32 104 48 86 Q66 64 55 42 Q51 26 61 13" fill="none" stroke="#E5E7EB" strokeWidth="2.4" opacity=".65"/>
      <ellipse cx="61" cy="15" rx="12" ry="9" fill="#86EFAC"/>
      <path d="M61 15v-6l4 1.6-4 1.6" fill="#DC2626"/>
      <ellipse cx="41" cy="70" rx="6" ry="4" fill="#FDE68A"/>
      <ellipse cx="66" cy="48" rx="4.2" ry="3" fill="#FDE68A"/>
      <path d="M36 134 Q27 104 45 84 Q64 62 53 40 Q49 24 60 10" fill="none" stroke="#B91C1C" strokeWidth="1.4" opacity=".55"/>
    </svg>
  );
}

// 검색 결과 없음 캐릭터 — Figma 디자인 에셋(Empty_chun)
function CoEmptyChar(){
  return <img src="assets/course-empty.png" alt="" style={{width:126,height:132,objectFit:"contain"}}/>;
}

function CourseIntro({ onBack, onOpenDetail }){
  const [q, setQ] = React.useState("");
  const [machine, setMachine] = React.useState("Q"); // Q | T2 (좌측 기기 선택)
  const [machineSheet, setMachineSheet] = React.useState(false);
  const [fav, setFav] = React.useState({1:true});
  const [rf, setRf] = React.useState(null);          // 라운드해본 | 라운드안해본
  const [favOnly, setFavOnly] = React.useState(false); // 즐겨찾는 필터
  const [sort, setSort] = React.useState("최신순");
  const [sortSheet, setSortSheet] = React.useState(false);
  const [flt, setFlt] = React.useState({region:"전국", cl:0, gl:0}); // 적용된 필터
  const [pending, setPending] = React.useState(null);  // 필터 시트 열림 = 편집 객체
  const [toast, setToast] = React.useState(null);
  const popToast = (m)=>{ setToast(m); window.clearTimeout(popToast._t); popToast._t=window.setTimeout(()=>setToast(null),2200); };

  const activeCnt = (flt.region!=="전국"?1:0) + (flt.cl?1:0) + (flt.gl?1:0);
  const filtered = !!q || favOnly || flt.region!=="전국" || rf || machine!=="Q";
  let list = COURSES.filter(c=>
    c.machine===machine
    && (!q || c.name.includes(q) || c.sub.includes(q))
    && (flt.region==="전국" || c.region===flt.region)
    && (!favOnly || fav[c.id]));
  if(sort==="마감임박순") list = [...list].reverse();

  const toggleFav = (id)=> setFav(f=>{ const nx={...f,[id]:!f[id]}; if(nx[id]) popToast("즐겨찾는 코스로 추가됐어요."); return nx; });
  const chip = (on)=>({flexShrink:0,display:"flex",alignItems:"center",gap:4,fontSize:13,fontWeight:on?700:600,padding:"9px 15px",borderRadius:20,border:on?"none":"1px solid var(--line-strong)",background:on?"#1A1C1F":"#fff",color:on?"#fff":"var(--text-sub)",whiteSpace:"nowrap"});

  return (
    <div className="screen">
      <StatusBar/>
      <Appbar title="코스 소개" onBack={onBack}/>
      {toast && <div className="toast"><span>{toast}</span></div>}
      <div className="scroll" style={{paddingBottom:30}}>
        {/* 필터칩 (좌우 스와이프) — 맨 좌측 기기(Q/T2) 선택 */}
        <div style={{display:"flex",gap:8,padding:"12px 20px 4px",overflowX:"auto",scrollbarWidth:"none"}}>
          <button onClick={()=>setMachineSheet(true)} style={chip(true)}>{machine} <Icon name="chev-d" size={13}/></button>
          <button onClick={()=>setPending({...flt})} style={chip(activeCnt>0)}>필터{activeCnt?` ${activeCnt}`:""} <Icon name="chev-d" size={13}/></button>
          <button onClick={()=>setRf(r=>r==="done"?null:"done")} style={chip(rf==="done")}>라운드해본</button>
          <button onClick={()=>setRf(r=>r==="undone"?null:"undone")} style={chip(rf==="undone")}>라운드안해본</button>
          <button onClick={()=>setFavOnly(v=>!v)} style={chip(favOnly)}>즐겨찾는</button>
        </div>
        {/* 검색 */}
        <div style={{padding:"6px 20px 4px"}}>
          <div style={{display:"flex",alignItems:"center",gap:8,background:"var(--bg-soft)",borderRadius:10,padding:"11px 14px"}}>
            <Icon name="search" size={16} style={{color:"var(--text-mute)"}}/>
            <input value={q} onChange={e=>setQ(e.target.value)} placeholder="검색" style={{border:"none",background:"transparent",outline:"none",fontSize:14,flex:1,minWidth:0}}/>
            {q && <button onClick={()=>setQ("")} style={{background:"var(--line-strong)",color:"#fff",width:18,height:18,borderRadius:"50%",border:"none",fontSize:10,lineHeight:1,flexShrink:0,cursor:"pointer"}}>✕</button>}
          </div>
        </div>
        {/* 카운트 + 정렬 */}
        <div style={{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"12px 20px 4px"}}>
          <span style={{fontSize:13,color:"var(--text-sub)",fontWeight:600}}>코스 {filtered?list.length:"438"}개</span>
          <button onClick={()=>setSortSheet(true)} style={{display:"flex",alignItems:"center",gap:3,fontSize:13,fontWeight:600,color:"var(--text-sub)",background:"transparent"}}>{sort} <Icon name="chev-d" size={13}/></button>
        </div>
        {/* 리스트 or 검색 결과 없음 */}
        {list.length===0 ? (
          <div style={{padding:"64px 30px",textAlign:"center"}}>
            <CoEmptyChar/>
            <div style={{fontSize:15,fontWeight:600,color:"var(--text-mute)",marginTop:18}}>검색 결과가 없어요.</div>
          </div>
        ) : list.map(c=>(
          <button key={c.id} onClick={()=>onOpenDetail(c)} style={{display:"block",width:"100%",textAlign:"left",padding:"16px 20px",background:"transparent",borderBottom:"1px solid var(--line)"}}>
            <div style={{display:"flex",justifyContent:"space-between",alignItems:"flex-start"}}>
              <div style={{fontSize:16,fontWeight:800,letterSpacing:"-.02em"}}>{c.name}</div>
              <span onClick={(e)=>{e.stopPropagation(); toggleFav(c.id);}} style={{padding:"2px 0 2px 8px",lineHeight:0}}><CoStar on={!!fav[c.id]}/></span>
            </div>
            <div style={{fontSize:12.5,color:"var(--text-sub)",margin:"7px 0 10px"}}>{c.sub} ({c.holes}H)</div>
            <div style={{display:"flex",alignItems:"center",gap:10,fontSize:12,color:"var(--text-sub)",fontWeight:600}}>
              <span style={{display:"inline-flex",alignItems:"center",gap:6}}>코스 <CoDots n={c.cl} color="#22C55E"/></span>
              <span style={{width:1,height:10,background:"var(--line-strong)"}}/>
              <span style={{display:"inline-flex",alignItems:"center",gap:6}}>그린 <CoDots n={c.gl} color="#22C55E"/></span>
              <span style={{marginLeft:"auto",color:"var(--text-mute)"}}>{c.region}</span>
            </div>
          </button>
        ))}
      </div>

      {/* 기기(Q/T2) 선택 바텀시트 */}
      {machineSheet && (
        <Sheet title="기기 선택" onClose={()=>setMachineSheet(false)}>
          {["Q","T2"].map(m=><SheetItem key={m} label={m} sub={m==="Q"?"퀀텀":"트레이닝2"} on={machine===m} onClick={()=>{setMachine(m); setMachineSheet(false);}}/>)}
        </Sheet>
      )}
      {/* 정렬 바텀시트 */}
      {sortSheet && (
        <Sheet title="정렬" onClose={()=>setSortSheet(false)}>
          {CO_SORTS.map(s=><SheetItem key={s} label={s} on={sort===s} onClick={()=>{setSort(s); setSortSheet(false);}}/>)}
        </Sheet>
      )}
      {/* 코스 필터 바텀시트 */}
      {pending && (
        <Sheet title="코스 필터" onClose={()=>setPending(null)}
          footer={<button className="btn btn-primary" style={{width:"100%"}} onClick={()=>{setFlt(pending); setPending(null);}}>적용</button>}>
          <FilterGroup title="지역">
            {CO_REGIONS.map(([r,n])=>(<FChip key={r} label={`${r} (${n})`} on={pending.region===r} onClick={()=>setPending(p=>({...p,region:r}))}/>))}
          </FilterGroup>
          <FilterGroup title="코스 난이도">
            {CO_LEVELS.map((l,i)=>(<FChip key={l} label={l} on={pending.cl===i} onClick={()=>setPending(p=>({...p,cl:i}))}/>))}
          </FilterGroup>
          <FilterGroup title="그린 난이도">
            {CO_LEVELS.map((l,i)=>(<FChip key={l} label={l} on={pending.gl===i} onClick={()=>setPending(p=>({...p,gl:i}))}/>))}
          </FilterGroup>
        </Sheet>
      )}
    </div>
  );
}

function CourseDetail({ onBack, course }){
  const c = course || COURSES[1];
  const [fav, setFav] = React.useState(true);
  const [mode, setMode] = React.useState("one"); // one | all
  const [hole, setHole] = React.useState(1);
  const [oi, setOi] = React.useState("OUT");
  const par = CO_PARS[hole-1];
  const cols = oi==="OUT" ? [1,2,3,4,5,6,7,8,9] : [10,11,12,13,14,15,16,17,18];
  const teeMarker = (t)=>(<span style={{width:22,height:22,borderRadius:"50%",background:t.c,color:t.txt,display:"flex",alignItems:"center",justifyContent:"center",fontSize:11,fontWeight:800,flexShrink:0,border:t.k==="White"?"1px solid var(--line-strong)":"none"}}>{t.ab}</span>);
  return (
    <div className="screen">
      <StatusBar/>
      <Appbar title="코스 상세" onBack={onBack}/>
      <div className="scroll" style={{paddingBottom:30}}>
        {/* 코스 헤더 */}
        <div style={{padding:"14px 20px 14px",borderBottom:"1px solid var(--line)"}}>
          <div style={{display:"flex",justifyContent:"space-between",alignItems:"center"}}>
            <div style={{display:"flex",alignItems:"center",gap:8}}>
              <span style={{fontSize:17,fontWeight:800,letterSpacing:"-.02em"}}>{c.name}</span>
              <span style={{fontSize:10,fontWeight:800,padding:"2px 6px",borderRadius:4,background:"var(--primary-tint)",color:"var(--primary)"}}>{c.machine}</span>
            </div>
            <button onClick={()=>setFav(v=>!v)} style={{background:"transparent",lineHeight:0}}><CoStar on={fav} color="#2563EB"/></button>
          </div>
          <div style={{display:"flex",alignItems:"center",gap:10,marginTop:9,fontSize:12,color:"var(--text-sub)",fontWeight:600}}>
            <span>{c.region}</span>
            <span style={{width:1,height:10,background:"var(--line-strong)"}}/>
            <span style={{display:"inline-flex",alignItems:"center",gap:6}}>코스 <CoDots n={c.cl} color="#F59E0B"/></span>
            <span style={{display:"inline-flex",alignItems:"center",gap:6}}>그린 <CoDots n={c.gl} color="#F59E0B"/></span>
          </div>
        </div>

        {/* Tee별 총 합계 거리 */}
        <div style={{margin:"14px 20px 4px",padding:"14px 16px",background:"var(--bg-soft)",borderRadius:12}}>
          <div style={{fontSize:12,fontWeight:700,color:"var(--text-sub)",marginBottom:9}}>Tee별 총 합계 거리</div>
          <div style={{display:"flex",flexWrap:"wrap",gap:"9px 18px"}}>
            {CO_TEES.map(t=>(<span key={t.k} style={{fontSize:12.5}}><b style={{fontWeight:800}}>{t.k}</b> <span style={{color:"var(--text-sub)"}}>{t.total}</span></span>))}
          </div>
        </div>

        {/* 뷰 토글 헤더 */}
        <div style={{display:"flex",justifyContent:"space-between",alignItems:"center",padding:"14px 20px 8px"}}>
          <div style={{display:"flex",alignItems:"baseline",gap:6}}>
            <span style={{fontSize:18,fontWeight:800,letterSpacing:"-.02em"}}>{mode==="one"?`${hole}H`:"1H - 18H"}</span>
            {mode==="one" && <span style={{fontSize:14,fontWeight:700,color:"var(--text-sub)"}}>Par{par}</span>}
          </div>
          <button onClick={()=>setMode(m=>m==="one"?"all":"one")} style={{display:"flex",alignItems:"center",gap:5,fontSize:12,fontWeight:700,padding:"7px 12px",borderRadius:16,background:"var(--bg-soft)",border:"1px solid var(--line)",color:"var(--text-sub)"}}>
            {mode==="one"
              ? <svg viewBox="0 0 16 16" width="13" height="13" fill="none" stroke="currentColor" strokeWidth="1.6"><rect x="2.5" y="2.5" width="4.5" height="4.5" rx="1"/><rect x="9" y="2.5" width="4.5" height="4.5" rx="1"/><rect x="2.5" y="9" width="4.5" height="4.5" rx="1"/><rect x="9" y="9" width="4.5" height="4.5" rx="1"/></svg>
              : <svg viewBox="0 0 16 16" width="13" height="13" fill="none" stroke="currentColor" strokeWidth="1.6"><rect x="3" y="3" width="10" height="10" rx="1.5"/></svg>}
            {mode==="one"?"리스트로 보기":"한 홀 씩 보기"}
          </button>
        </div>
        <div style={{padding:"0 20px",fontSize:12,color:"var(--text-sub)",marginBottom:10}}>{c.sub} 코스</div>

        {mode==="one" ? (
          <div style={{padding:"0 20px"}}>
            <div style={{display:"flex",alignItems:"center",gap:8}}>
              <button onClick={()=>setHole(h=>h>1?h-1:18)} className="icon-btn"><Icon name="back" size={18}/></button>
              <div style={{flex:1,aspectRatio:"3/4",borderRadius:12,overflow:"hidden",border:"1px solid var(--line)"}}><HoleMap/></div>
              <button onClick={()=>setHole(h=>h<18?h+1:1)} className="icon-btn"><Icon name="chev-r" size={18}/></button>
            </div>
            <div style={{marginTop:20}}>
              <div style={{display:"flex",justifyContent:"space-between",padding:"4px 6px 12px",fontSize:12,fontWeight:700,color:"var(--text-mute)",borderBottom:"1px solid var(--line)"}}><span>Tee</span><span>거리</span></div>
              {CO_TEES.map((t,ti)=>(
                <div key={t.k} style={{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"17px 6px",borderBottom:"1px solid var(--line)"}}>
                  <span style={{display:"flex",alignItems:"center",gap:12}}>{teeMarker(t)}<span style={{fontSize:14.5,fontWeight:600}}>{t.k}</span></span>
                  <span style={{fontSize:15,fontWeight:700}}>{coDist(hole,ti)}m</span>
                </div>
              ))}
            </div>
          </div>
        ) : (
          <div style={{padding:"0 20px"}}>
            <div style={{display:"grid",gridTemplateColumns:"repeat(3,1fr)",gap:8}}>
              {cols.map(n=>(
                <button key={n} onClick={()=>{setHole(n); setMode("one");}} style={{padding:0,border:"1px solid var(--line)",borderRadius:10,overflow:"hidden",background:"#fff"}}>
                  <div style={{aspectRatio:"3/4"}}><HoleMap/></div>
                  <div style={{padding:"6px 0",fontSize:12,fontWeight:800}}>{n}H</div>
                </button>
              ))}
            </div>
            <div style={{display:"flex",justifyContent:"center",gap:6,padding:"14px 0"}}>
              {["OUT","IN"].map(p=><button key={p} onClick={()=>setOi(p)} style={{width:oi===p?18:7,height:7,borderRadius:4,background:oi===p?"var(--primary)":"var(--line-strong)",border:"none",transition:"width .15s"}}/>)}
            </div>
            <div style={{overflowX:"auto",scrollbarWidth:"none",paddingBottom:20}}>
              <div style={{minWidth:540}}>
                {[["Hole",cols],["Par",cols.map(n=>CO_PARS[n-1])]].map(([label,vals],ri)=>(
                  <div key={label} style={{display:"grid",gridTemplateColumns:"46px repeat(9,1fr)",background:ri===0?"var(--bg-soft)":"transparent"}}>
                    <div style={{padding:"9px 0",textAlign:"center",fontSize:12,fontWeight:700,color:"var(--text-sub)"}}>{label}</div>
                    {vals.map((v,k)=><div key={k} style={{padding:"9px 0",textAlign:"center",fontSize:12,fontWeight:ri===0?800:600,color:ri===0?"var(--text)":"var(--text-sub)"}}>{v}</div>)}
                  </div>
                ))}
                {CO_TEES.map((t,ti)=>(
                  <div key={t.k} style={{display:"grid",gridTemplateColumns:"46px repeat(9,1fr)",borderTop:"1px solid var(--line)"}}>
                    <div style={{display:"flex",justifyContent:"center",alignItems:"center",padding:"9px 0"}}>{teeMarker(t)}</div>
                    {cols.map(n=><div key={n} style={{padding:"9px 0",textAlign:"center",fontSize:11.5,fontWeight:600,color:"var(--text-sub)"}}>{coDist(n,ti)}</div>)}
                  </div>
                ))}
              </div>
            </div>
          </div>
        )}
      </div>
    </div>
  );
}

// ===== 대회 (홈 [대회] 퀵메뉴 → 목록 · 상세) — Figma 05.1.대회 =====
const CH_CARDS = [
  {id:1, cat:"공식", machines:["Q"],      title:"프렌즈 스크린 전국 아마추어 챔피언십",        status:"진행 예정", dday:"D-115", date:"01.17 - 03.23"},
  {id:2, cat:"공식", machines:["Q","T2"], title:"광동제약과 함께하는 행운 가드득 클래식 시즌2", status:"진행중",   dday:"D-42",  date:"01.17 - 03.23", score:"133타"},
  {id:3, cat:"공식", machines:["T2"],     title:"헤이밥 인비테이셔널 오너스컵",                status:"종료",                   date:"11.01 - 12.15"},
  {id:4, cat:"공식", machines:["Q","T2"], title:"2024 신년맞이 버디 페스티벌",                 status:"종료",                   date:"01.01 - 01.31", score:"10,230위"},
  {id:5, cat:"매장", machines:["Q"],      title:"판교점 위클리 스트로크 대회",                status:"진행중",   dday:"D-3",   date:"01.20 - 01.27"},
  {id:6, cat:"매장", machines:["T2"],     title:"강남점 나이트 토너먼트",                      status:"진행 예정", dday:"D-10",  date:"02.01 - 02.14"},
  {id:7, cat:"개인", machines:["T2"],     title:"라이언배 친선 개인전",                        status:"진행중",   dday:"D-5",   date:"01.18 - 01.25"},
  {id:8, cat:"개인", machines:["Q"],      title:"어피치와 함께하는 주말 라운드",              status:"진행 예정", dday:"D-20",  date:"02.10 - 02.24"},
];
// 참여/개설 상태 (프로토타입: 모듈 레벨, 라우트 재마운트 시 반영)
const CH_JOINED = new Set();     // 참여한 대회 id
const CH_CREATED = [];           // 개설한 대회 객체
const CH_SUMMARY = [["시작 일시","2024.01.18 12:00"],["종료 일시","2024.03.23 12:00"],["코스","프렌즈버추얼 A코스"],["OUT / IN","마스터 / 록키"]];
const CH_CONDITIONS = [["티샷","남자 White · 여자 Red"],["스윙 플레이트","4개"],["컨시드 거리","3m"],["멀리건","자유"],["타수","제한 없음"],["그린 빠르기","빠름"],["멀리건 개수","2개"],["핸디","적용"],["바람","1m"],["난이도","마스터"]];
const CH_NOTICE = ["신규 제품 출시 이후로 T2·T3 대회는 구분하지 않고 모든 프렌즈 스크린 매장에서 대회에 참여할 수 있습니다.","T1은 서비스가 종료되어 대회 개설·참여가 지원되지 않습니다."];
const CH_MYRANK = {r:99, name:"삼나무", fin:"완주 3회", join:"참가 4회"};
const CH_RANK = [
  {r:1, name:"지나태윤", fin:"완주 3회", join:"참가 6회"},
  {r:2, name:"쏭크리스탈", fin:"완주 5회", join:"참가 6회"},
  {r:3, name:"다다제이", fin:"완주 2회", join:"참가 3회"},
  {r:4, name:"밤토리엄니", fin:"완주 4회", join:"참가 5회"},
  {r:5, name:"청라동버디땅콩", fin:"완주 3회", join:"참가 4회"},
  {r:6, name:"김프로0108", fin:"완주 5회", join:"참가 6회"},
  {r:7, name:"삼나무", fin:"완주 4회", join:"참가 5회"},
  {r:8, name:"수내이덕화", fin:"완주 3회", join:"참가 6회"},
  {r:9, name:"도윤멘", fin:"완주 4회", join:"참가 4회"},
  {r:10, name:"이서준", fin:"완주 4회", join:"참가 6회"},
];
const chStatusColor = (s)=> s==="종료" ? "var(--text-mute)" : "var(--primary)";

function ChEmpty({ text }){
  return (
    <div style={{padding:"66px 30px",textAlign:"center"}}>
      <img src="assets/course-empty.png" alt="" style={{width:122,height:128,objectFit:"contain"}}/>
      <div style={{fontSize:15,fontWeight:600,color:"var(--text-mute)",marginTop:16}}>{text}</div>
    </div>
  );
}
function ChCard({ c, onOpen }){
  const badge = (txt,dark)=>(<span style={{fontSize:10.5,fontWeight:800,padding:"2px 7px",borderRadius:4,background:dark?"#1A1C1F":"#EEF0F2",color:dark?"#fff":"var(--text-sub)"}}>{txt}</span>);
  return (
    <button onClick={()=>onOpen(c)} style={{display:"block",width:"100%",textAlign:"left",padding:"16px",background:"var(--bg-soft)",borderRadius:14,border:"none",marginBottom:10}}>
      <div style={{display:"flex",gap:5,marginBottom:9}}>{badge(c.cat,true)}{c.machines.map(m=><span key={m}>{badge(m)}</span>)}</div>
      <div style={{display:"flex",justifyContent:"space-between",gap:12,alignItems:"flex-start"}}>
        <div style={{fontSize:15,fontWeight:800,lineHeight:1.35,letterSpacing:"-.01em"}}>{c.title}</div>
        {c.score && <div style={{fontSize:20,fontWeight:800,whiteSpace:"nowrap"}}>{c.score}</div>}
      </div>
      <div style={{display:"flex",justifyContent:"space-between",alignItems:"center",marginTop:12}}>
        <span style={{fontSize:12.5,fontWeight:700,color:chStatusColor(c.status)}}>{c.status}{c.dday?` ${c.dday}`:""}</span>
        <span className="mono" style={{fontSize:12,color:"var(--text-sub)"}}>{c.date}</span>
      </div>
    </button>
  );
}
function ChRanking(){
  const [q, setQ] = React.useState("");
  const chip = (on)=>({flexShrink:0,display:"flex",alignItems:"center",gap:4,fontSize:13,fontWeight:on?700:600,padding:"8px 14px",borderRadius:18,border:on?"none":"1px solid var(--line-strong)",background:on?"#1A1C1F":"#fff",color:on?"#fff":"var(--text-sub)",whiteSpace:"nowrap"});
  const list = CH_RANK.filter(r=> !q || r.name.includes(q));
  return (
    <div style={{paddingTop:14}}>
      <div style={{display:"flex",gap:8,padding:"0 20px 12px",overflowX:"auto",scrollbarWidth:"none"}}>
        <button style={chip(true)}>Q <Icon name="chev-d" size={13}/></button>
        <button style={chip(false)}>필터 <Icon name="chev-d" size={13}/></button>
        <button style={chip(false)}>라운드해본</button>
        <button style={chip(false)}>라운드안해본</button>
      </div>
      <div style={{margin:"0 20px 14px",padding:"12px 14px",background:"var(--primary-tint)",borderRadius:10,fontSize:12,color:"var(--primary)",fontWeight:600,lineHeight:1.5}}>우리매장투어대회의 순위는 코스 완주, 스코어 순서로 표기됩니다.</div>
      <div style={{display:"flex",alignItems:"center",gap:12,padding:"12px 20px",background:"var(--primary-tint)"}}>
        <div style={{width:30,textAlign:"center",fontWeight:800,color:"var(--primary)"}}>{CH_MYRANK.r}</div>
        <div style={{flex:1,fontWeight:700}}>{CH_MYRANK.name}</div>
        <div style={{fontSize:12,color:"var(--text-sub)"}}>{CH_MYRANK.fin} · {CH_MYRANK.join}</div>
      </div>
      <div style={{display:"flex",gap:16,padding:"12px 20px",fontSize:12.5,color:"var(--text-sub)",fontWeight:600,borderBottom:"1px solid var(--line)"}}>
        <span>완주자 <b style={{color:"var(--text)"}}>952</b></span><span>참가자 <b style={{color:"var(--text)"}}>970</b></span>
      </div>
      <div style={{padding:"12px 20px 4px"}}>
        <div style={{display:"flex",alignItems:"center",gap:8,background:"var(--bg-soft)",borderRadius:10,padding:"10px 14px"}}>
          <Icon name="search" size={16} style={{color:"var(--text-mute)"}}/>
          <input value={q} onChange={e=>setQ(e.target.value)} placeholder="닉네임 검색" style={{border:"none",background:"transparent",outline:"none",fontSize:14,flex:1,minWidth:0}}/>
        </div>
      </div>
      {list.map(r=>(
        <div key={r.r} style={{display:"flex",alignItems:"center",gap:12,padding:"14px 20px",borderTop:"1px solid var(--line)"}}>
          <div style={{width:24,textAlign:"center",fontWeight:800,fontSize:14,color:r.r<=3?"var(--primary)":"var(--text-sub)"}}>{r.r}</div>
          <div style={{flex:1,fontWeight:600}}>{r.name}</div>
          <div style={{fontSize:12,color:"var(--text-sub)"}}>{r.fin} · {r.join}</div>
        </div>
      ))}
    </div>
  );
}

function ChampionshipList({ onBack, onOpenDetail, onCreate, initialTab }){
  const [tab, setTab] = React.useState(initialTab||"all");     // all | joined | created
  const [cat, setCat] = React.useState("공식");     // 공식 | 매장 | 개인
  const [machine, setMachine] = React.useState("Q");
  const [q, setQ] = React.useState("");
  const [sort, setSort] = React.useState("최신순");
  const [sortSheet, setSortSheet] = React.useState(false);
  const allList = CH_CARDS.filter(c=> c.cat===cat && (!q || c.title.includes(q)));
  const chip = (on)=>({flexShrink:0,display:"flex",alignItems:"center",gap:4,fontSize:13,fontWeight:on?700:600,padding:"8px 14px",borderRadius:18,border:on?"none":"1px solid var(--line-strong)",background:on?"#1A1C1F":"#fff",color:on?"#fff":"var(--text-sub)",whiteSpace:"nowrap"});

  return (
    <div className="screen">
      <StatusBar/>
      <Appbar title="대회" onBack={onBack}/>
      <div style={{display:"flex",borderBottom:"1px solid var(--line)"}}>
        {[["all","전체"],["joined","참여"],["created","개설"]].map(([id,label])=>(
          <button key={id} onClick={()=>setTab(id)} style={{flex:1,padding:"14px 0",fontSize:15,fontWeight:700,color:tab===id?"var(--text)":"var(--text-mute)",borderBottom:"2px solid "+(tab===id?"var(--primary)":"transparent"),background:"none"}}>{label}</button>
        ))}
      </div>
      <div className="scroll" style={{paddingBottom:tab==="created"?100:30}}>
        {tab==="all" && (<>
          <div style={{display:"flex",gap:8,padding:"14px 20px 8px",overflowX:"auto",scrollbarWidth:"none"}}>
            {["공식","매장","개인"].map(k=><button key={k} onClick={()=>setCat(k)} style={chip(cat===k)}>{k}대회</button>)}
          </div>
          <div style={{padding:"4px 20px"}}>
            <div style={{display:"flex",alignItems:"center",gap:8,background:"var(--bg-soft)",borderRadius:10,padding:"11px 14px"}}>
              <Icon name="search" size={16} style={{color:"var(--text-mute)"}}/>
              <input value={q} onChange={e=>setQ(e.target.value)} placeholder="검색" style={{border:"none",background:"transparent",outline:"none",fontSize:14,flex:1,minWidth:0}}/>
            </div>
          </div>
          <div style={{display:"flex",justifyContent:"space-between",alignItems:"center",padding:"12px 20px 10px"}}>
            <span style={{fontSize:13,color:"var(--text-sub)",fontWeight:600}}>대회 {q?allList.length:"123"}개</span>
            <button onClick={()=>setSortSheet(true)} style={{display:"flex",alignItems:"center",gap:3,fontSize:13,fontWeight:600,color:"var(--text-sub)",background:"transparent"}}>{sort} <Icon name="chev-d" size={13}/></button>
          </div>
          <div style={{padding:"0 20px"}}>
            {allList.length===0 ? <ChEmpty text="대회가 없습니다."/> : allList.map(c=><ChCard key={c.id} c={c} onOpen={onOpenDetail}/>)}
          </div>
        </>)}
        {tab==="joined" && (<>
          <div style={{display:"flex",gap:8,padding:"14px 20px 8px",overflowX:"auto",scrollbarWidth:"none"}}>
            {["Q","T2"].map(m=><button key={m} onClick={()=>setMachine(m)} style={chip(machine===m)}>{m}</button>)}
          </div>
          {(()=>{ const joined = CH_CARDS.filter(c=>CH_JOINED.has(c.id)); return joined.length===0
            ? <ChEmpty text="참여한 대회가 없습니다."/>
            : <div style={{padding:"4px 20px 0"}}>{joined.map(c=><ChCard key={c.id} c={c} onOpen={onOpenDetail}/>)}</div>; })()}
        </>)}
        {tab==="created" && (CH_CREATED.length===0
          ? <ChEmpty text="개설한 대회가 없습니다."/>
          : <div style={{padding:"14px 20px 0"}}>{CH_CREATED.map(c=><ChCard key={c.id} c={c} onOpen={onOpenDetail}/>)}</div>)}
      </div>
      {tab==="created" && (
        <div style={{position:"absolute",left:0,right:0,bottom:0,padding:"14px 20px 24px",background:"#fff",borderTop:"1px solid var(--line)"}}>
          <button className="btn btn-primary" style={{width:"100%"}} onClick={onCreate}>대회 개설하기</button>
        </div>
      )}
      {sortSheet && <Sheet title="정렬" onClose={()=>setSortSheet(false)}>{CO_SORTS.map(s=><SheetItem key={s} label={s} on={sort===s} onClick={()=>{setSort(s); setSortSheet(false);}}/>)}</Sheet>}
    </div>
  );
}

function ChampionshipDetail({ onBack, champ }){
  const c = champ || CH_CARDS[0];
  const [tab, setTab] = React.useState("info"); // info | rank
  const [terms, setTerms] = React.useState(false);
  const [joined, setJoined] = React.useState(CH_JOINED.has(c.id));
  const [toast, setToast] = React.useState(null);
  const ended = c.status==="종료";
  const doJoin = ()=>{ if(joined||ended) return; CH_JOINED.add(c.id); setJoined(true); setToast("대회에 참여했어요. 참여 탭에서 확인하세요."); window.clearTimeout(doJoin._t); doJoin._t=window.setTimeout(()=>setToast(null),2400); };
  const Row = ({k,v})=>(
    <div style={{display:"flex",justifyContent:"space-between",gap:12,padding:"13px 0",borderTop:"1px solid var(--line)",fontSize:13.5}}>
      <span style={{color:"var(--text-sub)",flexShrink:0}}>{k}</span><span style={{fontWeight:600,textAlign:"right"}}>{v}</span>
    </div>
  );
  return (
    <div className="screen">
      <StatusBar/>
      <Appbar title="대회" onBack={onBack}/>
      {toast && <div className="toast"><span>{toast}</span></div>}
      <div className="scroll" style={{paddingBottom: tab==="info"?100:30}}>
        {/* 히어로 */}
        <div style={{padding:"10px 20px 16px"}}>
          <div style={{fontSize:19,fontWeight:800,lineHeight:1.3,letterSpacing:"-.02em"}}>{c.title}</div>
          <div style={{fontSize:12.5,color:"var(--text-sub)",marginTop:6}}>광동 버츄얼 · 아웃/인</div>
          <div style={{position:"relative",marginTop:14,borderRadius:16,overflow:"hidden",background:"#EEF1F3"}}>
            <img src="assets/tournament-hero.png" alt="" style={{width:"100%",display:"block"}}/>
            <span style={{position:"absolute",right:10,bottom:10,fontSize:11,fontWeight:700,color:"#fff",background:"rgba(0,0,0,.45)",padding:"3px 10px",borderRadius:12}}>공개</span>
          </div>
        </div>
        {/* 탭 */}
        <div style={{display:"flex",borderBottom:"1px solid var(--line)"}}>
          {[["info","정보"],["rank","랭킹"]].map(([id,label])=>(
            <button key={id} onClick={()=>setTab(id)} style={{flex:1,padding:"13px 0",fontSize:14,fontWeight:700,color:tab===id?"var(--text)":"var(--text-mute)",borderBottom:"2px solid "+(tab===id?"var(--primary)":"transparent"),background:"none"}}>{label}</button>
          ))}
        </div>

        {tab==="info" ? (
          <>
            <div style={{padding:"20px 20px 0"}}>
              <div className="h3" style={{marginBottom:10}}>대회 안내</div>
              <div style={{fontSize:13,color:"var(--text-sub)",lineHeight:1.7}}>광동제약과 함께 하는 이번 대회는 반얀트리호텔 숙박권, 신세계 상품권 및 광동제약 건강식품 등 알차게 구성되어 있습니다. 골프 못 쳐도 당첨되는 스크린 골프대회! 지금 바로 참여하세요.</div>
            </div>
            <div style={{height:8,background:"var(--bg-soft)",margin:"20px 0 0"}}/>
            <div style={{padding:"18px 20px 6px"}}>
              <div className="h3" style={{marginBottom:2}}>대회 요강</div>
              {CH_SUMMARY.map(([k,v])=><Row key={k} k={k} v={v}/>)}
            </div>
            <div style={{height:8,background:"var(--bg-soft)",margin:"14px 0 0"}}/>
            <div style={{padding:"18px 20px 6px"}}>
              <div className="h3" style={{marginBottom:2}}>게임 조건</div>
              {CH_CONDITIONS.map(([k,v])=><Row key={k} k={k} v={v}/>)}
            </div>
            <button onClick={()=>setTerms(o=>!o)} style={{display:"flex",width:"100%",justifyContent:"space-between",alignItems:"center",padding:"18px 20px",background:"transparent",borderTop:"8px solid var(--bg-soft)"}}>
              <span className="h3">대회 약관</span>
              <svg viewBox="0 0 16 16" width="16" height="16" style={{transform:terms?"rotate(180deg)":"none",transition:"transform .15s",color:"var(--text-mute)"}}><path d="M4 6l4 4 4-4" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/></svg>
            </button>
            {terms && <div style={{padding:"0 20px 16px",fontSize:12.5,color:"var(--text-sub)",lineHeight:1.7}}>본 대회는 프렌즈 스크린 운영정책에 따라 진행되며, 부정행위 적발 시 순위에서 제외될 수 있습니다. 상품 수령은 대회 종료 후 별도 안내됩니다.</div>}
            <div style={{padding:"18px 20px 20px",background:"var(--bg-soft)"}}>
              <div style={{fontSize:13,fontWeight:700,marginBottom:12}}>유의사항</div>
              {CH_NOTICE.map((n,i)=>(
                <div key={i} style={{display:"flex",gap:8,marginBottom:10}}>
                  <span style={{width:3,height:3,borderRadius:"50%",background:"var(--text-mute)",marginTop:8,flexShrink:0}}/>
                  <span style={{fontSize:12,color:"var(--text-sub)",lineHeight:1.6}}>{n}</span>
                </div>
              ))}
            </div>
          </>
        ) : <ChRanking/>}
      </div>
      {tab==="info" && (
        <div style={{position:"absolute",left:0,right:0,bottom:0,padding:"14px 20px 24px",background:"#fff",borderTop:"1px solid var(--line)"}}>
          <button onClick={doJoin} disabled={joined||ended}
            className={"btn "+((joined||ended)?"btn-soft":"btn-primary")} style={{width:"100%",opacity:(joined||ended)?.7:1}}>
            {ended?"종료된 대회":joined?"참여 완료":"지금 바로 참여하기"}
          </button>
        </div>
      )}
    </div>
  );
}

// ===== 대회 개설 (개인 대회 개설) — 4단계 위저드, Figma 대회개설-1/2/3 =====
// 실제 앱(FS 게임설정 strings) 기준 옵션값. 시스템은 T3를 Q로 통합, T1은 종료로 제외
const CH_OPT = {
  gender:["전체","남성","여성"], system:["Q","T2"], unit:["미터","야드"], giveup:["무제한","3회","5회"],
  handi:["사용안함","사용"], femaleHandi:["사용안함","3타","5타","7타"], groupHandi:["사용안함","설정"],
  difficulty:["비기너","세미프로","프로","마스터","직접설정"], condition:["쉬움","보통","어려움"],
  swingPlate:["사용안함","아마추어","프로","마스터"],
  mulligan:["무제한","3개","2개","1개","없음"], caddie:["제한 없음","10회","6회","없음"],
  concede:["없음","1.5m","2m","2.5m"], green:["느림","보통","빠름","매우 빠름"],
  wind:["없음","약함","보통","강함"], pin:["하","중","상","랜덤"],
  teeM:["Black","Blue","White","Yellow","Red"], teeF:["Black","Blue","White","Yellow","Red"],
  incourse:["록키","올림프스","레이크","마운틴"], outcourse:["록키","올림프스","레이크","마운틴"],
};
const CH_STEPS = ["대회 정보","조건 설정","코스 및 난이도","미리보기"];
const CH_TIMES = Array.from({length:24},(_,h)=>`${String(h).padStart(2,"0")}:00`);
const CH_WD = ["일","월","화","수","목","금","토"];
// 오늘(유저 확인 시점) 이후 날짜 생성
const chGenDates = (n, from=0)=>{ const base=new Date(); base.setHours(0,0,0,0); return Array.from({length:n},(_,i)=>{ const t=new Date(base.getTime()+(from+i)*86400000); return `${t.getFullYear()}.${String(t.getMonth()+1).padStart(2,"0")}.${String(t.getDate()).padStart(2,"0")} (${CH_WD[t.getDay()]})`; }); };
const CH_COURSE_REGIONS = [["전국",321],["수도권",99],["강원도",28],["충청도",120],["경상도",88],["전라도",45],["제주도",30]];
const CH_COURSE_NAMES = ["360도","88-동","가평베네스트","강남300","거제뷰","경주","경주신라","골든밸리","그린힐","남서울","라비에벨","레이크사이드","몽베르","베어크리크","블루원","사우스스프링스","세인트포","스카이72","아일랜드","제이드팰리스","일동레이크","잭니클라우스","파인비치","포천힐스","해슬리","화산"];

// 코스 선택 바텀시트 (지역 탭 + 목록 + 적용)
function CourseSelectSheet({ current, onClose, onApply }){
  const [region, setRegion] = React.useState("전국");
  const [sel, setSel] = React.useState(current||"");
  return (
    <div onClick={onClose} style={{position:"absolute",inset:0,background:"rgba(0,0,0,.4)",zIndex:40,display:"flex",alignItems:"flex-end"}}>
      <div onClick={e=>e.stopPropagation()} style={{width:"100%",height:"82%",display:"flex",flexDirection:"column",background:"#fff",borderRadius:"18px 18px 0 0"}}>
        <div style={{width:40,height:4,borderRadius:2,background:"var(--line-strong)",margin:"8px auto 4px",flexShrink:0}}/>
        <div style={{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"8px 20px 10px",flexShrink:0}}>
          <span style={{fontSize:16,fontWeight:800}}>코스 선택</span>
          <button onClick={onClose} style={{background:"transparent",border:"none",lineHeight:0,padding:2}}><Icon name="x" size={20} style={{color:"var(--text-sub)"}}/></button>
        </div>
        <div style={{display:"flex",gap:18,padding:"0 20px",borderBottom:"1px solid var(--line)",overflowX:"auto",scrollbarWidth:"none",flexShrink:0}}>
          {CH_COURSE_REGIONS.map(([r,n])=>{ const on=region===r; return (
            <button key={r} onClick={()=>setRegion(r)} style={{padding:"12px 0",fontSize:15,fontWeight:on?800:600,color:on?"var(--text)":"var(--text-mute)",borderBottom:on?"2px solid var(--text)":"2px solid transparent",background:"transparent",whiteSpace:"nowrap",marginBottom:-1}}>{r}({n})</button>
          ); })}
        </div>
        <div style={{overflowY:"auto",flex:1,padding:"4px 0"}}>
          {CH_COURSE_NAMES.map(name=>(
            <button key={name} onClick={()=>setSel(name)} style={{display:"flex",width:"100%",alignItems:"center",justifyContent:"space-between",padding:"15px 20px",background:"transparent",border:"none",textAlign:"left"}}>
              <span style={{fontSize:15,fontWeight:sel===name?800:500,color:sel===name?"var(--text)":"var(--text-sub)"}}>{name}</span>
              {sel===name && <Icon name="check" size={18} style={{color:"var(--primary)"}}/>}
            </button>
          ))}
        </div>
        <div style={{padding:"12px 20px 22px",flexShrink:0,borderTop:"1px solid var(--line)"}}>
          <button className="btn btn-primary" style={{width:"100%",opacity:sel?1:.5}} disabled={!sel} onClick={()=>onApply(sel)}>적용</button>
        </div>
      </div>
    </div>
  );
}

function ChampionshipCreate({ onBack, onDone }){
  const [step, setStep] = React.useState(1);
  const [done, setDone] = React.useState(false);
  const [sheet, setSheet] = React.useState(null); // {key,label,options}
  const [toast, setToast] = React.useState(null);
  const [f, setF] = React.useState({
    name:"", startDate:"", startTime:"", endDate:"", endTime:"", notice:"",
    open:true, gender:"전체", system:"T2", unit:"미터", giveup:"무제한", handi:"사용안함", femaleHandi:"3타", groupHandi:"사용안함",
    course:"", incourse:"", outcourse:"", difficulty:"프로", condition:"보통",
    swingPlate:"프로", mulligan:"3개", caddie:"6회", concede:"1.5m", green:"보통", wind:"보통", pin:"중", teeM:"White", teeF:"Red",
  });
  const set = (k,v)=> setF(s=>({...s,[k]:v}));
  const pop = (m)=>{ setToast(m); window.clearTimeout(pop._t); pop._t=window.setTimeout(()=>setToast(null),2200); };
  const custom = f.difficulty==="직접설정";
  const dShow = (v)=> v ? v.slice(5) : null;            // "07.09 (수)"
  const mmdd = (v)=> v ? v.slice(5,10).replace(".","/") : "";
  const dRange = (f.startDate&&f.endDate) ? `${mmdd(f.startDate)} - ${mmdd(f.endDate)}` : "-";

  const SelRow = ({label, k})=>(
    <button onClick={()=>setSheet({key:k,label,options:CH_OPT[k]})} style={{display:"flex",width:"100%",justifyContent:"space-between",alignItems:"center",padding:"15px 0",borderTop:"1px solid var(--line)",background:"transparent",textAlign:"left"}}>
      <span style={{fontSize:14,color:"var(--text-sub)"}}>{label}</span>
      <span style={{display:"flex",alignItems:"center",gap:4,fontSize:14,fontWeight:700,color:f[k]?"var(--primary)":"var(--text-mute)"}}>{f[k]||"선택"} <Icon name="chev-r" size={14}/></span>
    </button>
  );
  const CondRow = ({label, k})=>( custom
    ? <SelRow label={label} k={k}/>
    : <div style={{display:"flex",justifyContent:"space-between",alignItems:"center",padding:"15px 0",borderTop:"1px solid var(--line)"}}>
        <span style={{fontSize:14,color:"var(--text-sub)"}}>{label}</span>
        <span style={{fontSize:14,fontWeight:700,color:"var(--text)"}}>{f[k]}</span>
      </div>
  );
  const DateTime = ({dateKey, timeKey, tag})=>(
    <div style={{display:"flex",gap:10,marginTop:2}}>
      <button onClick={()=>setSheet({key:dateKey,label:`${tag} 날짜`,options:chGenDates(dateKey==="startDate"?8:30,0)})} style={{flex:1,display:"flex",justifyContent:"space-between",alignItems:"center",borderBottom:"1px solid var(--line-strong)",padding:"11px 0",background:"transparent"}}>
        <span style={{fontSize:14,fontWeight:600,color:f[dateKey]?"var(--text)":"var(--text-mute)",whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis"}}>{dShow(f[dateKey])||"날짜 선택"}</span><Icon name="chev-d" size={15} style={{color:"var(--text-mute)",flexShrink:0}}/>
      </button>
      <button onClick={()=>setSheet({key:timeKey,label:`${tag} 시간`,options:CH_TIMES})} style={{flex:1,display:"flex",justifyContent:"space-between",alignItems:"center",borderBottom:"1px solid var(--line-strong)",padding:"11px 0",background:"transparent"}}>
        <span style={{fontSize:14,fontWeight:600,color:f[timeKey]?"var(--text)":"var(--text-mute)"}}>{f[timeKey]||"시간 선택"}</span><Icon name="chev-d" size={15} style={{color:"var(--text-mute)",flexShrink:0}}/>
      </button>
    </div>
  );

  const next = ()=>{
    if(step===1){ if(!f.name.trim()) return pop("대회명을 입력해 주세요."); if(!f.startDate||!f.startTime||!f.endDate||!f.endTime) return pop("대회 시작·종료 날짜와 시간을 선택해 주세요."); }
    if(step===3){ if(!f.course) return pop("코스를 선택해 주세요."); if(f.incourse && f.incourse===f.outcourse) return pop("아웃코스와 인코스를 동일하게 설정할 수 없습니다."); }
    if(step<4) setStep(step+1); else finish();
  };
  const finish = ()=>{
    CH_CREATED.unshift({ id:1000+CH_CREATED.length, cat:"개인", machines:[f.system], title:f.name, status:"진행 예정", dday:"D-7", date:dRange });
    setDone(true);
  };

  if(done) return (
    <div className="screen">
      <StatusBar/>
      <Appbar title="개인 대회 개설" onBack={onDone}/>
      <div className="scroll" style={{display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",textAlign:"center",padding:"0 30px"}}>
        <div style={{width:72,height:72,borderRadius:"50%",background:"var(--primary-tint)",display:"flex",alignItems:"center",justifyContent:"center",marginBottom:18}}>
          <Icon name="check" size={38} style={{color:"var(--primary)"}}/>
        </div>
        <div style={{fontSize:19,fontWeight:800,letterSpacing:"-.02em"}}>대회가 개설되었어요!</div>
        <div style={{fontSize:13.5,color:"var(--text-sub)",marginTop:10,lineHeight:1.6}}><b style={{color:"var(--text)"}}>{f.name}</b><br/>개설한 대회는 '개설' 탭에서 확인·관리할 수 있어요.</div>
      </div>
      <div style={{padding:"14px 20px 24px",borderTop:"1px solid var(--line)"}}>
        <button className="btn btn-primary" style={{width:"100%"}} onClick={onDone}>확인</button>
      </div>
    </div>
  );

  return (
    <div className="screen">
      <StatusBar/>
      <Appbar title="개인 대회 개설" onBack={step>1?()=>setStep(step-1):onBack}
        right={<button className="icon-btn" onClick={onBack}><Icon name="x" size={20}/></button>}/>
      {toast && <div className="toast"><span>{toast}</span></div>}

      {/* 스텝 인디케이터 */}
      <div style={{display:"flex",alignItems:"center",gap:6,padding:"16px 20px 12px",borderBottom:"1px solid var(--line)"}}>
        {CH_STEPS.map((label,i)=>{ const n=i+1; const on=n===step, passed=n<step; return (
          <React.Fragment key={n}>
            <div style={{display:"flex",alignItems:"center",gap:6,flexShrink:0}}>
              <span style={{width:22,height:22,borderRadius:"50%",background:on||passed?"var(--primary)":"var(--bg-soft)",color:on||passed?"#fff":"var(--text-mute)",fontSize:11,fontWeight:800,display:"flex",alignItems:"center",justifyContent:"center"}}>{n}</span>
              {on && <span style={{fontSize:13.5,fontWeight:800}}>{label}</span>}
            </div>
            {n<CH_STEPS.length && <div style={{flex:on?"unset":1,minWidth:8,height:1,background:"var(--line)"}}/>}
          </React.Fragment>
        ); })}
      </div>

      <div className="scroll" style={{paddingBottom:20}}>
        {step===1 && (
          <div style={{padding:"18px 20px"}}>
            <label style={{fontSize:12,color:"var(--text-sub)",fontWeight:600}}>대회명</label>
            <input value={f.name} onChange={e=>set("name",e.target.value.slice(0,80))} placeholder="다 함께 라운드 해요." style={{width:"100%",border:"none",borderBottom:"1px solid var(--line-strong)",padding:"10px 0",fontSize:16,fontWeight:600,outline:"none",background:"transparent"}}/>
            <div style={{textAlign:"right",fontSize:11,color:"var(--text-mute)",marginTop:4}}>{f.name.length}/80자</div>

            <div style={{fontSize:12,color:"var(--text-sub)",fontWeight:600,marginTop:18}}>대회 시작일</div>
            <DateTime dateKey="startDate" timeKey="startTime" tag="시작"/>
            <div style={{fontSize:12,color:"var(--text-sub)",fontWeight:600,marginTop:16}}>대회 종료일</div>
            <DateTime dateKey="endDate" timeKey="endTime" tag="종료"/>

            <ul style={{margin:"16px 0 0",padding:0,listStyle:"none"}}>
              {["시작일은 당일~7일 이후까지만 선택이 가능합니다.","기간은 최소 2시간~최대 30일까지 가능합니다.","기간 중에는 시작/종료 기간 수정이 불가합니다."].map((t,i)=>(
                <li key={i} style={{display:"flex",gap:6,fontSize:12,color:"var(--text-mute)",marginBottom:6}}><span>·</span><span>{t}</span></li>
              ))}
            </ul>
            <div style={{fontSize:12,color:"var(--text-sub)",fontWeight:600,marginTop:16}}>대회 공지 (선택사항)</div>
            <textarea value={f.notice} onChange={e=>set("notice",e.target.value.slice(0,1000))} placeholder="최대 글자 수는 1,000자이며, 글자 수를 26자 내로 입력하시면 게임화면에 동일하게 출력됩니다." style={{width:"100%",height:110,border:"1px solid var(--line)",borderRadius:10,padding:"12px 14px",fontSize:13,outline:"none",resize:"none",marginTop:8,fontFamily:"inherit"}}/>
            <div style={{textAlign:"right",fontSize:11,color:"var(--text-mute)"}}>{f.notice.length}/1,000자</div>
          </div>
        )}

        {step===2 && (
          <div style={{padding:"6px 20px 0"}}>
            <div style={{display:"flex",justifyContent:"space-between",alignItems:"center",padding:"16px 0"}}>
              <span style={{fontSize:14,color:"var(--text-sub)"}}>대회 공개 여부</span>
              <div style={{display:"flex",background:"var(--bg-soft)",borderRadius:8,padding:2}}>
                {[["공개",true],["비공개",false]].map(([lb,v])=>(
                  <button key={lb} onClick={()=>set("open",v)} style={{padding:"6px 16px",borderRadius:6,fontSize:13,fontWeight:700,border:"none",background:f.open===v?"var(--primary)":"transparent",color:f.open===v?"#fff":"var(--text-sub)"}}>{lb}</button>
                ))}
              </div>
            </div>
            <SelRow label="성별" k="gender"/>
            <SelRow label="시스템 선택" k="system"/>
            <SelRow label="거리 (단위)" k="unit"/>
            <SelRow label="포기 횟수" k="giveup"/>
            <SelRow label="핸디 적용" k="handi"/>
            <SelRow label="여성 핸디 적용" k="femaleHandi"/>
            <SelRow label="그룹별 핸디" k="groupHandi"/>
          </div>
        )}

        {step===3 && (
          <div style={{padding:"18px 20px 0"}}>
            <div style={{marginBottom:18}}>
              <div style={{fontSize:12,color:"var(--text-sub)",fontWeight:600,marginBottom:4}}>코스 선택</div>
              <button onClick={()=>setSheet({key:"course"})} style={{display:"flex",width:"100%",justifyContent:"space-between",alignItems:"center",borderBottom:"1px solid var(--line-strong)",padding:"10px 0",background:"transparent"}}>
                <span style={{fontSize:15,fontWeight:600,color:f.course?"var(--text)":"var(--text-mute)"}}>{f.course||"코스"}</span><Icon name="chev-d" size={16} style={{color:"var(--text-mute)"}}/>
              </button>
            </div>
            {[["outcourse","아웃코스 선택","아웃코스"],["incourse","인코스 선택","인코스"]].map(([k,label,ph])=>(
              <div key={k} style={{marginBottom:18}}>
                <div style={{fontSize:12,color:"var(--text-sub)",fontWeight:600,marginBottom:4}}>{label}</div>
                <button onClick={()=>setSheet({key:k,label,options:CH_OPT[k]})} style={{display:"flex",width:"100%",justifyContent:"space-between",alignItems:"center",borderBottom:"1px solid var(--line-strong)",padding:"10px 0",background:"transparent"}}>
                  <span style={{fontSize:15,fontWeight:600,color:f[k]?"var(--text)":"var(--text-mute)"}}>{f[k]||ph}</span><Icon name="chev-d" size={16} style={{color:"var(--text-mute)"}}/>
                </button>
              </div>
            ))}
            <div style={{marginTop:6}}>
              <SelRow label="대회 난이도" k="difficulty"/>
              <CondRow label="대회 조건" k="condition"/>
              <CondRow label="스윙 플레이트" k="swingPlate"/>
              <CondRow label="멀리건" k="mulligan"/>
              <CondRow label="캐디" k="caddie"/>
              <CondRow label="컨시드" k="concede"/>
              <CondRow label="그린 빠르기" k="green"/>
              <CondRow label="바람세기" k="wind"/>
              <CondRow label="핀 위치" k="pin"/>
              <CondRow label="티박스 (남성)" k="teeM"/>
              <CondRow label="티박스 (여성)" k="teeF"/>
            </div>
          </div>
        )}

        {step===4 && (
          <div style={{padding:"18px 20px 0"}}>
            <div className="h3" style={{marginBottom:12}}>미리보기</div>
            {/* 대회 카드 미리보기 */}
            <div style={{padding:"16px",background:"var(--bg-soft)",borderRadius:14}}>
              <div style={{display:"flex",gap:5,marginBottom:9}}>
                <span style={{fontSize:10.5,fontWeight:800,padding:"2px 7px",borderRadius:4,background:"#1A1C1F",color:"#fff"}}>개인</span>
                <span style={{fontSize:10.5,fontWeight:800,padding:"2px 7px",borderRadius:4,background:"#EEF0F2",color:"var(--text-sub)"}}>{f.system}</span>
                {!f.open && <span style={{fontSize:10.5,fontWeight:800,padding:"2px 7px",borderRadius:4,background:"#EEF0F2",color:"var(--text-sub)"}}>비공개</span>}
              </div>
              <div style={{fontSize:15,fontWeight:800,letterSpacing:"-.01em"}}>{f.name||"대회명"}</div>
              <div style={{display:"flex",justifyContent:"space-between",alignItems:"center",marginTop:12}}>
                <span style={{fontSize:12.5,fontWeight:700,color:"var(--primary)"}}>진행 예정 D-7</span>
                <span className="mono" style={{fontSize:12,color:"var(--text-sub)"}}>{dRange}</span>
              </div>
            </div>
            {/* 조건 요약 */}
            <div style={{marginTop:20}}>
              <div style={{fontSize:14,fontWeight:800,marginBottom:2}}>대회 조건</div>
              {[["기간",`${dShow(f.startDate)} ${f.startTime} ~ ${dShow(f.endDate)} ${f.endTime}`],["코스",[f.course,f.outcourse,f.incourse].filter(Boolean).join(" · ")||"-"],["난이도",f.difficulty],["대회 조건",f.condition],["스윙 플레이트",f.swingPlate],["멀리건",f.mulligan],["캐디",f.caddie],["컨시드",f.concede],["그린 빠르기",f.green],["티박스",`남 ${f.teeM} · 여 ${f.teeF}`]].map(([k,v])=>(
                <div key={k} style={{display:"flex",justifyContent:"space-between",gap:12,padding:"12px 0",borderTop:"1px solid var(--line)",fontSize:13}}>
                  <span style={{color:"var(--text-sub)",flexShrink:0}}>{k}</span><span style={{fontWeight:600,textAlign:"right"}}>{v}</span>
                </div>
              ))}
            </div>
            <div style={{fontSize:12,color:"var(--text-mute)",marginTop:14,lineHeight:1.6}}>개설 후에는 기간·조건 일부를 수정할 수 없어요. 미리보기를 확인하고 개설해 주세요.</div>
          </div>
        )}
      </div>

      {/* 하단 버튼 */}
      <div style={{display:"flex",gap:8,padding:"14px 20px 24px",borderTop:"1px solid var(--line)"}}>
        <button className="btn btn-soft" style={{flex:1}} onClick={step>1?()=>setStep(step-1):onBack}>이전</button>
        <button className="btn btn-primary" style={{flex:1.6}} onClick={next}>{step<4?"다음":"대회 개설하기"}</button>
      </div>

      {sheet && (sheet.key==="course"
        ? <CourseSelectSheet current={f.course} onClose={()=>setSheet(null)} onApply={(v)=>{ set("course",v); setSheet(null); }}/>
        : <Sheet title={sheet.label} onClose={()=>setSheet(null)}>
            {sheet.options.map(o=><SheetItem key={o} label={o} on={f[sheet.key]===o} onClick={()=>{ set(sheet.key,o); setSheet(null); }}/>)}
          </Sheet>
      )}
    </div>
  );
}

// ===== 이벤트 (홈 [이벤트] 퀵메뉴) — Figma 01.0.MainHome_03.이벤트 =====
const EV_SCREEN = [
  {id:1, title:"카카오 T대리 롱기스트 2023", sub:"카카오 T대리 × FRIENDS SCREEN", status:"진행 예정", dday:"D-115", date:"2024.01.17 - 2024.03.23", grad:"linear-gradient(135deg,#2563EB,#38BDF8)", label:"LONGEST 2023", desc:"실력있는 골퍼들의 비거리 경쟁!"},
  {id:2, title:"광동 버츄얼CC와 행운 가드득 클래식 시즌2", sub:"광동제약 × FRIENDS SCREEN", status:"진행중", dday:"D-42", date:"2024.01.17 - 2024.03.23", grad:"linear-gradient(135deg,#F97316,#FB923C)", label:"행운 가드득 클래식", desc:"골프 못 쳐도 당첨되는 스크린 골프대회!"},
  {id:3, title:"GOLF LIFE with Hankook", sub:"한국타이어 × FRIENDS SCREEN", status:"종료", date:"2023.11.01 - 2023.12.15", grad:"linear-gradient(135deg,#0EA5E9,#67E8F9)", label:"GOLF LIFE", desc:"라운드하고 경품 받자!", winner:true},
];
const EV_ACADEMY = [
  {id:11, title:"프아 니어리스트 OPEN", type:"니어리스트", status:"진행중",   dday:"D-10", date:"2024.10.14 ~ 2024.10.31", grad:"linear-gradient(135deg,#16A34A,#4ADE80)"},
  {id:12, title:"프아 홀인원 챌린지",   type:"홀인원",   status:"진행 예정", dday:"D-20", date:"2024.11.01 ~ 2024.11.30", grad:"linear-gradient(135deg,#7C3AED,#A78BFA)"},
  {id:13, title:"프아 롱기스트 시즌3",  type:"장타",     status:"종료",                date:"2024.08.01 ~ 2024.08.31", grad:"linear-gradient(135deg,#DC2626,#F87171)"},
];
const EV_CONDITIONS = [["코스","벨라스톤 4홀"],["난이도","프로"],["그린 빠르기","빠름"],["바람 세기","강함"],["바람 방향","N"],["남성 티박스","Blue"],["여성 티박스","Yellow"],["핀 위치","중"]];
const EV_RULES = ["이벤트 기간 내 지정 코스에서 라운드한 기록만 순위에 반영됩니다.","동일 기록일 경우 먼저 달성한 순으로 순위가 결정됩니다.","부정 행위 적발 시 순위에서 제외되며 상품 지급이 취소됩니다.","상품은 이벤트 종료 후 개별 안내를 통해 지급됩니다."];
const EV_AWARDS = [["🥇","1위","반얀트리 호텔 숙박권 (2인)"],["🥈","2위","신세계 상품권 30만원"],["🥉","3위","광동제약 건강식품 세트"],["🎁","참가상","프렌즈 스크린 이용권 (선착순 100명)"]];
const EV_MYRANK = {r:99, name:"삼나무", dist:"316.2m", speed:"87m/s", store:"동탄그린바이스타점"};
const EV_RANK = [
  {r:1, name:"지나태윤", dist:"340.1m"}, {r:2, name:"쏭크리스탈", dist:"336.8m"}, {r:3, name:"다다제이", dist:"329.5m"},
  {r:4, name:"밤토리엄니", dist:"325.3m"}, {r:5, name:"청라동버디땅콩", dist:"322.1m"}, {r:6, name:"김프로0108", dist:"319.6m"},
  {r:7, name:"삼나무", dist:"316.2m"}, {r:8, name:"수내이덕화", dist:"312.9m"}, {r:9, name:"도윤멘", dist:"309.4m"}, {r:10, name:"이서준", dist:"305.0m"},
];
const EV_WINNERS = [
  {rank:"대상", name:"골든하이머", prize:"제주 왕복 항공권 (2인)"},
  {rank:"금상", name:"버디사냥꾼", prize:"신세계 상품권 50만원"},
  {rank:"은상", name:"어프로치장인", prize:"프렌즈 스크린 이용권 20매"},
  {rank:"동상", name:"미라니에", prize:"골프공 1더즌"},
  {rank:"참가상", name:"외 100명", prize:"스타벅스 기프티콘"},
];

// 이벤트 카드 (배너 + 정보)
function EvCard({ e, onOpen }){
  return (
    <button onClick={()=>onOpen(e)} style={{display:"block",width:"100%",textAlign:"left",background:"transparent",border:"none",padding:0,marginBottom:20}}>
      <div style={{position:"relative",height:118,borderRadius:12,overflow:"hidden",background:e.grad,display:"flex",flexDirection:"column",justifyContent:"center",padding:"0 18px"}}>
        {e.type && <span style={{position:"absolute",left:12,top:12,fontSize:10.5,fontWeight:800,color:"#fff",background:"rgba(0,0,0,.25)",padding:"2px 8px",borderRadius:10}}>{e.type}</span>}
        <div style={{fontSize:12,fontWeight:700,color:"rgba(255,255,255,.85)"}}>{e.desc||e.sub}</div>
        <div style={{fontSize:22,fontWeight:900,color:"#fff",letterSpacing:"-.02em",marginTop:2,textShadow:"0 1px 3px rgba(0,0,0,.15)"}}>{e.label||e.type}</div>
      </div>
      <div style={{fontSize:15,fontWeight:800,letterSpacing:"-.01em",margin:"10px 0 6px",lineHeight:1.35}}>{e.title}</div>
      <div style={{display:"flex",alignItems:"center",justifyContent:"space-between"}}>
        <span style={{fontSize:12.5,fontWeight:700,color:chStatusColor(e.status)}}>{e.status}{e.dday?` ${e.dday}`:""}</span>
        <span className="mono" style={{fontSize:12,color:"var(--text-sub)"}}>{e.date}</span>
      </div>
    </button>
  );
}

function EventList({ onBack, onOpenScreen, onOpenAcademy, initialTab }){
  const [tab, setTab] = React.useState(initialTab==="academy"?"academy":"screen");
  const [filter, setFilter] = React.useState("전체");
  const [demoEmpty, setDemoEmpty] = React.useState(false);
  const screen = tab==="screen";
  const list = demoEmpty ? [] : (screen ? EV_SCREEN.filter(e=> filter==="전체" ? true : !!e.winner) : EV_ACADEMY);
  return (
    <div className="screen">
      <StatusBar/>
      <Appbar title="이벤트" onBack={onBack}
        right={<button onClick={()=>setDemoEmpty(v=>!v)} style={{fontSize:9,fontWeight:600,color:"var(--text-mute)",background:"transparent",border:"1px dashed var(--line)",borderRadius:4,padding:"3px 6px"}}>데모:{demoEmpty?"빈":"이벤트"}</button>}/>
      <div style={{display:"flex",borderBottom:"1px solid var(--line)"}}>
        {[["screen","스크린"],["academy","아카데미"]].map(([id,label])=>(
          <button key={id} onClick={()=>setTab(id)} style={{flex:1,padding:"14px 0",fontSize:15,fontWeight:700,color:tab===id?"var(--text)":"var(--text-mute)",borderBottom:"2px solid "+(tab===id?"var(--primary)":"transparent"),background:"none"}}>{label}</button>
        ))}
      </div>
      <div className="scroll" style={{padding:"12px 20px 24px"}}>
        {/* AD 배너 */}
        <div style={{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"14px 16px",background:"var(--bg-soft)",borderRadius:10,marginBottom:14}}>
          <span style={{fontSize:13,fontWeight:700}}>티스테이션컵과 홀인원 이벤트</span>
          <span style={{fontSize:10,color:"var(--text-mute)",border:"1px solid var(--line-strong)",borderRadius:4,padding:"1px 5px"}}>AD</span>
        </div>
        {screen && (
          <div style={{display:"flex",gap:8,marginBottom:16}}>
            {["전체","당첨자 발표"].map(f=>(
              <button key={f} onClick={()=>setFilter(f)} style={{fontSize:13,fontWeight:filter===f?700:600,padding:"7px 15px",borderRadius:18,border:filter===f?"none":"1px solid var(--line-strong)",background:filter===f?"#1A1C1F":"#fff",color:filter===f?"#fff":"var(--text-sub)"}}>{f}</button>
            ))}
          </div>
        )}
        {list.length===0 ? (
          <div style={{padding:"56px 30px",textAlign:"center"}}>
            <img src="assets/course-empty.png" alt="" style={{width:120,height:126,objectFit:"contain"}}/>
            <div style={{fontSize:15,fontWeight:600,color:"var(--text-mute)",marginTop:14}}>진행 중이거나 참여한 이벤트가 없어요.</div>
          </div>
        ) : list.map(e=><EvCard key={e.id} e={e} onOpen={screen?onOpenScreen:onOpenAcademy}/>)}
      </div>
    </div>
  );
}

// 스크린 이벤트 상세 (프로모션 랜딩)
function EventScreenDetail({ event, onBack }){
  const e = event || EV_SCREEN[0];
  const [toast, setToast] = React.useState(null);
  const [joined, setJoined] = React.useState(false);
  const [winnerOpen, setWinnerOpen] = React.useState(false);
  const ended = e.status==="종료";
  const pop = (m)=>{ setToast(m); window.clearTimeout(pop._t); pop._t=window.setTimeout(()=>setToast(null),2200); };
  const onPrimary = ()=>{ if(ended){ if(e.winner) setWinnerOpen(true); } else if(!joined){ setJoined(true); pop("이벤트에 응모되었어요!"); } };
  const disabled = (ended && !e.winner) || joined;
  return (
    <div className="screen">
      <StatusBar/>
      <Appbar title="이벤트" onBack={onBack}/>
      {toast && <div className="toast"><span>{toast}</span></div>}
      <div className="scroll" style={{paddingBottom:100}}>
        {/* 프로모 히어로 */}
        <div style={{background:e.grad,color:"#fff",padding:"26px 24px 30px",textAlign:"center"}}>
          <div style={{fontSize:12.5,fontWeight:700,opacity:.9}}>{e.sub}</div>
          <div style={{fontSize:19,fontWeight:800,marginTop:12,lineHeight:1.35}}>{e.desc}</div>
          <svg viewBox="0 0 120 90" width="150" height="112" style={{margin:"14px auto 0",display:"block"}}>
            <ellipse cx="60" cy="82" rx="42" ry="6" fill="rgba(0,0,0,.12)"/>
            <circle cx="60" cy="20" r="11" fill="#fff"/><path d="M52 16a8 8 0 0 1 16 0z" fill="#111827"/>
            <path d="M54 34 Q60 30 66 34 L70 60 Q60 66 50 60 Z" fill="#fff"/>
            <path d="M66 40 L92 20" stroke="#E5E7EB" strokeWidth="3" strokeLinecap="round"/>
            <path d="M50 58 L44 78 M70 58 L76 78" stroke="#fff" strokeWidth="6" strokeLinecap="round"/>
            <circle cx="30" cy="80" r="4" fill="#fff"/>
          </svg>
          <div style={{fontSize:34,fontWeight:900,letterSpacing:"-.03em",marginTop:8}}>{e.label}</div>
          <div style={{display:"inline-block",fontSize:13,fontWeight:700,marginTop:12,background:"rgba(255,255,255,.2)",padding:"6px 16px",borderRadius:16}}>{e.date}</div>
        </div>
        {/* 안내 */}
        <div style={{padding:"22px 20px 0"}}>
          <div className="h3" style={{marginBottom:10}}>이벤트 안내</div>
          <div style={{fontSize:13,color:"var(--text-sub)",lineHeight:1.7}}>{e.sub}가 함께하는 <b style={{color:"var(--text)"}}>{e.title}</b> 이벤트! 이벤트 기간 동안 스크린 골프를 즐기고 다양한 경품의 주인공이 되어보세요. 골프 실력과 상관없이 누구나 참여할 수 있습니다.</div>
        </div>
        <div style={{height:8,background:"var(--bg-soft)",margin:"20px 0 0"}}/>
        <div style={{padding:"18px 20px 0"}}>
          <div className="h3" style={{marginBottom:12}}>참여 방법</div>
          {["이벤트 기간 내 프렌즈 스크린 매장 방문","지정 코스에서 라운드 플레이","자동으로 이벤트에 응모 완료"].map((s,i)=>(
            <div key={i} style={{display:"flex",alignItems:"center",gap:12,marginBottom:12}}>
              <span style={{width:26,height:26,borderRadius:"50%",background:"var(--primary-tint)",color:"var(--primary)",fontSize:13,fontWeight:800,display:"flex",alignItems:"center",justifyContent:"center",flexShrink:0}}>{i+1}</span>
              <span style={{fontSize:13.5,fontWeight:600}}>{s}</span>
            </div>
          ))}
        </div>
        <div style={{padding:"18px 20px 20px",marginTop:8,background:"var(--bg-soft)"}}>
          <div style={{fontSize:13,fontWeight:700,marginBottom:10}}>유의사항</div>
          {["당첨자는 이벤트 종료 후 개별 안내됩니다.","경품은 제세공과금이 부과될 수 있습니다.","부정 참여 시 응모가 취소됩니다."].map((n,i)=>(
            <div key={i} style={{display:"flex",gap:8,marginBottom:8}}><span style={{width:3,height:3,borderRadius:"50%",background:"var(--text-mute)",marginTop:8,flexShrink:0}}/><span style={{fontSize:12,color:"var(--text-sub)",lineHeight:1.6}}>{n}</span></div>
          ))}
        </div>
      </div>
      <div style={{position:"absolute",left:0,right:0,bottom:0,padding:"14px 20px 24px",background:"#fff",borderTop:"1px solid var(--line)"}}>
        <button onClick={onPrimary} disabled={disabled} className={"btn "+(disabled?"btn-soft":"btn-primary")} style={{width:"100%",opacity:disabled?.7:1}}>{ended?(e.winner?"당첨 내역 확인하기":"종료된 이벤트"):(joined?"참여 완료":"이벤트 참여하기")}</button>
      </div>
      {winnerOpen && (
        <Sheet title="당첨자 발표" onClose={()=>setWinnerOpen(false)}>
          <div style={{padding:"0 20px 10px",fontSize:12.5,color:"var(--text-sub)"}}><b style={{color:"var(--text)"}}>{e.title}</b> 이벤트 당첨을 축하드립니다! 🎉</div>
          {EV_WINNERS.map((w,i)=>(
            <div key={i} style={{display:"flex",alignItems:"center",gap:12,padding:"14px 20px",borderTop:"1px solid var(--line)"}}>
              <span style={{fontSize:12,fontWeight:800,color:"var(--primary)",width:46,flexShrink:0}}>{w.rank}</span>
              <span style={{flex:1,fontWeight:700,fontSize:14}}>{w.name}</span>
              <span style={{fontSize:12,color:"var(--text-sub)",textAlign:"right"}}>{w.prize}</span>
            </div>
          ))}
        </Sheet>
      )}
    </div>
  );
}

// 아카데미 이벤트 상세 (히어로 + 요강/규정/랭킹/시상내역)
function EventAcademyDetail({ event, onBack, onOpenSwing }){
  const e = event || EV_ACADEMY[0];
  const [tab, setTab] = React.useState("info"); // info | rules | rank | award
  const [rankTab, setRankTab] = React.useState("score"); // score | join
  const [q, setQ] = React.useState("");
  const [joined, setJoined] = React.useState(false);
  const [toast, setToast] = React.useState(null);
  const ended = e.status==="종료";
  const list = EV_RANK.filter(r=> !q || r.name.includes(q));
  const join = ()=>{ if(joined) return; setJoined(true); setToast("이벤트에 참여했어요!"); window.clearTimeout(join._t); join._t=window.setTimeout(()=>setToast(null),2200); };
  const openSwing = (r)=> onOpenSwing && onOpenSwing({dist:r.dist, club:"드라이버", shot:"티샷", author:r.name, store:EV_MYRANK.store, community:true});
  return (
    <div className="screen">
      <StatusBar/>
      <Appbar title="이벤트 상세보기" onBack={onBack}/>
      {toast && <div className="toast"><span>{toast}</span></div>}
      <div className="scroll" style={{paddingBottom: ended?24:96}}>
        {/* 히어로 */}
        <div style={{padding:"14px 20px 6px",textAlign:"center"}}>
          <div style={{fontSize:19,fontWeight:800,letterSpacing:"-.02em"}}>{e.title}</div>
          <div style={{fontSize:12.5,color:"var(--text-sub)",marginTop:6}}>{e.date}</div>
          <div style={{marginTop:12,borderRadius:16,overflow:"hidden",background:"#EEF1F3"}}>
            <img src="assets/tournament-hero.png" alt="" style={{width:"100%",display:"block"}}/>
          </div>
        </div>
        {/* 탭 */}
        <div style={{display:"flex",borderBottom:"1px solid var(--line)"}}>
          {[["info","요강"],["rules","규정"],["rank","랭킹"],["award","시상내역"]].map(([id,label])=>(
            <button key={id} onClick={()=>setTab(id)} style={{flex:1,padding:"13px 0",fontSize:14,fontWeight:700,color:tab===id?"var(--text)":"var(--text-mute)",borderBottom:"2px solid "+(tab===id?"var(--primary)":"transparent"),background:"none"}}>{label}</button>
          ))}
        </div>

        {tab==="info" && (
          <div style={{padding:"8px 20px 0"}}>
            {EV_CONDITIONS.map(([k,v])=>(
              <div key={k} style={{display:"flex",justifyContent:"space-between",padding:"14px 0",borderBottom:"1px solid var(--line)",fontSize:13.5}}>
                <span style={{color:"var(--text-sub)"}}>{k}</span><span style={{fontWeight:700}}>{v}</span>
              </div>
            ))}
          </div>
        )}
        {tab==="rules" && (
          <div style={{padding:"20px"}}>
            {EV_RULES.map((r,i)=>(
              <div key={i} style={{display:"flex",gap:10,marginBottom:14}}>
                <span style={{fontSize:13,fontWeight:800,color:"var(--primary)",flexShrink:0}}>{i+1}</span>
                <span style={{fontSize:13.5,color:"var(--text-sub)",lineHeight:1.6}}>{r}</span>
              </div>
            ))}
          </div>
        )}
        {tab==="rank" && (
          <div style={{paddingTop:12}}>
            <div style={{display:"flex",gap:8,padding:"0 20px 12px"}}>
              {[["score","스코어"],["join","참여도"]].map(([id,label])=>(
                <button key={id} onClick={()=>setRankTab(id)} style={{fontSize:13,fontWeight:rankTab===id?700:600,padding:"7px 15px",borderRadius:18,border:rankTab===id?"none":"1px solid var(--line-strong)",background:rankTab===id?"#1A1C1F":"#fff",color:rankTab===id?"#fff":"var(--text-sub)"}}>{label}</button>
              ))}
            </div>
            <div style={{margin:"0 20px 14px",padding:"12px 14px",background:"var(--primary-tint)",borderRadius:10,fontSize:12,color:"var(--primary)",fontWeight:600,lineHeight:1.5}}>{e.type} 이벤트 순위는 {rankTab==="score"?"기록(거리) 순":"참여 횟수 순"}으로 표기됩니다.</div>
            <div style={{display:"flex",alignItems:"center",gap:12,padding:"12px 20px",background:"var(--primary-tint)"}}>
              <div style={{width:30,textAlign:"center",fontWeight:800,color:"var(--primary)"}}>{EV_MYRANK.r}</div>
              <div style={{flex:1,fontWeight:700}}>{EV_MYRANK.name}</div>
              <div style={{fontSize:12.5,fontWeight:800}}>{EV_MYRANK.dist}</div>
            </div>
            <div style={{display:"flex",gap:16,padding:"12px 20px",fontSize:12.5,color:"var(--text-sub)",fontWeight:600,borderBottom:"1px solid var(--line)"}}>
              <span>참가자 <b style={{color:"var(--text)"}}>970</b></span><span>{EV_MYRANK.store}</span>
            </div>
            <div style={{padding:"12px 20px 4px"}}>
              <div style={{display:"flex",alignItems:"center",gap:8,background:"var(--bg-soft)",borderRadius:10,padding:"10px 14px"}}>
                <Icon name="search" size={16} style={{color:"var(--text-mute)"}}/>
                <input value={q} onChange={e=>setQ(e.target.value)} placeholder="닉네임 검색" style={{border:"none",background:"transparent",outline:"none",fontSize:14,flex:1,minWidth:0}}/>
              </div>
            </div>
            {list.map(r=>(
              <div key={r.r} style={{display:"flex",alignItems:"center",gap:12,padding:"14px 20px",borderTop:"1px solid var(--line)"}}>
                <div style={{width:24,textAlign:"center",fontWeight:800,fontSize:14,color:r.r<=3?"var(--primary)":"var(--text-sub)"}}>{r.r}</div>
                <div style={{flex:1,fontWeight:600}}>{r.name}</div>
                <div style={{fontSize:13,fontWeight:700}}>{r.dist}</div>
                <button onClick={()=>openSwing(r)} style={{width:26,height:26,borderRadius:"50%",background:"var(--primary)",display:"flex",alignItems:"center",justifyContent:"center",color:"#fff",flexShrink:0,border:"none"}}><Icon name="play" size={11}/></button>
              </div>
            ))}
          </div>
        )}
        {tab==="award" && (
          <div style={{padding:"14px 20px 0"}}>
            {EV_AWARDS.map(([ic,rank,prize],i)=>(
              <div key={i} style={{display:"flex",alignItems:"center",gap:14,padding:"16px",background:"var(--bg-soft)",borderRadius:12,marginBottom:10}}>
                <span style={{fontSize:28}}>{ic}</span>
                <div><div style={{fontSize:14,fontWeight:800}}>{rank}</div><div style={{fontSize:12.5,color:"var(--text-sub)",marginTop:2}}>{prize}</div></div>
              </div>
            ))}
          </div>
        )}
      </div>
      {!ended && (
        <div style={{position:"absolute",left:0,right:0,bottom:0,padding:"14px 20px 24px",background:"#fff",borderTop:"1px solid var(--line)"}}>
          <button onClick={join} disabled={joined} className={"btn "+(joined?"btn-soft":"btn-primary")} style={{width:"100%",opacity:joined?.7:1}}>{joined?"참여 완료":"이벤트 참여하기"}</button>
        </div>
      )}
    </div>
  );
}

// ===== 구독 (스크린 골프 프리미엄) =====
// 구독 플랜 — 월간/연간 (첨부 표 기준 혜택 해금)
const SUB_PLANS = [
  {id:"monthly", name:"월간 구독", price:19900,  per:"월", cycle:"매월", note:"매월 자동 결제"},
  {id:"yearly",  name:"연간 구독", price:199000, per:"년", cycle:"매년", note:"2개월 할인 · 매년 자동 결제", best:true, permo:16584},
];
// 구독 시 해금되는 핵심 기능
const SUB_HILITE = [
  {t:"18홀 라운드",   d:"기본 9홀 → 9·18홀", ic:"flag"},
  {t:"9홀 멀티플레이", d:"친구와 함께 라운드", ic:"users"},
  {t:"코스 60개",     d:"기본 30개 → 60개", ic:"map"},
  {t:"코스 트레이닝",  d:"실전 코스로 연습",   ic:"target"},
  {t:"미니게임 다트",  d:"라운드 후 즐기기",   ic:"game"},
];
// 기본 제공 vs 구독 비교표 (val: true=제공 / false=미제공 / 문자열=값)
const SUB_COMPARE = [
  {f:"스트로크 라운드",  base:"9홀",  sub:"9·18홀"},
  {f:"9홀 멀티플레이",   base:false,  sub:true},
  {f:"제공 코스",        base:"30개", sub:"60개"},
  {f:"샷 트레이닝",      base:true,   sub:true, note:"롱·숏·퍼팅 모두 포함"},
  {f:"클럽 측정",        base:true,   sub:true, note:"샷 트레이닝 내 기능"},
  {f:"AI 스윙분석",      base:true,   sub:true, note:"IP 카메라 별도 필요"},
  {f:"코스 트레이닝",    base:false,  sub:true},
  {f:"미니게임 · 다트",  base:false,  sub:true, note:"틱택토는 2인 이상이라 미제공"},
  {f:"9X 스윙 플레이트", base:false,  sub:true, note:"하드웨어 별도 필요"},
  {f:"매트 디스플레이",  base:false,  sub:true, note:"하드웨어 별도(Q eye mini)"},
];
const subFmt = (n)=> n.toLocaleString("ko-KR");
function SubIcon({ name, size=20, color="var(--primary)" }){
  const c = {viewBox:"0 0 24 24",width:size,height:size,fill:"none",stroke:color,strokeWidth:1.8,strokeLinecap:"round",strokeLinejoin:"round"};
  const g = {
    flag:  <><path d="M6 21V4"/><path d="M6 5h11l-2 3 2 3H6"/></>,
    users: <><circle cx="9" cy="8" r="3"/><path d="M3 20c0-3 3-5 6-5s6 2 6 5"/><path d="M16 6a3 3 0 0 1 0 6M17 15c2 .4 4 2 4 5"/></>,
    map:   <><path d="M9 4 3 6v14l6-2 6 2 6-2V4l-6 2-6-2z"/><path d="M9 4v14M15 6v14"/></>,
    target:<><circle cx="12" cy="12" r="8"/><circle cx="12" cy="12" r="4"/><circle cx="12" cy="12" r="1"/></>,
    game:  <><circle cx="11" cy="13" r="7"/><circle cx="11" cy="13" r="2.6"/><path d="M11 13l7.5-7.5M14.5 5.5h4v4"/></>,
  }[name];
  return <svg {...c}>{g}</svg>;
}
function SubCmpCell({ v }){
  if(v===true)  return <Icon name="check" size={16} style={{color:"var(--primary)"}}/>;
  if(v===false) return <span style={{color:"var(--text-mute)",fontSize:14}}>–</span>;
  return <span style={{fontSize:12.5,fontWeight:700}}>{v}</span>;
}

// 구독 신청/관리 — 미구독: 소개·플랜 선택 / 구독중: 관리·해지
function SubscribeScreen({ sub, onBack, onCheckout, onCancel, justSubscribed }){
  const [plan, setPlan] = React.useState("yearly");
  const [cancelOpen, setCancelOpen] = React.useState(false);
  const [toast, setToast] = React.useState(justSubscribed ? "구독이 시작되었어요! 🎉" : null);
  React.useEffect(()=>{ if(toast){ const t=setTimeout(()=>setToast(null),2400); return ()=>clearTimeout(t); } },[]);
  const sel = SUB_PLANS.find(p=>p.id===plan);

  // ---- 구독중: 관리 화면 ----
  if(sub){
    const p = SUB_PLANS.find(x=>x.id===sub.plan) || SUB_PLANS[1];
    return (
      <div className="screen">
        <StatusBar/>
        <Appbar title="구독 관리" onBack={onBack}/>
        {toast && <div className="toast"><span>{toast}</span></div>}
        <div className="scroll" style={{padding:"16px 20px 40px"}}>
          <div style={{borderRadius:16,padding:"20px",background:"linear-gradient(135deg,#0E7A3B 0%,#16A34A 60%,#22C55E 100%)",color:"#fff"}}>
            <div style={{display:"flex",alignItems:"center",gap:6,fontSize:12,fontWeight:700,opacity:.9}}><span style={{background:"rgba(255,255,255,.22)",borderRadius:5,padding:"2px 7px"}}>구독중</span>프렌즈 스크린 프리미엄</div>
            <div style={{fontSize:22,fontWeight:800,marginTop:10,letterSpacing:"-.02em"}}>{p.name}</div>
            <div style={{fontSize:13,marginTop:4,opacity:.92}}>다음 결제일 {sub.nextBill} · {subFmt(p.price)}원</div>
          </div>
          <div className="card" style={{padding:"4px 0",marginTop:14}}>
            {[["결제 수단", sub.method==="vxmoney"?"VX머니 자동결제":"카드 정기결제"],["결제 주기", p.cycle+" 자동 갱신"],["구독 시작일", sub.since]].map(([k,v],i)=>(
              <div key={i} style={{display:"flex",justifyContent:"space-between",padding:"13px 16px",borderTop:i?"1px solid var(--line)":"none"}}>
                <span style={{fontSize:13.5,color:"var(--text-sub)"}}>{k}</span>
                <span style={{fontSize:13.5,fontWeight:700}}>{v}</span>
              </div>
            ))}
          </div>
          <div style={{fontSize:15,fontWeight:800,margin:"22px 0 10px",letterSpacing:"-.02em"}}>이용 중인 혜택</div>
          <div style={{display:"flex",flexDirection:"column",gap:8}}>
            {SUB_HILITE.map((h,i)=>(
              <div key={i} style={{display:"flex",alignItems:"center",gap:12,padding:"13px 14px",background:"var(--bg-soft)",borderRadius:12}}>
                <span style={{width:36,height:36,borderRadius:10,background:"var(--primary-tint)",display:"flex",alignItems:"center",justifyContent:"center",flexShrink:0}}><SubIcon name={h.ic} size={18}/></span>
                <div><div style={{fontSize:14,fontWeight:700}}>{h.t}</div><div style={{fontSize:12,color:"var(--text-sub)",marginTop:1}}>{h.d}</div></div>
              </div>
            ))}
          </div>
          <div style={{display:"flex",gap:8,alignItems:"flex-start",marginTop:16,padding:"12px 14px",background:"var(--primary-tint)",borderRadius:12}}>
            <Icon name="check" size={16} style={{color:"var(--primary)",marginTop:1,flexShrink:0}}/>
            <div style={{fontSize:12.5,color:"var(--text-sub)",lineHeight:1.55}}>매장에서 <b style={{color:"var(--text)"}}>스크린 골프 실행 시 자동으로 적용</b>돼요. (일부 기능은 하드웨어 설치 매장에서 이용 가능)</div>
          </div>
          <button onClick={()=>setToast("결제 수단 변경은 준비 중이에요.")} className="btn btn-soft" style={{width:"100%",height:46,marginTop:18}}>결제 수단 변경</button>
          <button onClick={()=>setCancelOpen(true)} style={{width:"100%",height:46,marginTop:8,background:"transparent",border:"none",color:"var(--text-mute)",fontSize:13.5,fontWeight:600}}>구독 해지하기</button>
        </div>
        {cancelOpen && (
          <Sheet title="구독을 해지할까요?" onClose={()=>setCancelOpen(false)}
            footer={<div style={{display:"flex",gap:8}}>
              <button onClick={()=>setCancelOpen(false)} className="btn btn-soft" style={{flex:1,height:48}}>유지하기</button>
              <button onClick={()=>{ setCancelOpen(false); onCancel&&onCancel(); }} className="btn" style={{flex:1,height:48,background:"#FEECEC",color:"#EF4444",fontWeight:800}}>해지하기</button>
            </div>}>
            <div style={{padding:"4px 20px 8px",fontSize:13.5,color:"var(--text-sub)",lineHeight:1.6}}>
              해지해도 <b style={{color:"var(--text)"}}>{sub.nextBill}까지</b>는 프리미엄 혜택을 계속 이용할 수 있어요. 이후에는 기본 제공 기능(9홀 스트로크·샷 트레이닝·AI 스윙분석)만 사용할 수 있어요.
            </div>
          </Sheet>
        )}
      </div>
    );
  }

  // ---- 미구독: 소개 + 플랜 선택 ----
  return (
    <div className="screen">
      <StatusBar/>
      <Appbar title="구독" onBack={onBack}/>
      <div className="scroll" style={{padding:"0 0 108px"}}>
        {/* 히어로 */}
        <div style={{padding:"18px 20px 22px",background:"linear-gradient(135deg,#0E7A3B 0%,#16A34A 55%,#22C55E 100%)",color:"#fff"}}>
          <div style={{fontSize:12.5,fontWeight:700,opacity:.9}}>프렌즈 스크린 프리미엄</div>
          <div style={{fontSize:23,fontWeight:800,marginTop:8,lineHeight:1.3,letterSpacing:"-.02em"}}>스크린 골프를<br/>더 깊게 즐기는 방법</div>
          <div style={{fontSize:13.5,marginTop:10,opacity:.92,lineHeight:1.5}}>구독하면 18홀 라운드·멀티플레이·코스 트레이닝 등<br/>추가 기능을 매장에서 바로 사용할 수 있어요.</div>
        </div>

        {/* 해금 핵심 기능 */}
        <div style={{padding:"20px 20px 0"}}>
          <div style={{fontSize:16,fontWeight:800,marginBottom:12,letterSpacing:"-.02em"}}>구독하면 이런 기능이 열려요</div>
          <div style={{display:"flex",flexDirection:"column",gap:8}}>
            {SUB_HILITE.map((h,i)=>(
              <div key={i} style={{display:"flex",alignItems:"center",gap:12,padding:"13px 14px",background:"var(--bg-soft)",borderRadius:12}}>
                <span style={{width:38,height:38,borderRadius:11,background:"var(--primary-tint)",display:"flex",alignItems:"center",justifyContent:"center",flexShrink:0}}><SubIcon name={h.ic}/></span>
                <div style={{flex:1}}><div style={{fontSize:14.5,fontWeight:700}}>{h.t}</div><div style={{fontSize:12,color:"var(--text-sub)",marginTop:1}}>{h.d}</div></div>
              </div>
            ))}
          </div>
        </div>

        {/* 전체 혜택 비교 */}
        <div style={{padding:"24px 20px 0"}}>
          <div style={{fontSize:16,fontWeight:800,marginBottom:12,letterSpacing:"-.02em"}}>기본 제공 vs 구독</div>
          <div className="card" style={{padding:0,overflow:"hidden"}}>
            <div style={{display:"grid",gridTemplateColumns:"1fr 62px 62px",padding:"11px 14px",background:"var(--bg-soft)",fontSize:11.5,fontWeight:700,color:"var(--text-mute)"}}>
              <div>기능</div><div style={{textAlign:"center"}}>기본</div><div style={{textAlign:"center",color:"var(--primary)"}}>구독</div>
            </div>
            {SUB_COMPARE.map((r,i)=>(
              <div key={i} style={{display:"grid",gridTemplateColumns:"1fr 62px 62px",padding:"11px 14px",borderTop:"1px solid var(--line)",alignItems:"center"}}>
                <div>
                  <div style={{fontSize:13,fontWeight:600}}>{r.f}</div>
                  {r.note && <div style={{fontSize:10.5,color:"var(--text-mute)",marginTop:2,lineHeight:1.35}}>{r.note}</div>}
                </div>
                <div style={{textAlign:"center"}}><SubCmpCell v={r.base}/></div>
                <div style={{textAlign:"center"}}><SubCmpCell v={r.sub}/></div>
              </div>
            ))}
          </div>
        </div>

        {/* 플랜 선택 */}
        <div style={{padding:"24px 20px 0"}}>
          <div style={{fontSize:16,fontWeight:800,marginBottom:12,letterSpacing:"-.02em"}}>플랜 선택</div>
          <div style={{display:"flex",flexDirection:"column",gap:10}}>
            {SUB_PLANS.map(p=>{
              const on = plan===p.id;
              return (
                <button key={p.id} onClick={()=>setPlan(p.id)} style={{position:"relative",width:"100%",textAlign:"left",padding:"16px",borderRadius:14,background:"#fff",border:"1.5px solid "+(on?"var(--primary)":"var(--line)"),display:"flex",alignItems:"center",gap:13}}>
                  <span style={{width:20,height:20,borderRadius:"50%",border:"1.5px solid "+(on?"var(--primary)":"var(--line-strong)"),display:"flex",alignItems:"center",justifyContent:"center",flexShrink:0}}>{on && <span style={{width:11,height:11,borderRadius:"50%",background:"var(--primary)"}}/>}</span>
                  <div style={{flex:1}}>
                    <div style={{display:"flex",alignItems:"center",gap:6}}>
                      <span style={{fontSize:15,fontWeight:800}}>{p.name}</span>
                      {p.best && <span style={{fontSize:10.5,fontWeight:800,color:"#fff",background:"var(--primary)",borderRadius:5,padding:"2px 6px"}}>2개월 할인</span>}
                    </div>
                    <div style={{fontSize:12,color:"var(--text-sub)",marginTop:3}}>{p.note}{p.permo && ` · 월 ${subFmt(p.permo)}원 꼴`}</div>
                  </div>
                  <div style={{textAlign:"right",flexShrink:0}}>
                    <div style={{fontSize:16,fontWeight:800}}>{subFmt(p.price)}<span style={{fontSize:12,fontWeight:700}}>원</span></div>
                    <div style={{fontSize:11,color:"var(--text-mute)"}}>/{p.per}</div>
                  </div>
                </button>
              );
            })}
          </div>
          <div style={{fontSize:11.5,color:"var(--text-mute)",marginTop:10,lineHeight:1.5}}>· 구독은 해지 전까지 {sel.cycle} 자동 갱신돼요.<br/>· AI 스윙분석·9X 스윙 플레이트·매트 디스플레이는 하드웨어가 설치된 매장에서 이용할 수 있어요.</div>
        </div>
      </div>

      {/* 하단 고정 CTA */}
      <div style={{position:"absolute",left:0,right:0,bottom:0,padding:"12px 20px 22px",background:"#fff",borderTop:"1px solid var(--line)"}}>
        <button onClick={()=>onCheckout&&onCheckout(plan)} className="btn btn-primary" style={{width:"100%",height:52,fontSize:16}}>{subFmt(sel.price)}원 · {sel.name}하기</button>
      </div>
    </div>
  );
}

// 구독 결제 — 플랜 요약 + 결제수단(카드 정기결제/VX머니) + 자동갱신 동의
function SubscribePay({ plan, onBack, onDone }){
  const p = SUB_PLANS.find(x=>x.id===plan) || SUB_PLANS[1];
  const [method, setMethod] = React.useState("card");
  const [agree, setAgree] = React.useState(false);
  const [card, setCard] = React.useState(null); // 등록 카드 (데모)
  const methods = [
    {id:"card",    label:"카드 정기결제", sub:"등록한 카드로 자동 결제·갱신", badge:"CARD"},
    {id:"vxmoney", label:"VX머니 자동결제", sub:"연동 계좌에서 자동 출금 · 1% 적립", badge:"VX"},
  ];
  return (
    <div className="screen">
      <StatusBar/>
      <Appbar title="구독 결제" onBack={onBack}/>
      <div className="scroll" style={{padding:"16px 20px 120px"}}>
        {/* 선택 플랜 요약 */}
        <div className="card" style={{padding:"16px"}}>
          <div style={{display:"flex",alignItems:"center",justifyContent:"space-between"}}>
            <div>
              <div style={{fontSize:12,color:"var(--text-sub)",fontWeight:600}}>프렌즈 스크린 프리미엄</div>
              <div style={{fontSize:17,fontWeight:800,marginTop:3,display:"flex",alignItems:"center",gap:6}}>{p.name}{p.best && <span style={{fontSize:10.5,fontWeight:800,color:"#fff",background:"var(--primary)",borderRadius:5,padding:"2px 6px"}}>2개월 할인</span>}</div>
            </div>
            <div style={{textAlign:"right"}}>
              <div style={{fontSize:19,fontWeight:800}}>{subFmt(p.price)}<span style={{fontSize:12,fontWeight:700}}>원</span></div>
              <div style={{fontSize:11,color:"var(--text-mute)"}}>{p.cycle} 갱신</div>
            </div>
          </div>
        </div>

        {/* 결제 수단 */}
        <div style={{fontSize:15,fontWeight:800,margin:"22px 0 10px"}}>결제 수단</div>
        <div style={{display:"flex",flexDirection:"column",gap:8}}>
          {methods.map(m=>{
            const on = method===m.id;
            return (
              <button key={m.id} onClick={()=>setMethod(m.id)} style={{width:"100%",textAlign:"left",padding:"14px",borderRadius:12,background:"#fff",border:"1.5px solid "+(on?"var(--primary)":"var(--line)"),display:"flex",alignItems:"center",gap:12}}>
                <span style={{width:20,height:20,borderRadius:"50%",border:"1.5px solid "+(on?"var(--primary)":"var(--line-strong)"),display:"flex",alignItems:"center",justifyContent:"center",flexShrink:0}}>{on && <span style={{width:11,height:11,borderRadius:"50%",background:"var(--primary)"}}/>}</span>
                <div style={{flex:1}}>
                  <div style={{fontSize:14.5,fontWeight:700}}>{m.label}</div>
                  <div style={{fontSize:12,color:"var(--text-sub)",marginTop:2}}>{m.sub}</div>
                </div>
                <span style={{fontSize:10,fontWeight:800,color:"var(--text-mute)",border:"1px solid var(--line-strong)",borderRadius:5,padding:"3px 6px"}}>{m.badge}</span>
              </button>
            );
          })}
        </div>
        {method==="card" && (card
          ? <div style={{marginTop:8,padding:"13px 14px",borderRadius:12,background:"#fff",border:"1px solid var(--line-strong)",display:"flex",alignItems:"center",gap:10}}>
              <span style={{width:30,height:20,borderRadius:4,background:"linear-gradient(135deg,#4B5563,#111827)",flexShrink:0}}/>
              <span style={{flex:1,fontSize:13.5,fontWeight:700}}>{card}</span>
              <button onClick={()=>setCard(null)} style={{fontSize:12,fontWeight:600,color:"var(--text-mute)",background:"transparent",border:"none"}}>변경</button>
            </div>
          : <button onClick={()=>setCard("신한카드 (****1234)")} style={{width:"100%",marginTop:8,padding:"13px 14px",borderRadius:12,background:"var(--bg-soft)",border:"1px dashed var(--line-strong)",display:"flex",alignItems:"center",gap:8,color:"var(--text-sub)",fontSize:13,fontWeight:600}}>
              <Icon name="plus" size={16}/> 결제 카드 등록
            </button>
        )}

        {/* 자동 갱신 안내 */}
        <div style={{marginTop:20,padding:"14px 16px",borderRadius:12,background:"var(--bg-soft)"}}>
          <div style={{fontSize:13,fontWeight:800,marginBottom:6}}>자동 갱신 안내</div>
          <div style={{fontSize:12,color:"var(--text-sub)",lineHeight:1.6}}>
            · 오늘 {subFmt(p.price)}원이 결제되고, 해지 전까지 {p.cycle} 자동 갱신돼요.<br/>
            · 다음 결제 예정일 전에 언제든 해지할 수 있어요.<br/>
            · 결제 시점의 혜택·요금은 정책에 따라 달라질 수 있어요.
          </div>
        </div>

        {/* 필수 동의 */}
        <button onClick={()=>setAgree(v=>!v)} style={{display:"flex",alignItems:"center",gap:10,width:"100%",padding:"14px 2px",marginTop:6,background:"transparent",border:"none",textAlign:"left"}}>
          <span style={{width:22,height:22,borderRadius:6,background:agree?"var(--primary)":"#fff",border:"1.5px solid "+(agree?"var(--primary)":"var(--line-strong)"),display:"flex",alignItems:"center",justifyContent:"center",flexShrink:0}}>{agree && <Icon name="check" size={14} style={{color:"#fff"}}/>}</span>
          <span style={{fontSize:13.5,color:"var(--text-sub)"}}><b style={{color:"var(--text)"}}>(필수)</b> 구독 이용약관 및 자동결제에 동의합니다.</span>
        </button>
      </div>

      <div style={{position:"absolute",left:0,right:0,bottom:0,padding:"12px 20px 22px",background:"#fff",borderTop:"1px solid var(--line)"}}>
        <button disabled={!agree} onClick={()=>onDone&&onDone({plan:p.id, method})} className="btn btn-primary" style={{width:"100%",height:52,fontSize:16,opacity:agree?1:.45}}>{subFmt(p.price)}원 결제하고 구독 시작</button>
      </div>
    </div>
  );
}

Object.assign(window, { SwingScreen, SwingVideoDetail, SwingUpload, SwingDraw, SwingDetail, ClubMeasure, ClubShotData, BookingList, BookingDetail, BookingCancel, AddressSearch, PasswordChange, Withdraw, MenuScreen, PointsCash, Certificates, Lockers, GameSettings, AppSettings, ProfileEdit, Notifications, Attendance, NoShowStatus, NoticeScreen, NoticeDetail, CourseIntro, CourseDetail, ChampionshipList, ChampionshipDetail, ChampionshipCreate, EventList, EventScreenDetail, EventAcademyDetail, SubscribeScreen, SubscribePay, CertificateDetail });
