// ============================================================
// pages.jsx — 부바 서브 페이지들 (카탈로그, 상세, 업로드, 뷰어, 마이페이지, 결제)
// ============================================================
// 기존 app.jsx 라우팅 계약 유지:
//   onNavigate(key) — 'landing'|'catalog'|'storyDetail'|'upload'|'reader'|'mypage'|'checkout'|'login'|'register'
//   props: user, token, onLogout, context(선택) — 라우트 간 전달값
// ------------------------------------------------------------
// 외부 의존: Nav, SiteFooter, BookCover, StarRating, Ico, WatercolorBG (common.jsx)
//           window.BUBA_STORIES, window.BUBA_TAGS, window.BUBA_SAMPLE_PAGES (data/stories.js)
// ============================================================

// ---------- 안전 폴백 (common.jsx 미로드 시) ----------
if (typeof BubaLogo === 'undefined') window.BubaLogo = () => React.createElement('span', {style:{fontWeight:800,fontSize:20,color:'#7E57C2'}}, 'BUBA');
if (typeof Ico === 'undefined') window.Ico = new Proxy({}, { get: () => ({size}) => React.createElement('span', null, '') });
if (typeof BookCover === 'undefined') window.BookCover = ({story,w}) => React.createElement('div', {style:{width:w||280,aspectRatio:'2/1',background:story?.color||'#B39DDB',borderRadius:14,display:'flex',alignItems:'center',justifyContent:'center',color:'#fff',fontSize:40}}, story?.emoji||'📖');
if (typeof SiteFooter === 'undefined') window.SiteFooter = () => React.createElement('footer', {style:{padding:40,textAlign:'center',background:'#1E1230',color:'rgba(255,255,255,0.5)',fontSize:13}}, '© BUBA');

// ---------- 상단 공용 네비 (auth 상태 연결) ----------
function AuthNav({ onNavigate, user, token, onLogout, active }) {
  return (
    <nav aria-label="주요 메뉴" style={{
      display:'flex', alignItems:'center', justifyContent:'space-between',
      padding:'16px 32px', position:'sticky', top:0, zIndex:100,
      background:'rgba(255,255,255,0.88)', backdropFilter:'blur(14px)',
      borderBottom:'1px solid rgba(209,196,233,0.4)',
    }}>
      <div style={{cursor:'pointer'}} onClick={() => onNavigate('landing')}><BubaLogo/></div>
      <div style={{display:'flex', gap:24, alignItems:'center'}} className="hide-mobile">
        <a onClick={()=>onNavigate('landing')} style={{fontSize:14, fontWeight: active==='home'?700:500, color: active==='home'?'#7E57C2':'#37274A', cursor:'pointer'}}>홈</a>
        <a onClick={()=>onNavigate('catalog')} style={{fontSize:14, fontWeight: active==='stories'?700:500, color: active==='stories'?'#7E57C2':'#37274A', cursor:'pointer'}}>스토리</a>
        {token && <a onClick={()=>onNavigate('mypage')} style={{fontSize:14, fontWeight: active==='mypage'?700:500, color: active==='mypage'?'#7E57C2':'#37274A', cursor:'pointer'}}>마이페이지</a>}
      </div>
      <div style={{display:'flex', gap:10, alignItems:'center'}}>
        {token && user ? (
          <>
            <span style={{fontSize:13, color:'#37274A'}}>{user.name || user.email}님</span>
            <button onClick={() => onNavigate('upload')} className="btn btn-primary" style={{padding:'9px 18px', fontSize:13}}>
              <Ico.Wand size={14}/> 동화 만들기
            </button>
            <button onClick={onLogout} className="btn-ghost" style={{fontSize:13}}>로그아웃</button>
          </>
        ) : (
          <>
            <button onClick={() => onNavigate('login')} className="btn-ghost" style={{fontSize:13}}>로그인</button>
            <button onClick={() => onNavigate('register')} className="btn btn-primary" style={{padding:'9px 18px', fontSize:13}}>
              무료 시작하기
            </button>
          </>
        )}
      </div>
    </nav>
  );
}

// ============================================================
// 1. CATALOG — 스토리 카탈로그 (남부키 12 / 여바바 10)
// ============================================================
window.CatalogPage = function CatalogPage({ onNavigate, user, token, onLogout }) {
  const [tab, setTab] = React.useState('boy');
  const [filter, setFilter] = React.useState('전체');
  const [query, setQuery] = React.useState('');
  const [showPaywall, setShowPaywall] = React.useState(false);
  const [config, setConfig] = React.useState({});
  const stories = (window.BUBA_STORIES?.[tab]) || [];
  const filtered = stories
    .filter(s => filter==='전체' || s.tag === filter)
    .filter(s => !query || s.title.includes(query) || s.description.includes(query));
  const charName = tab === 'boy' ? '부키' : '바바';
  const isUnlocked = user?.catalog_unlocked || false;
  const freeCount = config.free_story_count || 1;

  React.useEffect(() => {
    fetch('/api/config/public').then(r=>r.json()).then(setConfig).catch(()=>{});
  }, []);

  const allBoy = window.BUBA_STORIES?.boy || [];
  const allGirl = window.BUBA_STORIES?.girl || [];
  const freeIds = new Set([...allBoy.slice(0, freeCount).map(s=>s.id), ...allGirl.slice(0, freeCount).map(s=>s.id)]);

  const handleCardClick = (story) => {
    if (isUnlocked || freeIds.has(story.id)) {
      onNavigate('storyDetail', {storyId: story.id});
    } else {
      setShowPaywall(true);
    }
  };

  return (
    <div style={{minHeight:'100vh', background:'#FBF8FF', color:'#37274A'}}>
      <AuthNav onNavigate={onNavigate} user={user} token={token} onLogout={onLogout} active="stories"/>
      <section style={{padding:'48px 32px 32px', background:'linear-gradient(180deg, #F3E5F5, #FBF8FF)'}}>
        <div style={{maxWidth:1280, margin:'0 auto'}}>
          <div className="eyebrow" style={{marginBottom:10}}>— STORY LIBRARY —</div>
          <h1 style={{fontSize:'clamp(28px, 4vw, 44px)', color:'#311B57', marginBottom:14}}>22편의 이야기, 우리 아이는 어떤 주인공이 될까요?</h1>
          <div style={{display:'flex', gap:16, alignItems:'center', marginTop:24, flexWrap:'wrap'}}>
            <div style={{display:'flex', gap:8}}>
              {[{k:'boy', l:'부키 (남) 12편', c:'#B39DDB'},{k:'girl', l:'바바 (여) 10편', c:'#F48FB1'}].map(t=>(
                <button key={t.k} onClick={()=>{setTab(t.k);setFilter('전체');}}
                  style={{padding:'10px 20px', borderRadius:10, fontWeight:700, cursor:'pointer',
                    background: tab===t.k? t.c:'#fff', color: tab===t.k?'#fff':'#37274A',
                    border: tab===t.k?'none':'1.5px solid #D1C4E9'}}>
                  {t.l}
                </button>
              ))}
            </div>
            <input className="input" placeholder="이야기 검색..." value={query} onChange={e=>setQuery(e.target.value)} style={{maxWidth:240}}/>
          </div>
          <div style={{display:'flex', gap:6, flexWrap:'wrap', marginTop:16}}>
            {(window.BUBA_TAGS || []).map(t=>(
              <button key={t} onClick={()=>setFilter(t)} className="pill" style={{
                background: filter===t?'#311B57':'rgba(179,157,219,0.12)',
                color: filter===t?'#fff':'#7E57C2', cursor:'pointer', border:'none'
              }}>{t}</button>
            ))}
          </div>
        </div>
      </section>
      <section style={{padding:'40px 32px 100px'}}>
        <div style={{maxWidth:1280, margin:'0 auto'}}>
          <div style={{fontSize:14, color:'#7B6B8A', marginBottom:20}}>총 {filtered.length}편 · 주인공 이름: <b>{charName}</b></div>
          <div style={{display:'grid', gridTemplateColumns:'repeat(auto-fill, minmax(240px, 1fr))', gap:24}}>
            {filtered.map((s)=>{
              const locked = !isUnlocked && !freeIds.has(s.id);
              return (
                <div key={s.id} className="card-hover" style={{cursor:'pointer', position:'relative', opacity: locked ? 0.85 : 1}}
                  onClick={()=>handleCardClick(s)}>
                  <BookCover story={s} w={280}/>
                  {locked && (
                    <div style={{position:'absolute', top:8, right:8, background:'rgba(49,27,87,0.8)', color:'#fff', borderRadius:8, padding:'4px 10px', fontSize:11, fontWeight:700, display:'flex', alignItems:'center', gap:4}}>
                      🔒 잠금
                    </div>
                  )}
                  <div style={{padding:'14px 6px'}}>
                    <div style={{display:'flex', gap:6, marginBottom:8}}>
                      <span className="pill" style={{fontSize:10, padding:'3px 10px', background:`${s.color}22`, color:s.color}}>{s.tag}</span>
                      <span className="pill" style={{fontSize:10, padding:'3px 10px'}}>{s.age}</span>
                    </div>
                    <div style={{fontFamily:'var(--font-display)', fontSize:17, color:'#311B57', marginBottom:6, lineHeight:1.3}}>{s.title}</div>
                    <div style={{fontSize:13, color:'#7B6B8A', lineHeight:1.5}}>{s.description}</div>
                  </div>
                </div>
              );
            })}
          </div>
        </div>
      </section>

      {/* Paywall Modal */}
      {showPaywall && (
        <div onClick={()=>setShowPaywall(false)} style={{position:'fixed', inset:0, background:'rgba(0,0,0,0.5)', display:'flex', alignItems:'center', justifyContent:'center', zIndex:1000, padding:20}}>
          <div onClick={e=>e.stopPropagation()} style={{background:'#fff', borderRadius:20, maxWidth:440, width:'100%', padding:'36px 32px', textAlign:'center', boxShadow:'0 20px 60px rgba(49,27,87,0.25)'}}>
            <div style={{fontSize:40, marginBottom:12}}>📚</div>
            <h2 style={{fontSize:22, fontWeight:800, color:'#311B57', marginBottom:8}}>22편 전체 스토리 열람</h2>
            <div style={{marginBottom:20}}>
              <span style={{fontSize:16, color:'#7B6B8A', textDecoration:'line-through'}}>₩{(config.price_catalog || 19800).toLocaleString()}</span>
              <span style={{fontSize:28, fontWeight:800, color:'#7E57C2', marginLeft:12}}>₩{(config.price_catalog_sale || 9900).toLocaleString()}</span>
              <span style={{background:'#FF5252', color:'#fff', padding:'2px 8px', borderRadius:6, fontSize:12, fontWeight:700, marginLeft:8}}>50%</span>
            </div>
            <ul style={{textAlign:'left', margin:'0 auto 24px', maxWidth:280, listStyle:'none', fontSize:14, color:'#37274A'}}>
              <li style={{marginBottom:8}}>✓ 22편 모든 스토리 미리보기</li>
              <li style={{marginBottom:8}}>✓ 남부키 12편 + 여바바 10편</li>
              <li style={{marginBottom:8}}>✓ 1회 결제, 영구 열람</li>
            </ul>
            <button onClick={()=>{
              if (!token) { onNavigate('login'); return; }
              // TODO: 토스 결제 연동
              fetch('/api/payments/catalog-unlock', { method:'POST', headers:{'Authorization':`Bearer ${token}`, 'Content-Type':'application/json'} })
                .then(r=>r.json()).then(data=>{
                  if (data.already_unlocked) { setShowPaywall(false); window.location.reload(); return; }
                  alert('토스 결제창이 열립니다 (테스트 키 연동 후 활성화)');
                }).catch(()=>alert('결제 준비 실패'));
            }} style={{width:'100%', padding:'14px', borderRadius:12, background:'linear-gradient(135deg, #7E57C2, #B39DDB)', color:'#fff', border:'none', fontSize:16, fontWeight:700, cursor:'pointer', marginBottom:12}}>
              결제하고 전체 보기
            </button>
            <button onClick={()=>setShowPaywall(false)} style={{background:'none', border:'none', color:'#7B6B8A', cursor:'pointer', fontSize:14}}>
              무료 체험 계속하기
            </button>
          </div>
        </div>
      )}

      <SiteFooter variant="light"/>
    </div>
  );
};

// ============================================================
// 2. STORY DETAIL — 스토리 상세
// ============================================================
window.StoryDetailPage = function StoryDetailPage({ onNavigate, user, token, onLogout, context }) {
  const storyId = context?.storyId;
  const all = [...(window.BUBA_STORIES?.boy || []), ...(window.BUBA_STORIES?.girl || [])];
  const story = all.find(s => s.id === storyId) || all[0];
  const isBoy = window.BUBA_STORIES?.boy?.some(s => s.id === story.id);
  const charName = isBoy ? '부키' : '바바';
  const gender = isBoy ? '남자아이' : '여자아이';

  return (
    <div style={{minHeight:'100vh', background:'#FBF8FF', color:'#37274A'}}>
      <AuthNav onNavigate={onNavigate} user={user} token={token} onLogout={onLogout} active="stories"/>
      <section style={{padding:'40px 32px', background:'linear-gradient(180deg, #311B57, #4A2F75)', color:'#fff'}}>
        <div style={{maxWidth:1280, margin:'0 auto', display:'grid', gridTemplateColumns:'auto 1fr', gap:48, alignItems:'center'}} className="responsive-grid">
          <div style={{borderRadius:12, overflow:'hidden', width:'min(520px, 100%)', aspectRatio:'2/1', boxShadow:'0 24px 64px rgba(0,0,0,0.4)', position:'relative', flexShrink:0, background:'#FBF8FF'}}>
            {story.cover ? (
              <img src={story.cover} alt={`${story.title} 표지`} style={{width:'100%', height:'100%', objectFit:'cover'}}/>
            ) : (
              <div style={{width:'100%', height:'100%', background:`linear-gradient(145deg, ${story.color}, ${story.color}cc)`, display:'flex', alignItems:'center', justifyContent:'center', fontSize:72}}>{story.emoji}</div>
            )}
            <div aria-hidden="true" style={{position:'absolute', top:0, bottom:0, left:'50%', width:2, background:'rgba(0,0,0,0.2)', transform:'translateX(-1px)'}}/>
          </div>
          <div>
            <div style={{fontSize:13, opacity:0.7, letterSpacing:2, marginBottom:10}}>{gender} · {story.tag} · {story.age}</div>
            <h1 style={{fontSize:'clamp(32px, 5vw, 52px)', marginBottom:16, lineHeight:1.15}}>{story.title}</h1>
            <p style={{fontSize:17, opacity:0.88, lineHeight:1.8, marginBottom:24, maxWidth:580}}>{story.description}</p>
            <div style={{display:'flex', gap:24, marginBottom:28, alignItems:'center', flexWrap:'wrap'}}>
              <div style={{display:'flex', alignItems:'center', gap:8}}>
                {[1,2,3,4,5].map(i=><Ico.Star key={i} size={18}/>)}
                <span style={{fontWeight:700, marginLeft:4}}>4.9</span>
              </div>
              <div style={{fontSize:14, opacity:0.8}}>📖 12페이지 · 평균 8분 읽기</div>
            </div>
            <div style={{display:'flex', gap:12, flexWrap:'wrap'}}>
              <button onClick={()=>onNavigate(token ? 'upload' : 'register', {storyId: story.id})}
                className="btn btn-gold" style={{padding:'14px 28px'}}>
                <Ico.Wand size={18}/> 이 이야기로 만들기
              </button>
              <button className="btn" style={{background:'rgba(255,255,255,0.12)', color:'#fff', border:'1.5px solid rgba(255,255,255,0.25)', padding:'14px 24px'}}>
                <Ico.Book size={16}/> 1페이지 무료 미리보기
              </button>
            </div>
            <div style={{marginTop:24, padding:'14px 18px', background:'rgba(255,209,102,0.15)', borderRadius:12, fontSize:14, border:'1px solid rgba(255,209,102,0.3)', display:'inline-block'}}>
              💰 전자책 <b>₩29,800</b> · 주인공 이름은 <b>{charName}</b> 대신 우리 아이 이름으로
            </div>
          </div>
        </div>
      </section>
      {story.pages && story.pages.length > 0 && (
        <section style={{padding:'64px 32px', background:'#FBF8FF'}}>
          <div style={{maxWidth:1200, margin:'0 auto'}}>
            <div className="eyebrow" style={{marginBottom:14}}>— 이야기의 장면들</div>
            <h2 style={{fontSize:28, color:'#311B57', marginBottom:32}}>12페이지 중 6페이지 미리보기</h2>
            <div style={{display:'grid', gridTemplateColumns:'repeat(auto-fill, minmax(280px, 1fr))', gap:20}}>
              {story.pages.slice(0,6).map((img, i) => (
                <div key={i} style={{borderRadius:14, overflow:'hidden', boxShadow:'0 8px 24px rgba(55,39,74,0.1)', background:'#fff'}}>
                  <div style={{position:'relative', aspectRatio:'2/1'}}>
                    <img src={img} alt={`${story.title} ${i+1}페이지`} style={{width:'100%', height:'100%', objectFit:'cover'}}/>
                    <div aria-hidden="true" style={{position:'absolute', top:0, bottom:0, left:'50%', width:2, background:'rgba(0,0,0,0.1)', transform:'translateX(-1px)'}}/>
                    <div style={{position:'absolute', top:10, left:10}} className="pill">p. {i+1}</div>
                  </div>
                </div>
              ))}
            </div>
          </div>
        </section>
      )}
      <SiteFooter variant="light"/>
    </div>
  );
};

// ============================================================
// 3. UPLOAD — 업로드 플로우 (4단계)
// ============================================================
window.UploadPage = function UploadPage({ onNavigate, user, token, onLogout }) {
  const [step, setStep] = React.useState(1);
  const [childInfo, setChildInfo] = React.useState({name:'', age:'', gender:''});
  const [photo, setPhoto] = React.useState(null);
  const fileInputRef = React.useRef(null);
  const steps = ['정보 입력', '사진 업로드', '스토리 선택', '결제'];

  return (
    <div style={{minHeight:'100vh', background:'#FBF8FF', color:'#37274A'}}>
      <AuthNav onNavigate={onNavigate} user={user} token={token} onLogout={onLogout}/>
      <section style={{padding:'40px 32px 80px', position:'relative', overflow:'hidden'}}>
        <WatercolorBG opacity={0.4}/>
        <div style={{maxWidth:960, margin:'0 auto', position:'relative'}}>
          {/* Progress */}
          <div style={{display:'flex', alignItems:'center', justifyContent:'center', marginBottom:40, flexWrap:'wrap', gap:8}}>
            {steps.map((s,i)=>(
              <React.Fragment key={i}>
                <div style={{display:'flex', alignItems:'center', gap:10}}>
                  <div style={{width:36, height:36, borderRadius:'50%',
                    background: i+1<=step?'linear-gradient(135deg, #B39DDB, #7E57C2)':'#EDE7F6',
                    color: i+1<=step?'#fff':'#9575CD', display:'flex', alignItems:'center', justifyContent:'center',
                    fontWeight:700, fontSize:14
                  }}>{i+1}</div>
                  <span style={{fontSize:14, fontWeight: i+1===step?700:500, color: i+1<=step?'#311B57':'#9575CD'}}>{s}</span>
                </div>
                {i<3 && <div style={{width:40, height:2, background:'#D1C4E9'}}/>}
              </React.Fragment>
            ))}
          </div>

          <div className="card" style={{padding:'32px 40px'}}>
            {step === 1 && (
              <>
                <h1 style={{fontSize:28, color:'#311B57', marginBottom:10}}>주인공의 정보를 알려주세요</h1>
                <p style={{fontSize:14, color:'#7B6B8A', marginBottom:24}}>이름이 이야기 속에 등장하고, 성별에 따라 주인공 스타일(부키/바바)이 정해져요.</p>
                <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:12, marginBottom:12}}>
                  <input className="input" placeholder="아이 이름 (예: 지우)" value={childInfo.name} onChange={e=>setChildInfo({...childInfo, name:e.target.value})}/>
                  <input className="input" placeholder="나이 (만 나이)" value={childInfo.age} onChange={e=>setChildInfo({...childInfo, age:e.target.value})}/>
                </div>
                <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:12}}>
                  {[{k:'boy', l:'남자아이 (부키 스타일)', c:'#B39DDB'},{k:'girl', l:'여자아이 (바바 스타일)', c:'#F48FB1'}].map(g=>(
                    <button key={g.k} onClick={()=>setChildInfo({...childInfo, gender:g.k})}
                      style={{padding:'20px', borderRadius:12, cursor:'pointer', fontSize:15, fontWeight:600,
                        background: childInfo.gender===g.k ? g.c : '#fff',
                        color: childInfo.gender===g.k ? '#fff' : '#37274A',
                        border: childInfo.gender===g.k ? 'none' : '1.5px solid #D1C4E9'}}>
                      {g.l}
                    </button>
                  ))}
                </div>
              </>
            )}
            {step === 2 && (
              <>
                <h1 style={{fontSize:28, color:'#311B57', marginBottom:10}}>아이의 얼굴 사진을 올려주세요</h1>
                <p style={{fontSize:14, color:'#7B6B8A', marginBottom:24}}>정면이 잘 보이는 환한 사진이면 가장 좋아요. 업로드 후 48시간 뒤 자동 삭제됩니다.</p>
                <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:20}} className="responsive-grid">
                  <div onClick={()=>fileInputRef.current?.click()}
                    style={{border:'2px dashed #B39DDB', borderRadius:16, padding:'40px 20px', textAlign:'center', cursor:'pointer', background:'rgba(179,157,219,0.06)', minHeight:300, display:'flex', flexDirection:'column', alignItems:'center', justifyContent:'center'}}>
                    {photo ? (
                      <img src={photo} alt="" style={{maxWidth:'100%', maxHeight:240, borderRadius:8}}/>
                    ) : (
                      <>
                        <div style={{width:72, height:72, borderRadius:'50%', background:'#fff', display:'flex', alignItems:'center', justifyContent:'center', marginBottom:18, boxShadow:'0 4px 16px rgba(179,157,219,0.25)'}}>
                          <Ico.Upload size={28}/>
                        </div>
                        <div style={{fontSize:16, fontWeight:700, color:'#311B57', marginBottom:6}}>여기에 사진을 드래그하거나</div>
                        <div className="btn btn-primary" style={{padding:'10px 20px', marginTop:8, fontSize:14}}>파일 선택</div>
                        <div style={{fontSize:12, color:'#9575CD', marginTop:12}}>JPG, PNG · 최대 10MB</div>
                      </>
                    )}
                    <input ref={fileInputRef} type="file" accept="image/*" style={{display:'none'}}
                      onChange={e=>{ const f=e.target.files?.[0]; if(f){ const r=new FileReader(); r.onload=ev=>setPhoto(ev.target.result); r.readAsDataURL(f);}}}/>
                  </div>
                  <div>
                    <div style={{fontWeight:700, color:'#311B57', marginBottom:14, fontSize:15}}>✓ 좋은 사진 예시</div>
                    <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:10, marginBottom:20}}>
                      {[
                        {ok:true, t:'정면, 환한 조명'},
                        {ok:true, t:'얼굴 잘 보임'},
                        {ok:false, t:'너무 어두움'},
                        {ok:false, t:'옆얼굴/가려짐'},
                      ].map((ex,i)=>(
                        <div key={i} style={{aspectRatio:'1', borderRadius:10, background: ex.ok?'#E8F5E9':'#FFEBEE', padding:10, display:'flex', flexDirection:'column', justifyContent:'space-between', border:`1px solid ${ex.ok?'#81C784':'#EF9A9A'}`}}>
                          <div style={{fontSize:22}}>{ex.ok?'✅':'❌'}</div>
                          <div style={{fontSize:12, color: ex.ok?'#2E7D32':'#C62828'}}>{ex.t}</div>
                        </div>
                      ))}
                    </div>
                    <div style={{padding:'12px 14px', background:'#EDE7F6', borderRadius:12, fontSize:13, color:'#37274A', lineHeight:1.7}}>
                      🔒 <b>개인정보 안전</b><br/>업로드한 원본 사진은 제작 완료 후 48시간 내 자동 삭제되며, 외부에 공유되지 않습니다.
                    </div>
                  </div>
                </div>
              </>
            )}
            {step === 3 && (
              <>
                <h1 style={{fontSize:28, color:'#311B57', marginBottom:10}}>어떤 이야기를 만들까요?</h1>
                <p style={{fontSize:14, color:'#7B6B8A', marginBottom:24}}>
                  {childInfo.gender === 'girl' ? '바바' : '부키'} 주인공 스토리 중에서 골라주세요.
                </p>
                <div style={{display:'grid', gridTemplateColumns:'repeat(auto-fill, minmax(200px, 1fr))', gap:16, maxHeight:420, overflowY:'auto', padding:4}}>
                  {(window.BUBA_STORIES?.[childInfo.gender || 'boy'] || []).map(s=>(
                    <div key={s.id} style={{cursor:'pointer', borderRadius:12, overflow:'hidden', border:'2px solid transparent', transition:'all 0.2s'}}
                      onMouseEnter={e=>e.currentTarget.style.borderColor='#B39DDB'}
                      onMouseLeave={e=>e.currentTarget.style.borderColor='transparent'}>
                      <BookCover story={s} w={200}/>
                      <div style={{padding:'10px 8px'}}>
                        <div style={{fontFamily:'var(--font-display)', fontSize:13, color:'#311B57'}}>{s.title}</div>
                      </div>
                    </div>
                  ))}
                </div>
              </>
            )}

            <div style={{display:'flex', justifyContent:'space-between', marginTop:32}}>
              <button onClick={()=>step>1 ? setStep(step-1) : onNavigate('landing')} className="btn btn-ghost">
                <Ico.ArrowL/> {step>1 ? '이전' : '홈으로'}
              </button>
              <button onClick={()=>step<3 ? setStep(step+1) : onNavigate('checkout')} className="btn btn-primary">
                {step<3 ? `다음: ${steps[step]}` : '결제로 진행'} <Ico.ArrowR/>
              </button>
            </div>
          </div>
        </div>
      </section>
      <SiteFooter variant="light"/>
    </div>
  );
};

// ============================================================
// 4. READER — 뷰어
// ============================================================
window.ReaderPage = function ReaderPage({ onNavigate, user, token, onLogout, context }) {
  const all = [...(window.BUBA_STORIES?.boy || []), ...(window.BUBA_STORIES?.girl || [])];
  const story = context?.storyId ? all.find(s=>s.id===context.storyId) || all[0] : all[0];
  const [page, setPage] = React.useState(0);
  const pages = story.pages || [];
  const total = pages.length || 12;

  return (
    <div style={{minHeight:'100vh', background:'#1E0F38', color:'#fff', position:'relative', overflow:'hidden'}}>
      <div style={{display:'flex', justifyContent:'space-between', alignItems:'center', padding:'16px 24px', background:'rgba(0,0,0,0.3)', backdropFilter:'blur(12px)', position:'relative', zIndex:2}}>
        <div style={{display:'flex', alignItems:'center', gap:16}}>
          <button onClick={()=>onNavigate('mypage')} className="btn-ghost" style={{color:'#fff'}}><Ico.ArrowL size={16}/> 마이페이지</button>
          <div style={{width:1, height:20, background:'rgba(255,255,255,0.2)'}}/>
          <div>
            <div style={{fontFamily:'var(--font-display)', fontSize:17}}>{story.title}</div>
            <div style={{fontSize:12, opacity:0.6}}>{page+1} / {total}</div>
          </div>
        </div>
        <div style={{display:'flex', gap:8}}>
          <button className="btn" style={{background:'rgba(255,255,255,0.1)', color:'#fff', padding:'8px 14px', fontSize:13}}>🔊 읽어주기</button>
          <button className="btn" style={{background:'rgba(255,255,255,0.1)', color:'#fff', padding:'8px 14px', fontSize:13}}>💬 공유</button>
        </div>
      </div>

      <div style={{display:'flex', alignItems:'center', justifyContent:'center', minHeight:'calc(100vh - 140px)', padding:'20px 40px', position:'relative'}}>
        <button onClick={()=>setPage(Math.max(0, page-1))} disabled={page===0}
          style={{position:'absolute', left:16, width:44, height:44, borderRadius:'50%', background:'rgba(255,255,255,0.15)', border:'none', color:'#fff', cursor:page===0?'not-allowed':'pointer', opacity:page===0?0.4:1, display:'flex', alignItems:'center', justifyContent:'center'}}>
          <Ico.ArrowL/>
        </button>
        <div style={{aspectRatio:'2/1', width:'100%', maxWidth:1120, borderRadius:14, overflow:'hidden', boxShadow:'0 32px 80px rgba(0,0,0,0.5)', background:'#FBF8FF', position:'relative'}}>
          {pages[page] ? (
            <img src={pages[page]} alt={`${story.title} ${page+1}페이지`} style={{width:'100%', height:'100%', objectFit:'cover'}}/>
          ) : (
            <div style={{width:'100%', height:'100%', background:`linear-gradient(135deg, ${story.color}44, ${story.color}22)`, display:'flex', alignItems:'center', justifyContent:'center', color:'#37274A', fontSize:20}}>
              {story.title} · 페이지 {page+1}
            </div>
          )}
          <div aria-hidden="true" style={{position:'absolute', top:0, bottom:0, left:'50%', width:2, background:'rgba(0,0,0,0.12)', transform:'translateX(-1px)'}}/>
        </div>
        <button onClick={()=>setPage(Math.min(total-1, page+1))} disabled={page===total-1}
          style={{position:'absolute', right:16, width:44, height:44, borderRadius:'50%', background:'rgba(255,255,255,0.15)', border:'none', color:'#fff', cursor:page===total-1?'not-allowed':'pointer', opacity:page===total-1?0.4:1, display:'flex', alignItems:'center', justifyContent:'center'}}>
          <Ico.ArrowR/>
        </button>
      </div>

      <div style={{display:'flex', alignItems:'center', justifyContent:'center', gap:6, padding:'16px'}}>
        {Array.from({length:total}).map((_,i)=>(
          <div key={i} onClick={()=>setPage(i)} style={{width: i===page?24:8, height:8, borderRadius:8, cursor:'pointer', background: i===page?'#FFD166': (i<page?'rgba(255,255,255,0.4)':'rgba(255,255,255,0.15)')}}/>
        ))}
      </div>
    </div>
  );
};

// ============================================================
// 5. MY BOOKS — 마이페이지
// ============================================================
window.MyBooksPage = function MyBooksPage({ onNavigate, user, token, onLogout }) {
  const sampleBooks = [
    {story: window.BUBA_STORIES?.boy?.[0], name: user?.name || '우리 아이', date:'2026.04.18', status:'완성'},
    {story: window.BUBA_STORIES?.boy?.[4], name: user?.name || '우리 아이', date:'2026.03.02', status:'완성'},
  ].filter(b => b.story);

  return (
    <div style={{minHeight:'100vh', background:'#FBF8FF', color:'#37274A'}}>
      <AuthNav onNavigate={onNavigate} user={user} token={token} onLogout={onLogout} active="mypage"/>
      <section style={{padding:'40px 32px', display:'grid', gridTemplateColumns:'260px 1fr', gap:32, maxWidth:1280, margin:'0 auto'}} className="responsive-grid">
        <aside>
          <div className="card" style={{padding:20, marginBottom:16}}>
            <div style={{width:64, height:64, borderRadius:'50%', background:'linear-gradient(135deg, #F48FB1, #B39DDB)', margin:'0 auto 12px'}}/>
            <div style={{textAlign:'center', fontFamily:'var(--font-display)', fontSize:17, color:'#311B57'}}>{user?.name || '회원'}님</div>
            <div style={{textAlign:'center', fontSize:12, color:'#9575CD', marginTop:4}}>{user?.email || ''}</div>
          </div>
          <nav style={{display:'flex', flexDirection:'column', gap:4}}>
            {[
              {k:'books', l:'내 동화책', icon:<Ico.Book size={16}/>, count:sampleBooks.length, active:true},
              {k:'orders', l:'주문 내역', icon:<Ico.Bag size={16}/>},
              {k:'notifications', l:'알림', icon:<Ico.Bell size={16}/>, count:1},
              {k:'profile', l:'내 정보', icon:<Ico.User size={16}/>},
            ].map(m=>(
              <div key={m.k} style={{display:'flex', alignItems:'center', gap:12, padding:'12px 16px', borderRadius:10, cursor:'pointer',
                background: m.active?'rgba(179,157,219,0.15)':'transparent', color: m.active?'#7E57C2':'#37274A',
                fontWeight: m.active?700:500, fontSize:14}}>
                {m.icon}<span>{m.l}</span>
                {m.count != null && <span className="pill" style={{marginLeft:'auto', background:m.active?'#7E57C2':'#EDE7F6', color:m.active?'#fff':'#7E57C2', fontSize:10, padding:'2px 8px'}}>{m.count}</span>}
              </div>
            ))}
          </nav>
        </aside>
        <main>
          <div style={{display:'flex', justifyContent:'space-between', alignItems:'end', marginBottom:28, flexWrap:'wrap', gap:16}}>
            <div>
              <h1 style={{fontSize:'clamp(24px, 4vw, 32px)', color:'#311B57', marginBottom:6}}>내 동화책</h1>
              <div style={{fontSize:14, color:'#7B6B8A'}}>{sampleBooks.length}권 소장 · 언제든 다시 읽어볼 수 있어요</div>
            </div>
            <button onClick={()=>onNavigate('upload')} className="btn btn-primary" style={{padding:'11px 18px'}}>
              <Ico.Wand size={16}/> 새 동화 만들기
            </button>
          </div>

          {/* 진행중 */}
          <div className="card" style={{padding:20, marginBottom:24, borderLeft:'4px solid #FFD166', background:'linear-gradient(135deg, #fff, #FBF8FF)'}}>
            <div style={{display:'flex', gap:16, alignItems:'center'}}>
              <div style={{width:64, height:80, borderRadius:10, overflow:'hidden', background:'#EDE7F6', flexShrink:0}}>
                <div className="shimmer" style={{width:'100%', height:'100%'}}/>
              </div>
              <div style={{flex:1, minWidth:0}}>
                <div className="pill pill-gold" style={{marginBottom:8}}>제작 중</div>
                <div style={{fontFamily:'var(--font-display)', fontSize:16, color:'#311B57', marginBottom:6}}>꿈속 탐험대 바바 · 서연</div>
                <div style={{height:6, background:'#EDE7F6', borderRadius:3, overflow:'hidden', marginBottom:6}}>
                  <div style={{width:'65%', height:'100%', background:'linear-gradient(90deg, #B39DDB, #F48FB1)'}}/>
                </div>
                <div style={{fontSize:12, color:'#7B6B8A'}}>디자이너 검수 중 · 예상 완성 <b style={{color:'#7E57C2'}}>4월 26일</b></div>
              </div>
            </div>
          </div>

          <div style={{display:'grid', gridTemplateColumns:'repeat(auto-fill, minmax(260px, 1fr))', gap:20}}>
            {sampleBooks.map((b,i)=>(
              <div key={i} className="card-hover" style={{cursor:'pointer'}} onClick={()=>onNavigate('reader', {storyId: b.story.id})}>
                <div style={{position:'relative'}}>
                  <BookCover story={b.story} w={280}/>
                  <div style={{position:'absolute', top:12, left:12}} className="pill pill-gold">{b.status}</div>
                </div>
                <div style={{padding:'12px 6px'}}>
                  <div style={{fontFamily:'var(--font-display)', fontSize:15, color:'#311B57', marginBottom:4}}>{b.story.title}</div>
                  <div style={{fontSize:12, color:'#9575CD'}}>주인공 · <b>{b.name}</b> · {b.date}</div>
                </div>
              </div>
            ))}
            <div onClick={()=>onNavigate('upload')}
              style={{borderRadius:20, border:'2px dashed #D1C4E9', minHeight:220, display:'flex', flexDirection:'column', alignItems:'center', justifyContent:'center', color:'#9575CD', cursor:'pointer'}}>
              <div style={{fontSize:40, marginBottom:10}}>+</div>
              <div style={{fontSize:14, fontWeight:600}}>새 동화책 만들기</div>
            </div>
          </div>
        </main>
      </section>
      <SiteFooter variant="light"/>
    </div>
  );
};

// ============================================================
// 6. CHECKOUT — 결제
// ============================================================
window.CheckoutPage = function CheckoutPage({ onNavigate, user, token, onLogout, context }) {
  const all = [...(window.BUBA_STORIES?.boy || []), ...(window.BUBA_STORIES?.girl || [])];
  const story = context?.storyId ? all.find(s=>s.id===context.storyId) || all[0] : all[0];
  const [method, setMethod] = React.useState('카카오페이');

  return (
    <div style={{minHeight:'100vh', background:'#FBF8FF', color:'#37274A'}}>
      <AuthNav onNavigate={onNavigate} user={user} token={token} onLogout={onLogout}/>
      <section style={{padding:'40px 32px', display:'grid', gridTemplateColumns:'1fr 400px', gap:32, maxWidth:1200, margin:'0 auto'}} className="responsive-grid">
        <div>
          <h1 style={{fontSize:28, color:'#311B57', marginBottom:8}}>결제하기</h1>
          <div style={{fontSize:14, color:'#7B6B8A', marginBottom:24}}>마지막 단계예요. 결제 후 3–5일 이내 완성 알림을 보내드려요.</div>
          <div className="card" style={{padding:24, marginBottom:16}}>
            <div style={{fontWeight:700, color:'#311B57', marginBottom:14, fontSize:15}}>주문자 정보</div>
            <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:10, marginBottom:10}}>
              <input className="input" placeholder="이름" defaultValue={user?.name || ''}/>
              <input className="input" placeholder="전화번호"/>
            </div>
            <input className="input" placeholder="카카오톡 알림 받을 번호" style={{marginBottom:10}}/>
            <div style={{display:'flex', gap:8, padding:'10px 12px', background:'#FFF8E1', borderRadius:10, fontSize:13, color:'#8B6914'}}>
              <Ico.Bell size={16}/> <div>완성되면 이 번호로 카카오톡 알림을 보내드려요</div>
            </div>
          </div>
          <div className="card" style={{padding:24, marginBottom:16}}>
            <div style={{fontWeight:700, color:'#311B57', marginBottom:14, fontSize:15}}>결제 수단</div>
            <div style={{display:'grid', gridTemplateColumns:'repeat(auto-fill, minmax(100px, 1fr))', gap:8}}>
              {['카드', '카카오페이', '네이버페이', '토스'].map((m)=>(
                <div key={m} onClick={()=>setMethod(m)}
                  style={{padding:'12px', border: method===m?'2px solid #7E57C2':'1.5px solid #D1C4E9', borderRadius:12, textAlign:'center', cursor:'pointer', fontWeight:600, fontSize:13, background: method===m?'rgba(179,157,219,0.08)':'#fff'}}>
                  {m}
                </div>
              ))}
            </div>
          </div>
          <div className="card" style={{padding:20}}>
            <label style={{display:'flex', gap:10, alignItems:'start', fontSize:13, cursor:'pointer'}}>
              <input type="checkbox" defaultChecked style={{marginTop:3}}/>
              <span style={{color:'#7B6B8A'}}>[필수] 개인정보 수집 및 이용, 결제 약관에 동의합니다.</span>
            </label>
          </div>
        </div>
        <aside>
          <div className="card" style={{padding:20, position:'sticky', top:90}}>
            <div style={{display:'flex', gap:12, marginBottom:16, paddingBottom:16, borderBottom:'1px dashed #D1C4E9'}}>
              <div style={{width:70, height:90, borderRadius:8, overflow:'hidden', flexShrink:0, background: story.color || '#B39DDB'}}>
                {story.cover && <img src={story.cover} alt="" style={{width:'100%', height:'100%', objectFit:'cover'}}/>}
              </div>
              <div style={{minWidth:0}}>
                <div className="pill" style={{fontSize:10, padding:'2px 8px', marginBottom:6}}>{story.tag}</div>
                <div style={{fontFamily:'var(--font-display)', fontSize:14, color:'#311B57', marginBottom:4, lineHeight:1.3}}>{story.title}</div>
                <div style={{fontSize:11, color:'#9575CD'}}>12페이지 전자책</div>
              </div>
            </div>
            <div style={{display:'flex', flexDirection:'column', gap:8, marginBottom:14, fontSize:13, color:'#7B6B8A'}}>
              <div style={{display:'flex', justifyContent:'space-between'}}><span>전자책 1권</span><span>₩29,800</span></div>
              <div style={{display:'flex', justifyContent:'space-between', color:'#D32F2F'}}><span>오픈기념 (15%)</span><span>-₩4,470</span></div>
            </div>
            <div style={{display:'flex', justifyContent:'space-between', padding:'14px 0', borderTop:'2px solid #311B57', marginBottom:16}}>
              <span style={{fontWeight:700, fontSize:15, color:'#311B57'}}>최종 결제</span>
              <span style={{fontFamily:'var(--font-display)', fontSize:20, color:'#7E57C2'}}>₩25,330</span>
            </div>
            <button className="btn btn-primary" style={{width:'100%', padding:'14px', fontSize:15}}>₩25,330 결제하기</button>
            <div style={{fontSize:11, color:'#B0A3BF', textAlign:'center', marginTop:10}}>🔒 토스페이먼츠 안전 결제</div>
          </div>
        </aside>
      </section>
      <SiteFooter variant="light"/>
    </div>
  );
};
