import { useState } from "react";
const yen=n=>"¥"+n.toLocaleString();
function Ic({d,size=18,color="#64748b"}){return <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke={color} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d={d}/></svg>;}
const P={grid:"M3 3h7v7H3zM14 3h7v7h-7zM14 14h7v7h-7zM3 14h7v7H3z",scan:"M3 3h7v7H3zM14 3h7v7h-7zM3 14h7v7H3zM17 17h3v3M14 14h3v3M20 14v3",users:"M16 21v-2a4 4 0 00-4-4H6a4 4 0 00-4 4v2M9 3a4 4 0 100 8 4 4 0 000-8z",cal:"M3 6a2 2 0 012-2h14a2 2 0 012 2v14a2 2 0 01-2 2H5a2 2 0 01-2-2zM16 2v4M8 2v4M3 10h18",wallet:"M21 12V7H5a2 2 0 010-4h14v4M3 5v14a2 2 0 002 2h16v-5M18 12a2 2 0 000 4h4v-4z",bar:"M18 20V10M12 20V4M6 20v-6",gear:"M12 15a3 3 0 100-6 3 3 0 000 6z",check:"M20 6L9 17l-5-5",back:"M19 12H5M12 19l-7-7 7-7",chev:"M9 18l6-6-6-6",wine:"M8 22h8M12 15v7M7.5 10h9l1 5c0 2.5-2 4.5-5.5 4.5S6.5 17.5 6.5 15zM12 2v3M9.5 5h5",card:"M1 4h22v16H1zM1 10h22",home:"M3 10.5L12 3l9 7.5V21a1 1 0 01-1 1h-5v-6H9v6H4a1 1 0 01-1-1z",star:"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14l-5-4.87 6.91-1.01z",flag:"M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1zM4 22v-7",user:"M20 21v-2a4 4 0 00-4-4H8a4 4 0 00-4 4v2M12 3a4 4 0 100 8 4 4 0 000-8z",plus:"M12 5v14M5 12h14",clock:"M12 2a10 10 0 100 20 10 10 0 000-20zM12 6v6l4 2",store:"M3 9l9-7 9 7v11a2 2 0 01-2 2H5a2 2 0 01-2-2z",dollar:"M12 1v22M17 5H9.5a3.5 3.5 0 000 7h5a3.5 3.5 0 010 7H6"};
const D={
mrr:2750000, memberCount:200, newMembers:12, churnRate:2.4, todayVisits:18,
stores:[{name:"宗像本店",members:100,price:16500},{name:"香椎店",members:100,price:11000}],
members:[
{id:1,name:"田中 太郎",store:"宗像本店",status:"active",since:"2024/06",visits:42,lastVisit:"5/11",plan:16500,nextBill:"5/15",bottles:2},
{id:2,name:"佐藤 健一",store:"宗像本店",status:"active",since:"2024/09",visits:28,lastVisit:"5/10",plan:16500,nextBill:"5/20",bottles:1},
{id:3,name:"鈴木 一郎",store:"香椎店",status:"active",since:"2025/01",visits:15,lastVisit:"5/9",plan:11000,nextBill:"5/12",bottles:0},
{id:4,name:"高橋 誠",store:"宗像本店",status:"active",since:"2024/03",visits:68,lastVisit:"5/11",plan:16500,nextBill:"5/18",bottles:3},
{id:5,name:"渡辺 洋介",store:"香椎店",status:"overdue",since:"2025/02",visits:8,lastVisit:"4/28",plan:11000,nextBill:"5/5",bottles:0},
{id:6,name:"山本 隆",store:"宗像本店",status:"cancelled",since:"2024/07",visits:22,lastVisit:"4/15",plan:16500,nextBill:"-",bottles:0},
],
todayLog:[
{name:"田中 太郎",in:"20:15",companion:1,vip:false,staffDrink:0},
{name:"佐藤 健一",in:"20:40",companion:2,vip:false,staffDrink:1},
{name:"高橋 誠",in:"21:05",companion:3,vip:true,staffDrink:2},
{name:"鈴木 一郎",in:"21:30",companion:0,vip:false,staffDrink:0},
],
billing:[{month:"2026/04",sub:2805000,visitor:42000,vip:75000,drink:38000,food:12000,total:2972000}],
expenses:{rent:450000,utilities:62000,personnel:680000,advertising:45000,purchase:180000,misc:28000},
};
function Card({title,children,style:s}){return <div style={{background:"#fff",border:"1px solid #e2e8f0",borderRadius:8,padding:16,marginBottom:12,...s}}>{title&&<div style={{fontSize:13,fontWeight:600,color:"#334155",marginBottom:12}}>{title}</div>}{children}</div>;}
function Kpi({label,value,sub}){return <div style={{background:"#fff",border:"1px solid #e2e8f0",borderRadius:8,padding:14}}><div style={{fontSize:11,color:"#64748b"}}>{label}</div><div style={{fontSize:20,fontWeight:700,color:"#0f172a",marginTop:2}}>{value}</div>{sub&&<div style={{fontSize:10,color:"#64748b",marginTop:2}}>{sub}</div>}</div>;}
function Bdg({t,v}){const c={default:["#f1f5f9","#475569"],active:["#dcfce7","#166534"],overdue:["#fee2e2","#991b1b"],cancelled:["#f1f5f9","#94a3b8"],blue:["#e0f2fe","#0369a1"]};const[bg,cl]=c[v]||c.default;return <span style={{display:"inline-block",padding:"2px 8px",borderRadius:4,fontSize:10,fontWeight:600,background:bg,color:cl,marginRight:3}}>{t}</span>;}
const td={padding:"9px 10px",fontSize:12,borderBottom:"1px solid #f1f5f9"};
const statusLabel={active:"契約中",overdue:"未払い",cancelled:"退会済"};
export default function App(){
const[page,setPage]=useState("dashboard");
const[mode,setMode]=useState("admin");
const[dt,setDt]=useState(null);
const[sb,setSb]=useState(false);
const go=(p,d)=>{setPage(p);if(d)setDt(d);};
const goM=(p,d)=>{setPage(p);setSb(false);if(d)setDt(d);};
const nav=[
{id:"dashboard",l:"ダッシュボード",p:P.bar},
{id:"reception",l:"入店受付",p:P.scan},
{id:"members",l:"会員管理",p:P.users},
{id:"billing",l:"課金管理",p:P.card},
{id:"charges",l:"追加課金",p:P.dollar},
{id:"bottles",l:"ボトルキープ",p:P.wine},
{id:"staff",l:"スタッフ管理",p:P.user},
{id:"expenses",l:"経費・損益",p:P.wallet},
{id:"settings",l:"設定",p:P.gear},
];
if(mode==="member") return <div style={{maxWidth:430,margin:"0 auto",minHeight:"100vh",background:"#fff8fa",fontFamily:"system-ui,sans-serif",color:"#1e1e2e"}}>
<style>{`
@keyframes glow{0%,100%{box-shadow:0 0 8px #ec489930}50%{box-shadow:0 0 20px #ec489950}}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.6}}
@keyframes slideUp{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:translateY(0)}}
@keyframes shimmer{0%{background-position:-200% 0}100%{background-position:200% 0}}
@keyframes float{0%,100%{transform:translateY(0)}50%{transform:translateY(-4px)}}
.dg-glow{animation:glow 2.5s ease-in-out infinite}
.dg-pulse{animation:pulse 2s ease-in-out infinite}
.dg-slide{animation:slideUp .4s ease-out both}
.dg-float{animation:float 3s ease-in-out infinite}
.dg-shimmer{background:linear-gradient(90deg,#ec4899 0%,#f9a8d4 50%,#ec4899 100%);background-size:200% auto;animation:shimmer 3s linear infinite;-webkit-background-clip:text;-webkit-text-fill-color:transparent}
`}</style>
<div style={{background:"linear-gradient(135deg,#ec4899,#f472b6)",padding:"12px 16px",display:"flex",justifyContent:"space-between",alignItems:"center"}}>
<div style={{display:"flex",alignItems:"center",gap:8}}>
<span style={{fontSize:18}} className="dg-float">⚔️</span>
<span style={{fontWeight:800,fontSize:15,color:"#fff",letterSpacing:1}}>DUNGEON</span>
</div>
<button onClick={()=>{setMode("admin");setPage("dashboard");}} style={{background:"rgba(255,255,255,0.2)",border:"none",color:"#fff",padding:"4px 10px",borderRadius:4,fontSize:10,cursor:"pointer"}}>管理画面へ</button>
</div>
<MemberApp/>
</div>;
return <div style={{minHeight:"100vh",fontFamily:"system-ui,sans-serif",background:"#f8fafc",fontSize:13,color:"#1e293b"}}>
{/* Overlay */}
{sb&&<div onClick={()=>setSb(false)} style={{position:"fixed",inset:0,background:"rgba(0,0,0,0.4)",zIndex:40}}/>}
{/* Sidebar */}
<aside style={{width:240,background:"#1c1917",display:"flex",flexDirection:"column",position:"fixed",top:0,bottom:0,left:0,zIndex:50,transition:"transform .25s",transform:sb?"translateX(0)":"translateX(-100%)"}}>
<div style={{padding:"16px 14px",borderBottom:"1px solid #292524",display:"flex",justifyContent:"space-between",alignItems:"center"}}>
<div>
<div style={{color:"#fff",fontWeight:700,fontSize:14,letterSpacing:0.5}}>アニソンBARダンジョン</div>
<div style={{color:"#78716c",fontSize:10,marginTop:2}}>管理システム</div>
</div>
<button onClick={()=>setSb(false)} style={{background:"none",border:"none",cursor:"pointer",color:"#78716c",fontSize:18,padding:4}}>✕</button>
</div>
<nav style={{flex:1,padding:6,overflowY:"auto"}}>{nav.map(n=><button key={n.id} onClick={()=>goM(n.id)} style={{display:"flex",alignItems:"center",gap:8,width:"100%",padding:"10px 12px",borderRadius:6,border:"none",cursor:"pointer",marginBottom:1,background:page===n.id?"#44403c":"transparent",color:page===n.id?"#fff":"#a8a29e",fontSize:13,fontWeight:500,textAlign:"left"}}><Ic d={n.p} size={16} color={page===n.id?"#fff":"#78716c"}/>{n.l}</button>)}</nav>
<div style={{padding:"10px 12px",borderTop:"1px solid #292524"}}>
<div style={{display:"flex",gap:4,marginBottom:8}}>
{[["admin","管理画面"],["member","冒険者App"]].map(([m,l])=><button key={m} onClick={()=>{setMode(m);setPage(m==="admin"?"dashboard":"");setSb(false);}} style={{flex:1,padding:"6px 0",borderRadius:4,border:"none",cursor:"pointer",fontSize:10,fontWeight:600,background:mode===m?"#44403c":"#292524",color:mode===m?"#fbbf24":"#78716c"}}>{l}</button>)}
</div>
<div style={{color:"#78716c",fontSize:10}}>admin@dungeon.rola-gr.jp</div>
</div>
</aside>
{/* Header */}
<div style={{background:"#1c1917",padding:"10px 16px",display:"flex",alignItems:"center",gap:12,position:"sticky",top:0,zIndex:30}}>
<button onClick={()=>setSb(true)} style={{background:"none",border:"none",cursor:"pointer",padding:4}}>
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="#fff" strokeWidth="2" strokeLinecap="round"><line x1="4" x2="20" y1="6" y2="6"/><line x1="4" x2="20" y1="12" y2="12"/><line x1="4" x2="20" y1="18" y2="18"/></svg>
</button>
<span style={{color:"#fff",fontWeight:700,fontSize:14}}>アニソンBARダンジョン</span>
</div>
{/* Main */}
<main style={{padding:"16px",maxWidth:1060,margin:"0 auto"}}>
{page==="dashboard"&&<Dashboard go={goM}/>}
{page==="reception"&&<Reception/>}
{page==="members"&&<Members go={goM}/>}
{page==="member-detail"&&<MemberDetail m={dt} go={goM}/>}
{page==="billing"&&<Billing/>}
{page==="charges"&&<Charges/>}
{page==="bottles"&&<Bottles/>}
{page==="expenses"&&<Expenses/>}
{page==="staff"&&<Staff/>}
{page==="settings"&&<Settings/>}
</main>
</div>;
}
function Dashboard({go}){
return <div>
<h1 style={{fontSize:18,fontWeight:700,margin:"0 0 4px"}}>ダッシュボード</h1>
<p style={{fontSize:12,color:"#64748b",margin:"0 0 16px"}}>2026年5月12日(火)</p>
<div style={{display:"grid",gridTemplateColumns:"repeat(auto-fill,minmax(140px,1fr))",gap:10,marginBottom:16}}>
<Kpi label="MRR(月次経常収益)" value={yen(D.mrr)}/>
<Kpi label="会員数" value={D.memberCount+"名"} sub={"宗像 "+D.stores[0].members+"名 / 香椎 "+D.stores[1].members+"名"}/>
<Kpi label="今月新規" value={D.newMembers+"名"}/>
<Kpi label="解約率" value={D.churnRate+"%"}/>
<Kpi label="本日来店" value={D.todayVisits+"名"}/>
</div>
<div style={{display:"grid",gridTemplateColumns:"repeat(auto-fit,minmax(280px,1fr))",gap:12}}>
<Card title="本日の入店記録">
{D.todayLog.map((v,i)=><div key={i} style={{display:"flex",justifyContent:"space-between",alignItems:"center",padding:"8px 0",borderBottom:i<3?"1px solid #f1f5f9":"none"}}>
<div><span style={{fontWeight:600,fontSize:13}}>{v.name}</span><span style={{color:"#94a3b8",fontSize:11,marginLeft:6}}>{v.in}</span>
<div style={{display:"flex",gap:4,marginTop:2}}>
<span style={{fontSize:10,color:"#64748b"}}>同伴{v.companion}名</span>
{v.vip&&<Bdg t="VIP" v="blue"/>}
{v.staffDrink>0&&<span style={{fontSize:10,color:"#64748b"}}>スタッフDr.{v.staffDrink}杯</span>}
{v.companion>=3&&<Bdg t="ビジター課金" v="overdue"/>}
</div>
</div>
</div>)}
</Card>
<Card title="店舗別会員数">
{D.stores.map((s,i)=><div key={i} style={{padding:"12px 0",borderBottom:i<1?"1px solid #f1f5f9":"none"}}>
<div style={{display:"flex",justifyContent:"space-between",marginBottom:4}}><span style={{fontWeight:600}}>{s.name}</span><span style={{fontWeight:700}}>{s.members}名</span></div>
<div style={{display:"flex",justifyContent:"space-between",fontSize:11,color:"#64748b"}}><span>月額 {yen(s.price)}</span><span>月間収益 {yen(s.members*s.price)}</span></div>
</div>)}
<div style={{borderTop:"2px solid #e2e8f0",paddingTop:8,marginTop:8,display:"flex",justifyContent:"space-between"}}><span style={{fontWeight:700}}>合計MRR</span><span style={{fontWeight:700,fontSize:16,color:"#1e3a5f"}}>{yen(D.mrr)}</span></div>
</Card>
</div>
</div>;
}
function Reception(){
const[step,setStep]=useState("scan");const[comp,setComp]=useState(0);const m=D.members[0];
return <div style={{maxWidth:480,margin:"0 auto"}}>
<h1 style={{fontSize:18,fontWeight:700,margin:"0 0 12px"}}>入店受付</h1>
{step==="scan"&&<Card><div style={{textAlign:"center",padding:"32px 0"}}>
<div style={{width:72,height:72,margin:"0 auto",background:"#f5f5f4",borderRadius:8,display:"flex",alignItems:"center",justifyContent:"center"}}><Ic d={P.scan} size={28} color="#a8a29e"/></div>
<p style={{color:"#78716c",fontSize:13,marginTop:12}}>顔認証またはQRコードで会員を確認</p>
<button onClick={()=>setStep("found")} style={{background:"#1c1917",color:"#fff",border:"none",padding:"10px 20px",borderRadius:6,fontSize:12,fontWeight:600,cursor:"pointer",marginTop:16}}>認証実行(デモ)</button>
</div></Card>}
{step==="found"&&<Card>
<div style={{display:"flex",alignItems:"center",gap:12,marginBottom:16}}>
<div style={{width:44,height:44,borderRadius:6,background:"#f5f5f4",display:"flex",alignItems:"center",justifyContent:"center",fontSize:18,fontWeight:700,color:"#44403c"}}>{m.name[0]}</div>
<div><div style={{fontSize:18,fontWeight:700}}>{m.name}</div><div style={{display:"flex",gap:4,marginTop:2}}><Bdg t="契約中" v="active"/><Bdg t={m.store} v="blue"/></div></div>
</div>
<div style={{display:"grid",gridTemplateColumns:"1fr 1fr 1fr",gap:1,background:"#e2e8f0",borderRadius:6,overflow:"hidden",marginBottom:16}}>
{[[m.visits+"回","累計来店"],[m.bottles+"本","キープ"],["5/15","次回課金"]].map(([v,l])=><div key={l} style={{background:"#f8fafc",padding:"10px 8px",textAlign:"center"}}><div style={{fontSize:16,fontWeight:700}}>{v}</div><div style={{fontSize:10,color:"#64748b"}}>{l}</div></div>)}
</div>
<div style={{marginBottom:16}}>
<label style={{fontSize:12,fontWeight:600,color:"#334155",display:"block",marginBottom:6}}>同伴者数</label>
<div style={{display:"flex",gap:6}}>{[0,1,2,3,4,5].map(n=><button key={n} onClick={()=>setComp(n)} style={{width:40,height:40,borderRadius:6,border:comp===n?"2px solid #1c1917":"1px solid #e2e8f0",background:comp===n?"#1c1917":"#fff",color:comp===n?"#fff":"#44403c",fontWeight:700,fontSize:14,cursor:"pointer"}}>{n}</button>)}</div>
{comp>=3&&<div style={{background:"#fef3c7",border:"1px solid #fde68a",borderRadius:6,padding:"8px 10px",marginTop:8,fontSize:11,color:"#92400e"}}>同伴3名以降: ビジター料金 {yen(3000*(comp-2))} が発生します</div>}
</div>
<button onClick={()=>setStep("done")} style={{width:"100%",background:"#1c1917",color:"#fff",border:"none",padding:12,borderRadius:6,fontSize:13,fontWeight:600,cursor:"pointer"}}><Ic d={P.check} size={16} color="#fff"/> 入店確認</button>
</Card>}
{step==="done"&&<Card><div style={{textAlign:"center",padding:"20px 0"}}>
<div style={{width:40,height:40,borderRadius:20,background:"#dcfce7",margin:"0 auto",display:"flex",alignItems:"center",justifyContent:"center"}}><Ic d={P.check} color="#16a34a"/></div>
<div style={{fontSize:16,fontWeight:700,color:"#166534",marginTop:12}}>入店確認完了</div>
<div style={{fontSize:13,color:"#15803d",marginTop:4}}>{m.name}様 + 同伴{comp}名</div>
{comp>=3&&<div style={{fontSize:12,color:"#92400e",marginTop:4}}>ビジター課金: {yen(3000*(comp-2))}</div>}
<button onClick={()=>{setStep("scan");setComp(0);}} style={{background:"#f5f5f4",color:"#44403c",border:"none",padding:"8px 20px",borderRadius:6,fontSize:12,fontWeight:600,cursor:"pointer",marginTop:16}}>次の受付</button>
</div></Card>}
</div>;
}
function Members({go}){
return <div>
<h1 style={{fontSize:18,fontWeight:700,margin:"0 0 12px"}}>会員管理 <span style={{fontSize:12,color:"#64748b",fontWeight:400}}>{D.members.length}名</span></h1>
<div style={{background:"#fff",border:"1px solid #e2e8f0",borderRadius:8,overflowX:"auto"}}><table style={{width:"100%",minWidth:600,borderCollapse:"collapse"}}><thead><tr style={{background:"#f8fafc",borderBottom:"1px solid #e2e8f0"}}>{["会員名","店舗","ステータス","入会","来店","月額","次回課金","ボトル"].map(h=><th key={h} style={{padding:"8px 10px",textAlign:"left",fontSize:10,fontWeight:600,color:"#64748b"}}>{h}</th>)}</tr></thead><tbody>
{D.members.map(m=><tr key={m.id} onClick={()=>go("member-detail",m)} style={{cursor:"pointer"}}>
<td style={{...td,fontWeight:600,color:"#1c1917"}}>{m.name}</td>
<td style={td}><Bdg t={m.store} v="blue"/></td>
<td style={td}><Bdg t={statusLabel[m.status]} v={m.status}/></td>
<td style={td}>{m.since}</td>
<td style={{...td,textAlign:"right"}}>{m.visits}回</td>
<td style={{...td,textAlign:"right"}}>{yen(m.plan)}</td>
<td style={td}>{m.nextBill}</td>
<td style={{...td,textAlign:"right"}}>{m.bottles}本</td>
</tr>)}
</tbody></table></div>
</div>;
}
function MemberDetail({m,go}){
if(!m)return null;
return <div>
<button onClick={()=>go("members")} style={{background:"none",border:"none",color:"#64748b",cursor:"pointer",fontSize:12,display:"flex",alignItems:"center",gap:4,marginBottom:8,padding:0}}><Ic d={P.back} size={14}/> 会員一覧</button>
<div style={{display:"flex",alignItems:"center",gap:12,marginBottom:16}}>
<div style={{width:44,height:44,borderRadius:6,background:"#f5f5f4",display:"flex",alignItems:"center",justifyContent:"center",fontSize:18,fontWeight:700,color:"#44403c"}}>{m.name[0]}</div>
<div><div style={{fontSize:20,fontWeight:700}}>{m.name}</div><div style={{display:"flex",gap:4,marginTop:2}}><Bdg t={statusLabel[m.status]} v={m.status}/><Bdg t={m.store} v="blue"/></div></div>
</div>
<div style={{display:"grid",gridTemplateColumns:"repeat(auto-fit,minmax(260px,1fr))",gap:12}}>
<div>
<Card title="契約情報">{[["月額",yen(m.plan)],["入会日",m.since],["次回課金",m.nextBill],["来店回数",m.visits+"回"],["最終来店",m.lastVisit],["キープ",m.bottles+"本"]].map(([l,v])=><div key={l} style={{display:"flex",justifyContent:"space-between",padding:"5px 0",borderBottom:"1px solid #f8fafc",fontSize:12}}><span style={{color:"#64748b"}}>{l}</span><span style={{fontWeight:600}}>{v}</span></div>)}</Card>
{m.bottles>0&&<Card title="キープボトル">
{["山崎12年(残1/3)","響 JAPANESE HARMONY"].slice(0,m.bottles).map((b,i)=><div key={i} style={{padding:"6px 0",borderBottom:"1px solid #f1f5f9",fontSize:12,display:"flex",alignItems:"center",gap:6}}><Ic d={P.wine} size={14} color="#78716c"/>{b}</div>)}
</Card>}
</div>
<Card title="来店履歴">
{[{d:"5/11",in:"20:15",out:"23:40",comp:1,add:"-"},{d:"5/8",in:"21:00",out:"23:15",comp:2,add:"-"},{d:"5/3",in:"19:30",out:"22:00",comp:3,add:"ビジター¥3,000 + VIP¥5,000"},{d:"4/28",in:"20:45",out:"22:30",comp:0,add:"-"},{d:"4/22",in:"21:30",out:"23:55",comp:1,add:"スタッフDr. ¥2,000"}].map((v,i)=><div key={i} style={{display:"flex",justifyContent:"space-between",padding:"7px 0",borderBottom:"1px solid #f1f5f9",fontSize:12}}>
<span style={{width:50}}>{v.d}</span>
<span style={{width:100,color:"#64748b"}}>{v.in}〜{v.out}</span>
<span style={{width:50,textAlign:"center"}}>同伴{v.comp}</span>
<span style={{flex:1,textAlign:"right",color:v.add==="-"?"#d1d5db":"#92400e",fontSize:11}}>{v.add}</span>
</div>)}
</Card>
</div>
</div>;
}
function Billing(){
const b=D.billing[0];
return <div>
<h1 style={{fontSize:18,fontWeight:700,margin:"0 0 12px"}}>課金管理 <span style={{fontSize:12,color:"#64748b",fontWeight:400}}>2026年4月</span></h1>
<div style={{display:"grid",gridTemplateColumns:"repeat(auto-fill,minmax(160px,1fr))",gap:10,marginBottom:16}}>
<Kpi label="月額会費収入" value={yen(b.sub)}/>
<Kpi label="追加課金収入" value={yen(b.visitor+b.vip+b.drink+b.food)}/>
<Kpi label="売上合計" value={yen(b.total)}/>
</div>
<Card title="収益内訳">
{[["月額会費(サブスク)",b.sub],["ビジター料金",b.visitor],["VIPルーム",b.vip],["スタッフドリンク",b.drink],["軽食",b.food]].map(([l,v])=><div key={l} style={{display:"flex",justifyContent:"space-between",padding:"6px 0",borderBottom:"1px solid #f1f5f9",fontSize:13}}><span style={{color:"#475569"}}>{l}</span><span style={{fontWeight:600}}>{yen(v)}</span></div>)}
<div style={{display:"flex",justifyContent:"space-between",padding:"8px 0",borderTop:"2px solid #cbd5e1",marginTop:4}}><span style={{fontWeight:700}}>合計</span><span style={{fontWeight:700,fontSize:16,color:"#1c1917"}}>{yen(b.total)}</span></div>
</Card>
<Card title="未払い会員">
<div style={{display:"flex",alignItems:"center",gap:8,padding:"8px 0"}}>
<Bdg t="未払い" v="overdue"/>
<span style={{fontSize:13,fontWeight:600}}>渡辺 洋介</span>
<span style={{fontSize:11,color:"#64748b",marginLeft:"auto"}}>香椎店 / 課金日 5/5 / {yen(11000)}</span>
</div>
</Card>
</div>;
}
function Charges(){
return <div>
<h1 style={{fontSize:18,fontWeight:700,margin:"0 0 12px"}}>追加課金記録</h1>
<div style={{background:"#fff",border:"1px solid #e2e8f0",borderRadius:8,overflowX:"auto"}}><table style={{width:"100%",minWidth:600,borderCollapse:"collapse"}}><thead><tr style={{background:"#f8fafc",borderBottom:"1px solid #e2e8f0"}}>{["日付","会員","種別","数量","金額"].map(h=><th key={h} style={{padding:"8px 10px",textAlign:"left",fontSize:10,fontWeight:600,color:"#64748b"}}>{h}</th>)}</tr></thead><tbody>
{[
{d:"5/11",name:"高橋 誠",type:"VIPルーム",qty:1,amt:5000},
{d:"5/11",name:"高橋 誠",type:"ビジター",qty:1,amt:3000},
{d:"5/11",name:"高橋 誠",type:"スタッフドリンク",qty:2,amt:2000},
{d:"5/11",name:"佐藤 健一",type:"スタッフドリンク",qty:1,amt:1000},
{d:"5/8",name:"田中 太郎",type:"軽食",qty:1,amt:800},
].map((c,i)=><tr key={i}><td style={td}>{c.d}</td><td style={{...td,fontWeight:600}}>{c.name}</td><td style={td}><Bdg t={c.type}/></td><td style={{...td,textAlign:"right"}}>{c.qty}</td><td style={{...td,textAlign:"right",fontWeight:600}}>{yen(c.amt)}</td></tr>)}
</tbody></table></div>
</div>;
}
function Bottles(){
return <div>
<h1 style={{fontSize:18,fontWeight:700,margin:"0 0 12px"}}>ボトルキープ管理</h1>
<div style={{background:"#fff",border:"1px solid #e2e8f0",borderRadius:8,overflowX:"auto"}}><table style={{width:"100%",minWidth:600,borderCollapse:"collapse"}}><thead><tr style={{background:"#f8fafc",borderBottom:"1px solid #e2e8f0"}}>{["会員","店舗","ボトル名","持込日","残量","状態"].map(h=><th key={h} style={{padding:"8px 10px",textAlign:"left",fontSize:10,fontWeight:600,color:"#64748b"}}>{h}</th>)}</tr></thead><tbody>
{[
{name:"田中 太郎",store:"宗像",bottle:"山崎12年",date:"4/20",remain:"残1/3",s:"active"},
{name:"田中 太郎",store:"宗像",bottle:"響 JAPANESE HARMONY",date:"5/3",remain:"残2/3",s:"active"},
{name:"佐藤 健一",store:"宗像",bottle:"マッカラン18年",date:"3/15",remain:"残1/4",s:"active"},
{name:"高橋 誠",store:"宗像",bottle:"余市",date:"5/1",remain:"ほぼ満",s:"active"},
{name:"高橋 誠",store:"宗像",bottle:"白州",date:"4/10",remain:"残半分",s:"active"},
{name:"高橋 誠",store:"宗像",bottle:"角ハイボール",date:"3/1",remain:"空",s:"empty"},
].map((b,i)=><tr key={i}><td style={{...td,fontWeight:600}}>{b.name}</td><td style={td}>{b.store}</td><td style={td}>{b.bottle}</td><td style={td}>{b.date}</td><td style={td}>{b.remain}</td><td style={td}><Bdg t={b.s==="active"?"キープ中":"空"} v={b.s==="active"?"active":"cancelled"}/></td></tr>)}
</tbody></table></div>
</div>;
}
function Expenses(){
const e=D.expenses;const tot=Object.values(e).reduce((a,b)=>a+b,0);const rev=D.billing[0].total;const pf=rev-tot;
const labels={rent:"家賃",utilities:"光熱費",personnel:"人件費",advertising:"広告費",purchase:"仕入",misc:"雑費"};
return <div style={{maxWidth:640,margin:"0 auto"}}>
<h1 style={{fontSize:18,fontWeight:700,margin:"0 0 4px"}}>経費・損益</h1><p style={{fontSize:12,color:"#64748b",margin:"0 0 12px"}}>2026年4月</p>
<Card title="月次損益計算書">
<div style={{display:"flex",justifyContent:"space-between",padding:"8px 0",borderBottom:"2px solid #cbd5e1"}}><span style={{fontWeight:700}}>売上高</span><span style={{fontWeight:700,fontSize:16,color:"#1c1917"}}>{yen(rev)}</span></div>
<div style={{fontSize:11,color:"#64748b",padding:"8px 0 4px",fontWeight:600}}>経費</div>
{Object.entries(labels).map(([k,l])=><div key={k} style={{display:"flex",justifyContent:"space-between",padding:"5px 0 5px 12px",borderBottom:"1px solid #f1f5f9",fontSize:13}}><span style={{color:"#475569"}}>{l}</span><span>{yen(e[k])}</span></div>)}
<div style={{display:"flex",justifyContent:"space-between",padding:"8px 0",borderTop:"2px solid #cbd5e1",marginTop:4}}><span style={{fontWeight:700}}>経費合計</span><span style={{fontWeight:700,fontSize:16,color:"#dc2626"}}>{yen(tot)}</span></div>
<div style={{display:"flex",justifyContent:"space-between",padding:"12px 0 4px"}}><span style={{fontSize:16,fontWeight:700}}>営業利益</span><span style={{fontSize:22,fontWeight:700,color:pf>=0?"#16a34a":"#dc2626"}}>{yen(pf)}</span></div>
<div style={{textAlign:"right",fontSize:12,color:pf>=0?"#16a34a":"#dc2626"}}>利益率 {Math.round(pf/rev*100)}%</div>
</Card>
</div>;
}
function Staff(){return <div><h1 style={{fontSize:18,fontWeight:700,margin:"0 0 12px"}}>スタッフ管理</h1>
{[{name:"山田 花子",role:"店長",store:"宗像本店"},{name:"木村 拓也",role:"スタッフ",store:"宗像本店"},{name:"中村 美咲",role:"スタッフ",store:"香椎店"},{name:"井上 翔",role:"スタッフ",store:"香椎店"}].map((s,i)=>
<Card key={i} style={{display:"flex",gap:12,alignItems:"center"}}>
<div style={{width:36,height:36,borderRadius:6,background:"#f5f5f4",display:"flex",alignItems:"center",justifyContent:"center",fontSize:14,fontWeight:700,color:"#44403c"}}>{s.name[0]}</div>
<div style={{flex:1}}><div style={{fontWeight:700,fontSize:13}}>{s.name}</div><div style={{fontSize:11,color:"#64748b"}}>{s.store}</div></div>
<Bdg t={s.role}/>
</Card>
)}
</div>;}
function Settings(){return <div><h1 style={{fontSize:18,fontWeight:700,margin:"0 0 12px"}}>設定</h1>
{[["店舗管理","店舗情報・営業時間の管理",P.store],["プラン設定","月額料金・会員上限の設定",P.dollar],["スタッフ管理","アカウント・権限管理",P.user]].map(([t,d,icon])=>
<Card key={t} style={{display:"flex",gap:12,alignItems:"center",cursor:"pointer"}}>
<div style={{width:40,height:40,borderRadius:6,background:"#f5f5f4",display:"flex",alignItems:"center",justifyContent:"center"}}><Ic d={icon} color="#78716c"/></div>
<div><div style={{fontWeight:700,fontSize:14}}>{t}</div><div style={{fontSize:12,color:"#64748b"}}>{d}</div></div>
</Card>
)}
</div>;}
/* ═══ Member App (冒険者テーマ・ピンク基調) ═══ */
function MemberApp(){
const[tab,setTab]=useState("home");
const pk="#ec4899",pkL="#fdf2f8",pkB="#fce7f3",pkD="#be185d";
const tabs=[{id:"home",l:"拠点",e:"🏰"},{id:"qr",l:"冒険者証",e:"⚔️"},{id:"history",l:"冒険記録",e:"📜"},{id:"bottle",l:"宝物庫",e:"🍷"},{id:"my",l:"ステータス",e:"🛡️"}];
return <div style={{paddingBottom:64,minHeight:"100vh"}}>
<div style={{padding:16}}>
{tab==="home"&&<div>
<div className="dg-slide" style={{background:"linear-gradient(135deg,#ec4899,#f472b6,#fb7185)",borderRadius:16,padding:20,marginBottom:14,color:"#fff",position:"relative",overflow:"hidden"}}>
<div style={{position:"absolute",top:-15,right:-10,fontSize:70,opacity:.08,transform:"rotate(15deg)"}}>⚔️</div>
<div style={{display:"flex",alignItems:"center",gap:12,marginBottom:14}}>
<div style={{width:50,height:50,borderRadius:14,background:"rgba(255,255,255,0.2)",border:"2px solid rgba(255,255,255,0.3)",display:"flex",alignItems:"center",justifyContent:"center",fontSize:24}}>🥇</div>
<div style={{flex:1}}>
<div style={{fontSize:11,opacity:.85,letterSpacing:1}}>ADVENTURER</div>
<div style={{fontSize:20,fontWeight:800}}>田中 太郎</div>
</div>
<div style={{background:"rgba(255,255,255,0.25)",padding:"4px 14px",borderRadius:8}}>
<span style={{fontSize:11,fontWeight:800,letterSpacing:1}}>GOLD</span>
</div>
</div>
<div style={{background:"rgba(255,255,255,0.15)",borderRadius:10,padding:"12px 14px"}}>
<div style={{display:"flex",justifyContent:"space-between",fontSize:10,opacity:.9,marginBottom:5}}>
<span>📅 ご契約プラン</span><span style={{fontWeight:700}}>¥16,500 /月</span>
</div>
<div style={{fontSize:11,opacity:.8}}>宗像本店 / 次回課金日: 5月15日</div>
</div>
</div>
<div style={{display:"grid",gridTemplateColumns:"1fr 1fr 1fr",gap:8,marginBottom:14}}>
{[["42","累計冒険","🗡️",pk],["2","キープ","🍷","#8b5cf6"],["5/11","最終来店","📅","#f59e0b"]].map(([v,l,e,c],i)=>
<div key={l} className="dg-slide" style={{background:"#fff",border:`1px solid ${pkB}`,borderRadius:12,padding:"14px 8px",textAlign:"center",animationDelay:i*0.1+"s"}}>
<div style={{fontSize:18,marginBottom:2}}>{e}</div>
<div style={{fontSize:18,fontWeight:800,color:c}}>{v}</div>
<div style={{fontSize:9,color:"#9ca3af",marginTop:2}}>{l}</div>
</div>
)}
</div>
<button onClick={()=>setTab("qr")} className="dg-glow" style={{width:"100%",background:"#fff",border:`2px solid ${pkB}`,borderRadius:12,padding:14,cursor:"pointer",color:pk,fontWeight:700,fontSize:14,display:"flex",alignItems:"center",justifyContent:"center",gap:8,marginBottom:20}}>
<span className="dg-float" style={{fontSize:18}}>⚔️</span> 冒険者証を表示
</button>
<div style={{display:"flex",alignItems:"center",gap:6,marginBottom:10}}>
<span style={{fontSize:14}}>📋</span>
<span style={{fontSize:11,color:pk,fontWeight:700,letterSpacing:2}}>INFO</span>
</div>
<div style={{background:"#fff",border:`1px solid ${pkB}`,borderRadius:10,padding:"12px 14px",marginBottom:6}}>
<div style={{fontSize:13,fontWeight:600,color:"#1e1e2e"}}>同伴者2名まで無料</div>
<div style={{fontSize:11,color:"#9ca3af",marginTop:2}}>3名目以降はビジター料金 ¥3,000/人</div>
</div>
<div style={{background:"#fff",border:`1px solid ${pkB}`,borderRadius:10,padding:"12px 14px"}}>
<div style={{fontSize:13,fontWeight:600,color:"#1e1e2e"}}>ボトル持ち込み・キープOK</div>
<div style={{fontSize:11,color:"#9ca3af",marginTop:2}}>現在 2本キープ中</div>
</div>
</div>}
{tab==="qr"&&<div style={{textAlign:"center",paddingTop:8}}>
<div className="dg-slide dg-glow" style={{background:"linear-gradient(160deg,#fff,#fdf2f8,#fff)",border:`2px solid ${pkB}`,borderRadius:20,padding:"28px 22px",maxWidth:300,margin:"0 auto",boxShadow:`0 8px 32px ${pk}10`}}>
<div className="dg-float" style={{fontSize:30,marginBottom:6}}>⚔️</div>
<div style={{fontSize:9,color:"#d1d5db",letterSpacing:3,fontWeight:600}}>ADVENTURER'S CARD</div>
<div style={{margin:"10px 0"}}><span style={{background:`linear-gradient(135deg,${pk},#f472b6)`,color:"#fff",padding:"4px 18px",borderRadius:8,fontSize:11,fontWeight:800,letterSpacing:1}}>🥇 GOLD</span></div>
<div style={{fontSize:20,fontWeight:800,color:"#1e1e2e",marginTop:6}}>田中 太郎</div>
<div style={{fontSize:11,color:"#9ca3af",marginTop:2}}>宗像本店</div>
<div style={{width:170,height:170,margin:"18px auto",background:"#fff",borderRadius:14,border:`3px solid ${pkB}`,display:"flex",alignItems:"center",justifyContent:"center",flexDirection:"column",boxShadow:`0 0 20px ${pk}10`}}>
<Ic d={P.scan} size={52} color={pk}/>
<span style={{fontSize:9,color:"#d1d5db",marginTop:8}}>ギルドマスターに提示</span>
</div>
<div style={{borderTop:`1px solid ${pkB}`,paddingTop:14,marginTop:4}}>
<div style={{fontSize:9,color:"#d1d5db",letterSpacing:2}}>MEMBERSHIP</div>
<div className="dg-shimmer" style={{fontSize:24,fontWeight:800,marginTop:4}}>¥16,500 /月</div>
</div>
</div>
<div style={{fontSize:11,color:"#9ca3af",marginTop:18}}>来店時にスタッフにお見せください</div>
</div>}
{tab==="history"&&<div>
<div style={{display:"flex",alignItems:"center",gap:6,marginBottom:12}}>
<span style={{fontSize:14}}>📜</span>
<span style={{fontSize:11,color:pk,fontWeight:700,letterSpacing:2}}>冒険記録</span>
</div>
{[{d:"5/11",in:"20:15",out:"23:40",comp:1,note:""},{d:"5/8",in:"21:00",out:"23:15",comp:2,note:""},{d:"5/3",in:"19:30",out:"22:00",comp:3,note:"VIPルーム利用"},{d:"4/28",in:"20:45",out:"22:30",comp:0,note:""},{d:"4/22",in:"21:30",out:"23:55",comp:1,note:"スタッフDr. 2杯"}].map((v,i)=>
<div key={i} className="dg-slide" style={{background:"#fff",border:`1px solid ${pkB}`,borderRadius:10,padding:"12px 14px",marginBottom:6,animationDelay:i*0.08+"s"}}>
<div style={{display:"flex",justifyContent:"space-between",alignItems:"center"}}>
<div>
<div style={{fontSize:13,fontWeight:600,color:"#1e1e2e"}}>{v.d}</div>
<div style={{fontSize:11,color:"#9ca3af",marginTop:2}}>{v.in} - {v.out}</div>
</div>
<div style={{textAlign:"right"}}>
<span style={{fontSize:11,color:"#6b7280"}}>同伴 {v.comp}名</span>
{v.note&&<div style={{fontSize:10,color:pk,marginTop:2}}>{v.note}</div>}
</div>
</div>
</div>
)}
</div>}
{tab==="bottle"&&<div>
<div style={{display:"flex",alignItems:"center",gap:6,marginBottom:12}}>
<span style={{fontSize:14}}>🍷</span>
<span style={{fontSize:11,color:pk,fontWeight:700,letterSpacing:2}}>宝物庫(ボトルキープ)</span>
</div>
{[{name:"山崎12年",date:"4/20",remain:"残1/3"},{name:"響 JAPANESE HARMONY",date:"5/3",remain:"残2/3"}].map((b,i)=>
<div key={i} className="dg-slide" style={{background:"#fff",border:`1px solid ${pkB}`,borderRadius:10,padding:"14px",marginBottom:8,display:"flex",alignItems:"center",gap:12,animationDelay:i*0.1+"s"}}>
<div style={{width:40,height:40,borderRadius:10,background:pkL,display:"flex",alignItems:"center",justifyContent:"center",fontSize:18}}>🍷</div>
<div style={{flex:1}}>
<div style={{fontSize:13,fontWeight:600,color:"#1e1e2e"}}>{b.name}</div>
<div style={{fontSize:11,color:"#9ca3af",marginTop:2}}>持込 {b.date}</div>
</div>
<span style={{fontSize:11,color:pk,fontWeight:600}}>{b.remain}</span>
</div>
)}
<div style={{background:"#fff",border:`1px dashed ${pkB}`,borderRadius:10,padding:16,textAlign:"center",marginTop:8}}>
<span style={{fontSize:18}}>🔮</span>
<div style={{fontSize:11,color:"#d1d5db",marginTop:4}}>新しいボトルを持ち込みましょう</div>
</div>
</div>}
{tab==="my"&&<div>
<div className="dg-slide" style={{textAlign:"center",paddingBottom:18,borderBottom:`1px solid ${pkB}`,marginBottom:16}}>
<div className="dg-glow" style={{width:64,height:64,borderRadius:16,background:pkL,border:`2px solid ${pkB}`,margin:"0 auto",display:"flex",alignItems:"center",justifyContent:"center",fontSize:28}}>🥇</div>
<div style={{fontSize:20,fontWeight:800,marginTop:10,color:"#1e1e2e"}}>田中 太郎</div>
<div style={{margin:"6px 0"}}><span style={{background:`linear-gradient(135deg,${pk},#f472b6)`,color:"#fff",padding:"3px 16px",borderRadius:8,fontSize:10,fontWeight:800,letterSpacing:1}}>GOLD ADVENTURER</span></div>
</div>
<div className="dg-slide" style={{background:"#fff",border:`1px solid ${pkB}`,borderRadius:10,padding:14,marginBottom:16,animationDelay:".1s"}}>
<div style={{fontSize:9,color:pk,fontWeight:700,letterSpacing:2,marginBottom:10}}>⚔️ STATUS</div>
{[["累計冒険","42回",85,pk,"🗡️"],["キープボトル","2本",40,"#8b5cf6","🍷"],["契約月数","12ヶ月",60,"#f59e0b","📅"]].map(([l,v,w,c,e])=>
<div key={l} style={{marginBottom:10}}>
<div style={{display:"flex",justifyContent:"space-between",fontSize:11,marginBottom:4}}>
<span style={{color:"#6b7280"}}>{e} {l}</span>
<span style={{color:c,fontWeight:700}}>{v}</span>
</div>
<div style={{height:6,borderRadius:3,background:pkL,overflow:"hidden"}}>
<div style={{height:6,borderRadius:3,background:c,width:w+"%",boxShadow:`0 0 6px ${c}40`}}/>
</div>
</div>
)}
</div>
<div style={{fontSize:10,color:"#9ca3af",fontWeight:600,letterSpacing:1,marginBottom:8}}>MENU</div>
{[["📋","契約情報","宗像本店 / ¥16,500"],["💳","課金履歴","次回 5/15"],["🏪","店舗情報","宗像本店・香椎店"],["✏️","プロフィール編集",""]].map(([e,l,v],i)=>
<div key={l} className="dg-slide" style={{background:"#fff",border:`1px solid ${pkB}`,borderRadius:8,padding:"11px 14px",marginBottom:5,display:"flex",alignItems:"center",fontSize:12,cursor:"pointer",transition:"border-color .2s",animationDelay:(i*0.06+0.2)+"s"}}
onMouseEnter={ev=>ev.currentTarget.style.borderColor=pk}
onMouseLeave={ev=>ev.currentTarget.style.borderColor=pkB}>
<span style={{fontSize:14,marginRight:10}}>{e}</span>
<span style={{flex:1,color:"#1e1e2e"}}>{l}</span>
{v&&<span style={{color:pk,fontSize:11,fontWeight:600,marginRight:6}}>{v}</span>}
<Ic d={P.chev} size={12} color="#d1d5db"/>
</div>
)}
<div style={{marginTop:16,border:"1px solid #fecdd3",borderRadius:8,padding:"11px 14px",textAlign:"center",background:"#fff5f5",cursor:"pointer"}}>
<span style={{color:"#ef4444",fontSize:12,fontWeight:600}}>🚪 退会申請</span>
</div>
<div style={{textAlign:"center",color:"#d1d5db",fontSize:9,marginTop:16}}>DUNGEON v1.0.0</div>
</div>}
</div>
<div style={{position:"fixed",bottom:0,left:"50%",transform:"translateX(-50%)",width:"100%",maxWidth:430,background:"#fff",borderTop:`1px solid ${pkB}`,display:"flex",alignItems:"flex-end",padding:"0 0 8px"}}>
{tabs.map(t=>{
const active=tab===t.id;
const isCenter=t.id==="qr";
if(isCenter) return <button key={t.id} onClick={()=>setTab(t.id)} style={{flex:1,background:"none",border:"none",cursor:"pointer",textAlign:"center",display:"flex",flexDirection:"column",alignItems:"center",padding:0}}>
<div className={active?"dg-glow":""} style={{width:48,height:48,borderRadius:24,background:active?`linear-gradient(135deg,${pk},#f472b6)`:pkL,display:"flex",alignItems:"center",justifyContent:"center",marginTop:-14,border:"3px solid #fff",boxShadow:active?`0 0 16px ${pk}40`:"0 2px 6px rgba(0,0,0,0.06)",transition:"all .2s",fontSize:18}}>{t.e}</div>
<span style={{fontSize:8,fontWeight:700,marginTop:2,color:active?pk:"#d1d5db"}}>{t.l}</span>
</button>;
return <button key={t.id} onClick={()=>setTab(t.id)} style={{flex:1,background:"none",border:"none",cursor:"pointer",textAlign:"center",paddingTop:8}}>
<div style={{fontSize:16,transition:"transform .15s",transform:active?"scale(1.15)":"scale(1)"}}>{t.e}</div>
<div style={{fontSize:8,fontWeight:700,marginTop:2,color:active?pk:"#d1d5db",letterSpacing:.3}}>{t.l}</div>
</button>;
})}
</div>
</div>;
}