{"id":236,"date":"2026-03-18T14:51:39","date_gmt":"2026-03-18T05:51:39","guid":{"rendered":"https:\/\/hikanokurashi.com\/?p=236"},"modified":"2026-03-18T14:51:39","modified_gmt":"2026-03-18T05:51:39","slug":"236","status":"publish","type":"post","link":"https:\/\/hikanokurashi.com\/?p=236","title":{"rendered":""},"content":{"rendered":"\n<pre class=\"wp-block-code\"><code>import { useState, useEffect, useRef, useCallback } from \"react\";\n\n\/\/ \u2550\u2550\u2550 \u5360\u661f\u8853\u30c7\u30fc\u30bf \u2550\u2550\u2550\nconst SIGNS = &#91;'\u7261\u7f8a\u5ea7','\u7261\u725b\u5ea7','\u53cc\u5b50\u5ea7','\u87f9\u5ea7','\u7345\u5b50\u5ea7','\u4e59\u5973\u5ea7','\u5929\u79e4\u5ea7','\u880d\u5ea7','\u5c04\u624b\u5ea7','\u5c71\u7f8a\u5ea7','\u6c34\u74f6\u5ea7','\u9b5a\u5ea7'];\nconst SSYM  = &#91;'\u2648','\u2649','\u264a','\u264b','\u264c','\u264d','\u264e','\u264f','\u2650','\u2651','\u2652','\u2653'];\nconst PSYM  = {Sun:'\u2609',Moon:'\u263d',Mercury:'\u263f',Venus:'\u2640',Mars:'\u2642',Jupiter:'\u2643',Saturn:'\u2644',Uranus:'\u2645',Neptune:'\u2646',Pluto:'\u2647'};\nconst PJP   = {Sun:'\u592a\u967d',Moon:'\u6708',Mercury:'\u6c34\u661f',Venus:'\u91d1\u661f',Mars:'\u706b\u661f',Jupiter:'\u6728\u661f',Saturn:'\u571f\u661f',Uranus:'\u5929\u738b\u661f',Neptune:'\u6d77\u738b\u661f',Pluto:'\u51a5\u738b\u661f'};\nconst PCOL  = {Sun:'#c89840',Moon:'#7090c0',Mercury:'#40a890',Venus:'#d07890',Mars:'#d06050',Jupiter:'#c09050',Saturn:'#8090b0',Uranus:'#50b8c0',Neptune:'#6870d8',Pluto:'#a060b8'};\nconst PACC  = {Sun:'linear-gradient(90deg,#c89840,#e8c070)',Moon:'linear-gradient(90deg,#7090c0,#a0b8e0)',Mercury:'linear-gradient(90deg,#40a890,#70d0b0)',Venus:'linear-gradient(90deg,#d07890,#f0a8b8)',Mars:'linear-gradient(90deg,#d06050,#f08070)',Jupiter:'linear-gradient(90deg,#c09050,#e0b870)',Saturn:'linear-gradient(90deg,#8090b0,#a8b8d0)',Uranus:'linear-gradient(90deg,#50b8c0,#80d8e0)',Neptune:'linear-gradient(90deg,#6870d8,#9090f0)',Pluto:'linear-gradient(90deg,#a060b8,#c888d8)'};\nconst FORTUNE_COLORS = &#91;\n  {bar:'linear-gradient(90deg,#c8a87a,#a8885a)', dot:'#c8a87a'},\n  {bar:'linear-gradient(90deg,#7aa4d4,#4a6fa5)', dot:'#4a6fa5'},\n  {bar:'linear-gradient(90deg,#e09aaa,#c86478)', dot:'#c86478'},\n  {bar:'linear-gradient(90deg,#7abd8a,#4a8c5c)', dot:'#4a8c5c'},\n];\n\n\/\/ \u2550\u2550\u2550 \u5929\u6587\u8a08\u7b97 \u2550\u2550\u2550\nfunction toJD(y,m,d,h,mn){ if(m&lt;=2){y--;m+=12;} const A=Math.floor(y\/100),B=2-A+Math.floor(A\/4); return Math.floor(365.25*(y+4716))+Math.floor(30.6001*(m+1))+d+B-1524.5+(h+mn\/60)\/24; }\nfunction calcDeg(jd,p){ const T=(jd-2451545)\/36525; const base={Sun:280.46646+36000.76983*T,Moon:218.3165+481267.8813*T,Mercury:252.2509+149472.6746*T,Venus:181.9798+58517.8157*T,Mars:355.4330+19140.2993*T,Jupiter:34.3515+3034.9057*T,Saturn:50.0775+1221.8760*T,Uranus:314.0550+428.4748*T,Neptune:304.3487+218.4071*T,Pluto:238.9260+145.2078*T}; return((base&#91;p]||0)%360+360)%360; }\nfunction dts(deg){ const i=Math.floor(((deg%360)+360)%360\/30); return{idx:i,within:(((deg%360)+360)%360%30).toFixed(1),sign:SIGNS&#91;i],sym:SSYM&#91;i]}; }\nfunction buildPos(y,m,d,hh,mn){\n  const jd=toJD(y,m,d,hh||12,mn||0);\n  const PL=&#91;'Sun','Moon','Mercury','Venus','Mars','Jupiter','Saturn','Uranus','Neptune','Pluto'];\n  const pos={}; PL.forEach(p=>pos&#91;p]=calcDeg(jd,p));\n  pos.Ascendant=((pos.Sun+90+(hh-6)*15)%360+360)%360;\n  return pos;\n}\n\n\/\/ \u2550\u2550\u2550 Claude API \u2550\u2550\u2550\nasync function callClaude(prompt) {\n  const res = await fetch(\"https:\/\/api.anthropic.com\/v1\/messages\", {\n    method:\"POST\", headers:{\"Content-Type\":\"application\/json\"},\n    body: JSON.stringify({ model:\"claude-sonnet-4-20250514\", max_tokens:1800,\n      messages:&#91;{role:\"user\", content:prompt}] })\n  });\n  const data = await res.json();\n  if(data.error) throw new Error(data.error.message);\n  const text = data.content?.map(c=>c.text||\"\").join(\"\")||\"\";\n  const m = text.match(\/\\{&#91;\\s\\S]*\\}\/);\n  if(!m) throw new Error(\"\u30ec\u30b9\u30dd\u30f3\u30b9\u306e\u89e3\u6790\u306b\u5931\u6557\u3057\u307e\u3057\u305f\");\n  return JSON.parse(m&#91;0]);\n}\n\n\/\/ \u2550\u2550\u2550 \u30db\u30a4\u30fc\u30eb\u30ad\u30e3\u30f3\u30d0\u30b9 \u2550\u2550\u2550\nfunction ChartCanvas({ profile }) {\n  const ref = useRef(null);\n  useEffect(()=>{\n    if(!ref.current||!profile)return;\n    const cv=ref.current, ctx=cv.getContext(\"2d\");\n    const W=360,CX=W\/2,CY=W\/2,R=155,BD=\"#e8e4de\";\n    ctx.clearRect(0,0,W,W);\n    \/\/ \u5916\u5468\n    ctx.beginPath(); ctx.arc(CX,CY,R,0,Math.PI*2); ctx.fillStyle=\"#fafaf8\"; ctx.fill(); ctx.strokeStyle=BD; ctx.lineWidth=1; ctx.stroke();\n    \/\/ 12\u661f\u5ea7\u5e2f\n    for(let i=0;i&lt;12;i++){\n      const a1=(i*30-90)*Math.PI\/180, a2=((i+1)*30-90)*Math.PI\/180;\n      ctx.beginPath(); ctx.moveTo(CX+Math.cos(a1)*R*.67,CY+Math.sin(a1)*R*.67);\n      ctx.arc(CX,CY,R*.67,a1,a2); ctx.arc(CX,CY,R,a2,a1,true); ctx.closePath();\n      ctx.fillStyle=`hsla(${i*30},28%,97%,.9)`; ctx.fill(); ctx.strokeStyle=BD; ctx.lineWidth=.7; ctx.stroke();\n      const am=(i*30+15-90)*Math.PI\/180;\n      ctx.fillStyle=\"#9a9288\"; ctx.font=\"11px serif\"; ctx.textAlign=\"center\"; ctx.textBaseline=\"middle\";\n      ctx.fillText(SSYM&#91;i], CX+Math.cos(am)*R*.84, CY+Math.sin(am)*R*.84);\n    }\n    \/\/ \u30cf\u30a6\u30b9\u7dda\n    for(let i=0;i&lt;12;i++){\n      const a=(i*30-90)*Math.PI\/180;\n      ctx.beginPath(); ctx.moveTo(CX+Math.cos(a)*R*.43,CY+Math.sin(a)*R*.43); ctx.lineTo(CX+Math.cos(a)*R*.67,CY+Math.sin(a)*R*.67);\n      ctx.strokeStyle=BD; ctx.lineWidth=.7; ctx.stroke();\n    }\n    \/\/ \u5185\u5186\n    ctx.beginPath(); ctx.arc(CX,CY,R*.43,0,Math.PI*2); ctx.fillStyle=\"#fff\"; ctx.fill(); ctx.strokeStyle=BD; ctx.lineWidth=1; ctx.stroke();\n    \/\/ \u60d1\u661f\n    const PL=&#91;\"Sun\",\"Moon\",\"Mercury\",\"Venus\",\"Mars\",\"Jupiter\",\"Saturn\",\"Uranus\",\"Neptune\",\"Pluto\"], pp=&#91;];\n    PL.forEach(p=>{\n      const deg=profile.pos&#91;p], ang=(deg-90)*Math.PI\/180, pr=R*.55;\n      const px=CX+Math.cos(ang)*pr, py=CY+Math.sin(ang)*pr;\n      pp.push({p,px,py,deg});\n      ctx.beginPath(); ctx.arc(px,py,4,0,Math.PI*2); ctx.fillStyle=PCOL&#91;p]; ctx.fill();\n      ctx.fillStyle=PCOL&#91;p]; ctx.font=\"bold 10px serif\"; ctx.textAlign=\"center\"; ctx.textBaseline=\"middle\";\n      ctx.fillText(PSYM&#91;p], px, py-11);\n    });\n    \/\/ \u30a2\u30b9\u30da\u30af\u30c8\u7dda\n    const ASPS=&#91;{d:0,c:\"rgba(200,168,122,.55)\",w:1.5},{d:120,c:\"rgba(74,140,92,.4)\",w:1},{d:60,c:\"rgba(74,111,165,.3)\",w:.8},{d:90,c:\"rgba(200,100,100,.3)\",w:.8},{d:180,c:\"rgba(160,120,60,.28)\",w:.8}];\n    for(let i=0;i&lt;pp.length;i++) for(let j=i+1;j&lt;pp.length;j++){\n      let df=Math.abs(pp&#91;i].deg-pp&#91;j].deg); if(df>180)df=360-df;\n      for(const a of ASPS){ if(Math.abs(df-a.d)&lt;7){ ctx.beginPath(); ctx.moveTo(pp&#91;i].px,pp&#91;i].py); ctx.lineTo(pp&#91;j].px,pp&#91;j].py); ctx.strokeStyle=a.c; ctx.lineWidth=a.w; ctx.stroke(); break; }}\n    }\n    \/\/ ASC\u7dda\n    const aa=(profile.pos.Ascendant-90)*Math.PI\/180;\n    ctx.beginPath(); ctx.moveTo(CX-Math.cos(aa)*R*.67,CY-Math.sin(aa)*R*.67); ctx.lineTo(CX+Math.cos(aa)*R*.67,CY+Math.sin(aa)*R*.67);\n    ctx.strokeStyle=\"rgba(74,111,165,.5)\"; ctx.lineWidth=1.3; ctx.setLineDash(&#91;4,3]); ctx.stroke(); ctx.setLineDash(&#91;]);\n    \/\/ \u4e2d\u592e\u540d\u524d\n    ctx.fillStyle=\"#9a9288\"; ctx.font=\"10px sans-serif\"; ctx.textAlign=\"center\"; ctx.textBaseline=\"middle\";\n    ctx.fillText(profile.name, CX, CY);\n  }, &#91;profile]);\n  return &lt;canvas ref={ref} width={360} height={360} style={{maxWidth:\"100%\",display:\"block\"}} \/>;\n}\n\n\/\/ \u2550\u2550\u2550 \u661f\u5ea7\u30bf\u30b0\uff08\u30af\u30ea\u30c3\u30af\u53ef\u80fd\uff09 \u2550\u2550\u2550\nfunction SignTag({ planet, pos, onOpen }) {\n  const s = dts(pos&#91;planet]);\n  return (\n    &lt;button onClick={()=>onOpen(planet, s.sign, s.sym)}\n      style={{fontSize:\".76rem\",padding:\"3px 9px\",borderRadius:20,background:\"rgba(200,168,122,.12)\",color:\"#a8885a\",border:\"1px solid rgba(200,168,122,.4)\",cursor:\"pointer\",fontWeight:500,transition:\"all .15s\",whiteSpace:\"nowrap\"}}\n      onMouseEnter={e=>{e.currentTarget.style.background=\"rgba(200,168,122,.28)\";e.currentTarget.style.transform=\"scale(1.06)\";}}\n      onMouseLeave={e=>{e.currentTarget.style.background=\"rgba(200,168,122,.12)\";e.currentTarget.style.transform=\"scale(1)\";}}\n      title=\"\u30af\u30ea\u30c3\u30af\u3067\u8a73\u7d30\u8868\u793a\"\n    >{s.sym} {s.sign}&lt;\/button>\n  );\n}\n\n\/\/ \u2550\u2550\u2550 \u661f\u5ea7\u30dd\u30c3\u30d7\u30a2\u30c3\u30d7 \u2550\u2550\u2550\nfunction SignPopup({ planet, signName, signSym, onClose }) {\n  const &#91;data, setData] = useState(null);\n  const &#91;err,  setErr]  = useState(null);\n  useEffect(()=>{\n    setData(null); setErr(null);\n    callClaude(\n      `\u897f\u6d0b\u5360\u661f\u8853\u306b\u304a\u3044\u3066\u3001${PJP&#91;planet]}\u304c${signName}\u306b\u3042\u308b\u4eba\u306e\u7279\u5fb4\u3092\u65e5\u672c\u8a9e\u3067\u6559\u3048\u3066\u304f\u3060\u3055\u3044\u3002\\n` +\n      `JSON\u306e\u307f\u3067\u8fd4\u3057\u3066\u304f\u3060\u3055\u3044\uff08\u8aac\u660e\u30fb\u30b3\u30fc\u30c9\u30d6\u30ed\u30c3\u30af\u4e0d\u8981\uff09\uff1a\\n` +\n      `{\"element\":\"\u706b\",\"quality\":\"\u6d3b\u52d5\u5bae\",\"ruler\":\"\u706b\u661f\",\"keywords\":&#91;\"\u60c5\u71b1\u7684\",\"\u884c\u52d5\u529b\",\"\u76f4\u611f\",\"\u30ea\u30fc\u30c0\u30fc\u30b7\u30c3\u30d7\",\"\u77ed\u6c17\"],\"personality\":\"\u6027\u683c\u306e\u7279\u5fb4\uff08100\u301c130\u5b57\uff09\",\"strength\":\"\u5f37\u307f\uff0860\u301c80\u5b57\uff09\",\"weakness\":\"\u5f31\u307f\u30fb\u8ab2\u984c\uff0860\u301c80\u5b57\uff09\",\"advice\":\"\u30a2\u30c9\u30d0\u30a4\u30b9\uff0860\u301c80\u5b57\uff09\"}`\n    ).then(setData).catch(e=>setErr(e.message));\n  }, &#91;planet, signName]);\n\n  return (\n    &lt;div onClick={e=>e.target===e.currentTarget&amp;&amp;onClose()} style={{position:\"fixed\",inset:0,zIndex:9999,background:\"rgba(26,24,20,.42)\",backdropFilter:\"blur(3px)\",display:\"flex\",alignItems:\"center\",justifyContent:\"center\",padding:20}}>\n      &lt;div style={{background:\"#fff\",borderRadius:20,maxWidth:480,width:\"100%\",boxShadow:\"0 24px 80px rgba(26,24,20,.22)\",overflow:\"hidden\"}}>\n        {\/* \u30d8\u30c3\u30c0\u30fc *\/}\n        &lt;div style={{position:\"relative\",padding:\"26px 26px 18px\",borderBottom:\"1px solid #ede9e2\"}}>\n          &lt;div style={{position:\"absolute\",top:0,left:0,right:0,height:3,background:PACC&#91;planet]||\"#c8a87a\"}} \/>\n          &lt;div style={{fontSize:\".7rem\",letterSpacing:\".18em\",textTransform:\"uppercase\",color:\"#9a9288\",marginBottom:5}}>{PJP&#91;planet]}\u661f\u5ea7&lt;\/div>\n          &lt;div style={{display:\"flex\",alignItems:\"center\",gap:12}}>\n            &lt;span style={{fontSize:\"2rem\"}}>{signSym}&lt;\/span>\n            &lt;div>\n              &lt;div style={{fontFamily:\"Georgia,serif\",fontSize:\"1.5rem\",color:\"#1a1814\"}}>{signName}&lt;\/div>\n              &lt;div style={{fontSize:\".82rem\",color:\"#9a9288\",marginTop:3}}>\u306e\u7279\u5fb4&lt;\/div>\n            &lt;\/div>\n          &lt;\/div>\n          &lt;button onClick={onClose} style={{position:\"absolute\",top:14,right:14,width:28,height:28,borderRadius:\"50%\",background:\"#f2f0ed\",border:\"none\",cursor:\"pointer\",color:\"#9a9288\",fontSize:\".9rem\"}}>\u2715&lt;\/button>\n        &lt;\/div>\n        {\/* \u30dc\u30c7\u30a3 *\/}\n        &lt;div style={{padding:\"20px 26px 26px\",maxHeight:\"68vh\",overflowY:\"auto\"}}>\n          {!data&amp;&amp;!err&amp;&amp;&lt;div style={{textAlign:\"center\",padding:\"30px 0\"}}>&lt;div style={{width:32,height:32,margin:\"0 auto 12px\",border:\"2px solid #e8e4de\",borderTopColor:\"#c8a87a\",borderRadius:\"50%\",animation:\"spin 1s linear infinite\"}} \/>&lt;div style={{fontSize:\".85rem\",color:\"#9a9288\"}}>\u8aad\u307f\u8fbc\u3093\u3067\u3044\u307e\u3059\u2026&lt;\/div>&lt;\/div>}\n          {err&amp;&amp;&lt;div style={{color:\"#a04040\",fontSize:\".85rem\",padding:\"16px 0\"}}>\u53d6\u5f97\u306b\u5931\u6557\u3057\u307e\u3057\u305f\uff1a{err}&lt;\/div>}\n          {data&amp;&amp;&lt;>\n            &lt;div style={{display:\"grid\",gridTemplateColumns:\"1fr 1fr\",gap:9,marginBottom:13}}>\n              {&#91;&#91;\"\u30a8\u30ec\u30e1\u30f3\u30c8\",data.element],&#91;\"\u30af\u30aa\u30ea\u30c6\u30a3\",data.quality],&#91;\"\u652f\u914d\u661f\",data.ruler],&#91;\"\u30ad\u30fc\u30ef\u30fc\u30c9\",(data.keywords||&#91;]).slice(0,3).join(\" \u00b7 \")]].map((&#91;l,v])=>(\n                &lt;div key={l} style={{background:\"#f8f7f5\",borderRadius:9,padding:\"10px 13px\",border:\"1px solid #ede9e2\"}}>\n                  &lt;div style={{fontSize:\".66rem\",letterSpacing:\".12em\",textTransform:\"uppercase\",color:\"#9a9288\",marginBottom:3}}>{l}&lt;\/div>\n                  &lt;div style={{fontSize:\".87rem\",color:\"#1a1814\"}}>{v||\"\u2014\"}&lt;\/div>\n                &lt;\/div>\n              ))}\n            &lt;\/div>\n            &lt;div style={{display:\"flex\",flexWrap:\"wrap\",gap:5,marginBottom:14}}>\n              {(data.keywords||&#91;]).map(k=>&lt;span key={k} style={{fontSize:\".75rem\",padding:\"3px 9px\",borderRadius:20,background:\"rgba(200,168,122,.12)\",color:\"#a8885a\",border:\"1px solid rgba(200,168,122,.4)\"}}>{k}&lt;\/span>)}\n            &lt;\/div>\n            {&#91;&#91;\"\u6027\u683c\u306e\u7279\u5fb4\",data.personality],&#91;\"\u5f37\u307f\",data.strength],&#91;\"\u5f31\u307f\u30fb\u8ab2\u984c\",data.weakness],&#91;\"\u30a2\u30c9\u30d0\u30a4\u30b9\",data.advice]].map((&#91;l,v])=>(\n              &lt;div key={l} style={{marginBottom:13}}>\n                &lt;div style={{fontSize:\".71rem\",letterSpacing:\".13em\",textTransform:\"uppercase\",color:\"#9a9288\",marginBottom:5,display:\"flex\",alignItems:\"center\",gap:8}}>\n                  {l}&lt;span style={{flex:1,height:1,background:\"#e8e4de\",display:\"block\"}} \/>\n                &lt;\/div>\n                &lt;div style={{fontSize:\".875rem\",color:\"#4a463e\",lineHeight:1.85,fontWeight:300}}>{v}&lt;\/div>\n              &lt;\/div>\n            ))}\n          &lt;\/>}\n        &lt;\/div>\n      &lt;\/div>\n    &lt;\/div>\n  );\n}\n\n\/\/ \u2550\u2550\u2550 \u30c1\u30e3\u30fc\u30c8\u30d1\u30cd\u30eb\uff08\u672c\u8cea\u30fb\u6027\u683c\u5206\u6790\u4ed8\u304d\uff09 \u2550\u2550\u2550\nfunction ChartPanel({ profile, onOpenPopup }) {\n  const &#91;essence, setEssence] = useState(null);\n  const &#91;essLoading, setEssLoading] = useState(false);\n  const &#91;essErr, setEssErr] = useState(null);\n\n  useEffect(()=>{\n    if(!profile) return;\n    setEssence(null); setEssLoading(true); setEssErr(null);\n    const sun=dts(profile.pos.Sun), moon=dts(profile.pos.Moon), asc=dts(profile.pos.Ascendant);\n    const merc=dts(profile.pos.Mercury), ven=dts(profile.pos.Venus), mars=dts(profile.pos.Mars);\n    callClaude(\n      `\u3042\u306a\u305f\u306f\u897f\u6d0b\u5360\u661f\u8853\u306e\u5c02\u9580\u5bb6\u3067\u3059\u3002\u4ee5\u4e0b\u306e\u51fa\u751f\u30db\u30ed\u30b9\u30b3\u30fc\u30d7\u3092\u3082\u3068\u306b\u3001\u3053\u306e\u4eba\u306e\u672c\u8cea\u30fb\u6027\u683c\u30fb\u4eba\u751f\u30c6\u30fc\u30de\u3092\u8a73\u3057\u304f\u65e5\u672c\u8a9e\u3067\u9451\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002\\n\\n` +\n      `\u3010\u30db\u30ed\u30b9\u30b3\u30fc\u30d7\u30c7\u30fc\u30bf\u3011\\n` +\n      `\u540d\u524d: ${profile.name}\\n` +\n      `\u592a\u967d: ${sun.sign} (${sun.within}\u00b0)\\n` +\n      `\u6708: ${moon.sign} (${moon.within}\u00b0)\\n` +\n      `\u30a2\u30bb\u30f3\u30c0\u30f3\u30c8: ${asc.sign}\\n` +\n      `\u6c34\u661f: ${merc.sign} \/ \u91d1\u661f: ${ven.sign} \/ \u706b\u661f: ${mars.sign}\\n\\n` +\n      `JSON\u306e\u307f\u3067\u8fd4\u3057\u3066\u304f\u3060\u3055\u3044\uff08\u8aac\u660e\u30fb\u30b3\u30fc\u30c9\u30d6\u30ed\u30c3\u30af\u4e0d\u8981\uff09:\\n` +\n      `{\"essence\":\"\u3053\u306e\u4eba\u306e\u672c\u8cea\u30fb\u9b42\u306e\u50be\u5411\uff08150\u301c200\u5b57\uff09\",\"personality\":\"\u65e5\u5e38\u7684\u306a\u6027\u683c\u30fb\u632f\u308b\u821e\u3044\uff08150\u301c200\u5b57\uff09\",\"strength\":\"\u6301\u3063\u3066\u751f\u307e\u308c\u305f\u624d\u80fd\u3068\u5f37\u307f\uff08120\u301c150\u5b57\uff09\",\"challenge\":\"\u4eba\u751f\u306e\u8ab2\u984c\u3068\u6210\u9577\u30c6\u30fc\u30de\uff08100\u301c130\u5b57\uff09\",\"love\":\"\u604b\u611b\u30fb\u5bfe\u4eba\u95a2\u4fc2\u306e\u30b9\u30bf\u30a4\u30eb\uff08100\u301c130\u5b57\uff09\",\"career\":\"\u5411\u3044\u3066\u3044\u308b\u4ed5\u4e8b\u30fb\u624d\u80fd\u306e\u6d3b\u304b\u3057\u65b9\uff08100\u301c130\u5b57\uff09\",\"keyword\":&#91;\"\u30ad\u30fc\u30ef\u30fc\u30c91\",\"\u30ad\u30fc\u30ef\u30fc\u30c92\",\"\u30ad\u30fc\u30ef\u30fc\u30c93\",\"\u30ad\u30fc\u30ef\u30fc\u30c94\",\"\u30ad\u30fc\u30ef\u30fc\u30c95\"]}`\n    ).then(d=>{ setEssence(d); setEssLoading(false); }).catch(e=>{ setEssErr(e.message); setEssLoading(false); });\n  }, &#91;profile]);\n\n  if(!profile) return (\n    &lt;div style={{textAlign:\"center\",padding:\"76px 20px\"}}>\n      &lt;span style={{fontSize:\"2.2rem\",opacity:.18,display:\"block\",marginBottom:14}}>\u2b21&lt;\/span>\n      &lt;div style={{fontSize:\".93rem\",color:\"#9a9288\"}}>\u51fa\u751f\u60c5\u5831\u3092\u5165\u529b\u3057\u3066\u30db\u30ed\u30b9\u30b3\u30fc\u30d7\u3092\u751f\u6210\u3057\u3066\u304f\u3060\u3055\u3044&lt;\/div>\n    &lt;\/div>\n  );\n\n  const PL1=&#91;\"Sun\",\"Moon\",\"Mercury\",\"Venus\",\"Mars\"];\n  const PL2=&#91;\"Jupiter\",\"Saturn\",\"Uranus\",\"Neptune\",\"Pluto\"];\n\n  return (\n    &lt;div>\n      {\/* \u30c1\u30e3\u30fc\u30c8\u30e9\u30d9\u30eb *\/}\n      &lt;SectLabel>{profile.name} \u306e\u30cd\u30a4\u30bf\u30eb\u30c1\u30e3\u30fc\u30c8 \u2014 {profile.dateStr}&lt;\/SectLabel>\n\n      {\/* \u30c1\u30e3\u30fc\u30c8\u672c\u4f53 *\/}\n      &lt;div style={{display:\"grid\",gridTemplateColumns:\"1fr 290px\",gap:20,marginBottom:28}}>\n        &lt;div style={{background:\"#fff\",border:\"1px solid #ede9e2\",borderRadius:16,padding:22,boxShadow:\"0 2px 24px rgba(26,24,20,.07)\",display:\"flex\",alignItems:\"center\",justifyContent:\"center\"}}>\n          &lt;ChartCanvas profile={profile} \/>\n        &lt;\/div>\n        &lt;div style={{display:\"flex\",flexDirection:\"column\",gap:13}}>\n          {&#91;&#91;\"\u500b\u4eba\u5929\u4f53\",PL1],&#91;\"\u793e\u4f1a\u30fb\u4e16\u4ee3\u5929\u4f53\",PL2]].map((&#91;title,pl])=>(\n            &lt;PlanetCard key={title} title={title}>\n              {pl.map(p=>(\n                &lt;div key={p} style={{display:\"flex\",alignItems:\"center\",justifyContent:\"space-between\",padding:\"5px 0\",borderBottom:\"1px solid #ede9e2\"}}>\n                  &lt;div style={{fontSize:\".85rem\",color:\"#4a463e\",display:\"flex\",alignItems:\"center\",gap:7}}>\n                    &lt;span style={{color:PCOL&#91;p],fontSize:\".95rem\",width:16,textAlign:\"center\"}}>{PSYM&#91;p]}&lt;\/span>{PJP&#91;p]}\n                  &lt;\/div>\n                  &lt;SignTag planet={p} pos={profile.pos} onOpen={onOpenPopup} \/>\n                &lt;\/div>\n              ))}\n            &lt;\/PlanetCard>\n          ))}\n          &lt;PlanetCard title=\"\u30a2\u30f3\u30b0\u30eb\">\n            {&#91;&#91;\"ASC\uff08\u4e0a\u6607\u70b9\uff09\",profile.pos.Ascendant],&#91;\"MC\uff08\u5929\u9802\uff09\",(profile.pos.Ascendant+270)%360]].map((&#91;lbl,deg],i)=>{\n              const s=dts(deg);\n              return &lt;div key={lbl} style={{display:\"flex\",alignItems:\"center\",justifyContent:\"space-between\",padding:\"5px 0\",borderBottom:i===0?\"1px solid #ede9e2\":\"none\"}}>\n                &lt;div style={{fontSize:\".85rem\",color:\"#4a463e\"}}>{lbl}&lt;\/div>\n                &lt;span style={{fontSize:\".76rem\",padding:\"3px 9px\",borderRadius:20,background:\"rgba(200,168,122,.12)\",color:\"#a8885a\",border:\"1px solid rgba(200,168,122,.4)\",fontWeight:500}}>{s.sym} {s.sign}&lt;\/span>\n              &lt;\/div>;\n            })}\n          &lt;\/PlanetCard>\n          &lt;div style={{fontSize:\".72rem\",color:\"#9a9288\",textAlign:\"center\",lineHeight:1.7,padding:\"4px 0\"}}>\n            \u661f\u5ea7\u30bf\u30b0\u3092\u30af\u30ea\u30c3\u30af\u3059\u308b\u3068&lt;br\/>\u305d\u306e\u60d1\u661f\u00d7\u661f\u5ea7\u306e\u7279\u5fb4\u304c\u8868\u793a\u3055\u308c\u307e\u3059\n          &lt;\/div>\n        &lt;\/div>\n      &lt;\/div>\n\n      {\/* \u2500\u2500 \u672c\u8cea\u30fb\u6027\u683c\u5206\u6790\u30bb\u30af\u30b7\u30e7\u30f3 \u2500\u2500 *\/}\n      &lt;SectLabel>\u30db\u30ed\u30b9\u30b3\u30fc\u30d7\u304c\u8a9e\u308b \u3042\u306a\u305f\u306e\u672c\u8cea&lt;\/SectLabel>\n\n      {essLoading &amp;&amp; (\n        &lt;div style={{textAlign:\"center\",padding:\"48px 0\"}}>\n          &lt;div style={{width:38,height:38,margin:\"0 auto 14px\",border:\"2px solid #e8e4de\",borderTopColor:\"#c8a87a\",borderRadius:\"50%\",animation:\"spin 1s linear infinite\"}} \/>\n          &lt;div style={{fontSize:\".88rem\",color:\"#9a9288\"}}>\u661f\u3005\u304b\u3089\u3042\u306a\u305f\u306e\u672c\u8cea\u3092\u8aad\u307f\u53d6\u3063\u3066\u3044\u307e\u3059\u2026&lt;\/div>\n        &lt;\/div>\n      )}\n      {essErr &amp;&amp; &lt;div style={{padding:\"14px 18px\",background:\"#fef8f8\",border:\"1px solid #f0d0d0\",borderRadius:9,fontSize:\".83rem\",color:\"#a04040\"}}>\u53d6\u5f97\u306b\u5931\u6557\u3057\u307e\u3057\u305f\uff1a{essErr}&lt;\/div>}\n      {essence &amp;&amp; (\n        &lt;div>\n          {\/* \u30ad\u30fc\u30ef\u30fc\u30c9\u30d0\u30c3\u30b8 *\/}\n          {essence.keyword?.length > 0 &amp;&amp; (\n            &lt;div style={{display:\"flex\",flexWrap:\"wrap\",gap:8,marginBottom:22}}>\n              {essence.keyword.map((k,i)=>(\n                &lt;span key={i} style={{fontSize:\".82rem\",padding:\"5px 14px\",borderRadius:20,background:\"rgba(200,168,122,.1)\",color:\"#a8885a\",border:\"1px solid rgba(200,168,122,.35)\",fontWeight:500}}>{k}&lt;\/span>\n              ))}\n            &lt;\/div>\n          )}\n          {\/* \u5206\u6790\u30ab\u30fc\u30c9 *\/}\n          &lt;div style={{display:\"grid\",gridTemplateColumns:\"1fr 1fr\",gap:14}}>\n            {&#91;\n              {key:\"essence\", label:\"\u672c\u8cea\u30fb\u9b42\u306e\u50be\u5411\", bar:\"linear-gradient(90deg,#c89840,#e8c070)\", dot:\"#c89840\", full:true},\n              {key:\"personality\", label:\"\u65e5\u5e38\u7684\u306a\u6027\u683c\", bar:\"linear-gradient(90deg,#7090c0,#a0b8e0)\", dot:\"#7090c0\", full:true},\n              {key:\"strength\",   label:\"\u624d\u80fd\u3068\u5f37\u307f\",   bar:\"linear-gradient(90deg,#40a890,#70d0b0)\", dot:\"#40a890\"},\n              {key:\"challenge\",  label:\"\u4eba\u751f\u306e\u8ab2\u984c\",   bar:\"linear-gradient(90deg,#d07890,#f0a8b8)\", dot:\"#d07890\"},\n              {key:\"love\",       label:\"\u604b\u611b\u30fb\u5bfe\u4eba\u95a2\u4fc2\",bar:\"linear-gradient(90deg,#e09aaa,#c86478)\", dot:\"#c86478\"},\n              {key:\"career\",     label:\"\u4ed5\u4e8b\u30fb\u624d\u80fd\u306e\u6d3b\u304b\u3057\u65b9\",bar:\"linear-gradient(90deg,#7abd8a,#4a8c5c)\",dot:\"#4a8c5c\"},\n            ].map(({key,label,bar,dot,full})=>(\n              &lt;div key={key} style={{background:\"#fff\",border:\"1px solid #ede9e2\",borderRadius:14,padding:\"20px 22px\",boxShadow:\"0 2px 20px rgba(26,24,20,.06)\",position:\"relative\",overflow:\"hidden\",gridColumn:full?\"1\/-1\":\"auto\"}}>\n                &lt;div style={{position:\"absolute\",top:0,left:0,right:0,height:3,background:bar}} \/>\n                &lt;div style={{fontSize:\".7rem\",letterSpacing:\".15em\",textTransform:\"uppercase\",color:\"#9a9288\",marginBottom:8,display:\"flex\",alignItems:\"center\",gap:7}}>\n                  &lt;span style={{width:5,height:5,borderRadius:\"50%\",background:dot,display:\"inline-block\"}} \/>{label}\n                &lt;\/div>\n                &lt;div style={{fontSize:\".875rem\",color:\"#4a463e\",lineHeight:1.88,fontWeight:300}}>{essence&#91;key]}&lt;\/div>\n              &lt;\/div>\n            ))}\n          &lt;\/div>\n        &lt;\/div>\n      )}\n    &lt;\/div>\n  );\n}\n\n\/\/ \u2550\u2550\u2550 \u904b\u52e2\u30d1\u30cd\u30eb\uff08\u65e5\u4ed8\u6307\u5b9a\uff09 \u2550\u2550\u2550\nfunction FortunePanel({ profile }) {\n  const today = new Date().toISOString().split(\"T\")&#91;0];\n  const &#91;targetDate, setTargetDate] = useState(today);\n  const &#91;readings, setReadings]     = useState(null);\n  const &#91;loading,  setLoading]      = useState(false);\n  const &#91;err,      setErr]          = useState(null);\n  const &#91;queried,  setQueried]      = useState(null); \/\/ \u6700\u5f8c\u306b\u53d6\u5f97\u3057\u305f\u65e5\u4ed8\n\n  const load = useCallback(async (dateStr) => {\n    if(!profile) return;\n    setLoading(true); setReadings(null); setErr(null);\n    const sun=dts(profile.pos.Sun), moon=dts(profile.pos.Moon), asc=dts(profile.pos.Ascendant);\n    const d=new Date(dateStr);\n    const dow=&#91;\"\u65e5\",\"\u6708\",\"\u706b\",\"\u6c34\",\"\u6728\",\"\u91d1\",\"\u571f\"]&#91;d.getDay()];\n    const label=dateStr===today?\"\u4eca\u65e5\":dateStr&lt;today?\"\u904e\u53bb\u306e\u65e5\u4ed8\":\"\u672a\u6765\u306e\u65e5\u4ed8\";\n    try {\n      const result = await callClaude(\n        `\u3042\u306a\u305f\u306f\u897f\u6d0b\u5360\u661f\u8853\u306e\u5c02\u9580\u5bb6\u3067\u3059\u3002\u4ee5\u4e0b\u306e\u51fa\u751f\u30c7\u30fc\u30bf\u3068\u6307\u5b9a\u65e5\u3092\u3082\u3068\u306b\u3001\u305d\u306e\u65e5\u306e\u904b\u52e2\u3092\u65e5\u672c\u8a9e\u3067\u9451\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002\\n\\n` +\n        `\u3010\u51fa\u751f\u30c7\u30fc\u30bf\u3011\\n\u540d\u524d: ${profile.name}\\n\u751f\u5e74\u6708\u65e5: ${profile.dateStr} ${profile.timeStr}\\n\u51fa\u751f\u5730: ${profile.place}\\n\u592a\u967d: ${sun.sign} (${sun.within}\u00b0)\\n\u6708: ${moon.sign}\\n\u30a2\u30bb\u30f3\u30c0\u30f3\u30c8: ${asc.sign}\\n\\n` +\n        `\u3010\u9451\u5b9a\u5bfe\u8c61\u65e5\u3011${dateStr} (${dow}\u66dc\u65e5) \u203b${label}\\n\\n` +\n        `\u3053\u306e\u65e5\u306e\u30c8\u30e9\u30f3\u30b8\u30c3\u30c8\uff08\u79fb\u52d5\u5929\u4f53\uff09\u306e\u5f71\u97ff\u3082\u8003\u616e\u3057\u3066\u30014\u5206\u91ce\u306e\u904b\u52e2\u3092JSON\u306e\u307f\u3067\u8fd4\u3057\u3066\u304f\u3060\u3055\u3044\uff08\u8aac\u660e\u30fb\u30b3\u30fc\u30c9\u30d6\u30ed\u30c3\u30af\u4e0d\u8981\uff09\uff1a\\n` +\n        `{\"date\":\"${dateStr}\",\"summary\":\"\u4e00\u8a00\u7dcf\u8a55\uff0830\u5b57\u4ee5\u5185\uff09\",\"readings\":&#91;{\"area\":\"\u7dcf\u5408\u904b\",\"title\":\"\u898b\u51fa\u3057\uff0815\u5b57\u4ee5\u5185\uff09\",\"text\":\"\u9451\u5b9a\u6587\uff08150\u301c200\u5b57\uff09\",\"stars\":4,\"lucky\":&#91;\"\u30e9\u30c3\u30ad\u30fc\u30ab\u30e9\u30fc\uff1a\u25cb\u25cb\",\"\u30e9\u30c3\u30ad\u30fc\u30ca\u30f3\u30d0\u30fc\uff1a\u25cb\"]},{\"area\":\"\u604b\u611b\u904b\",\"title\":\"\u898b\u51fa\u3057\",\"text\":\"\u9451\u5b9a\u6587\uff08130\u5b57\u524d\u5f8c\uff09\",\"stars\":3,\"lucky\":&#91;]},{\"area\":\"\u4ed5\u4e8b\u30fb\u91d1\u904b\",\"title\":\"\u898b\u51fa\u3057\",\"text\":\"\u9451\u5b9a\u6587\uff08130\u5b57\u524d\u5f8c\uff09\",\"stars\":5,\"lucky\":&#91;]},{\"area\":\"\u5065\u5eb7\u904b\",\"title\":\"\u898b\u51fa\u3057\",\"text\":\"\u9451\u5b9a\u6587\uff08100\u5b57\u524d\u5f8c\uff09\",\"stars\":4,\"lucky\":&#91;]}]}`\n      );\n      setReadings(result); setQueried(dateStr);\n    } catch(e) { setErr(e.message); }\n    finally    { setLoading(false); }\n  }, &#91;profile, today]);\n\n  \/\/ \u521d\u56de\u30fb\u30d7\u30ed\u30d5\u30a3\u30fc\u30eb\u5909\u5316\u6642\u306b\u4eca\u65e5\u306e\u904b\u52e2\u3092\u53d6\u5f97\n  useEffect(()=>{ if(profile) load(today); }, &#91;profile]);\n\n  if(!profile) return (\n    &lt;div style={{textAlign:\"center\",padding:\"76px 20px\"}}>\n      &lt;span style={{fontSize:\"2.2rem\",opacity:.18,display:\"block\",marginBottom:14}}>\u25c8&lt;\/span>\n      &lt;div style={{fontSize:\".93rem\",color:\"#9a9288\"}}>\u51fa\u751f\u60c5\u5831\u3092\u5165\u529b\u3057\u3066\u904b\u52e2\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044&lt;\/div>\n    &lt;\/div>\n  );\n\n  return (\n    &lt;div>\n      {\/* \u65e5\u4ed8\u9078\u629e\u30a8\u30ea\u30a2 *\/}\n      &lt;SectLabel>\u9451\u5b9a\u3059\u308b\u65e5\u4ed8\u3092\u9078\u629e&lt;\/SectLabel>\n      &lt;div style={{background:\"#fff\",border:\"1px solid #ede9e2\",borderRadius:14,padding:\"22px 26px\",boxShadow:\"0 2px 20px rgba(26,24,20,.06)\",marginBottom:28,display:\"flex\",alignItems:\"flex-end\",gap:14,flexWrap:\"wrap\"}}>\n        &lt;div style={{flex:1,minWidth:200}}>\n          &lt;label style={{fontSize:\".72rem\",letterSpacing:\".13em\",textTransform:\"uppercase\",color:\"#9a9288\",fontWeight:500,display:\"block\",marginBottom:7}}>\u65e5\u4ed8&lt;\/label>\n          &lt;input type=\"date\" value={targetDate} onChange={e=>setTargetDate(e.target.value)}\n            style={{width:\"100%\",background:\"#f8f7f5\",border:\"1.5px solid #e8e4de\",borderRadius:9,padding:\"11px 14px\",color:\"#1a1814\",fontFamily:\"inherit\",fontSize:\".93rem\",outline:\"none\",transition:\"border-color .2s\"}}\n            onFocus={e=>{e.target.style.borderColor=\"#c8a87a\";e.target.style.boxShadow=\"0 0 0 3px rgba(200,168,122,.14)\";}}\n            onBlur={e=>{e.target.style.borderColor=\"#e8e4de\";e.target.style.boxShadow=\"none\";}}\n          \/>\n        &lt;\/div>\n        &lt;div style={{display:\"flex\",gap:8,flexWrap:\"wrap\"}}>\n          {&#91;&#91;\"\u4eca\u65e5\",today],&#91;\"\u660e\u65e5\",new Date(Date.now()+86400000).toISOString().split(\"T\")&#91;0]],&#91;\"\u660e\u5f8c\u65e5\",new Date(Date.now()+172800000).toISOString().split(\"T\")&#91;0]]].map((&#91;l,v])=>(\n            &lt;button key={l} onClick={()=>setTargetDate(v)} style={{padding:\"7px 14px\",borderRadius:7,background:targetDate===v?\"rgba(200,168,122,.15)\":\"var(--white,#fff)\",border:`1.5px solid ${targetDate===v?\"#c8a87a\":\"#e8e4de\"}`,color:targetDate===v?\"#a8885a\":\"#9a9288\",cursor:\"pointer\",fontSize:\".8rem\",transition:\"all .2s\",fontFamily:\"inherit\"}}>{l}&lt;\/button>\n          ))}\n        &lt;\/div>\n        &lt;button onClick={()=>load(targetDate)} disabled={loading}\n          style={{padding:\"11px 24px\",background:\"#1a1814\",color:\"#fff\",border:\"none\",borderRadius:9,cursor:loading?\"not-allowed\":\"pointer\",fontSize:\".83rem\",fontWeight:500,letterSpacing:\".08em\",display:\"flex\",alignItems:\"center\",gap:8,transition:\"background .2s\",opacity:loading?.6:1,whiteSpace:\"nowrap\",fontFamily:\"inherit\"}}\n          onMouseEnter={e=>!loading&amp;&amp;(e.currentTarget.style.background=\"#4a463e\")}\n          onMouseLeave={e=>{e.currentTarget.style.background=\"#1a1814\";}}\n        >\n          &lt;span>\u2726&lt;\/span> \u904b\u52e2\u3092\u9451\u5b9a\u3059\u308b\n        &lt;\/button>\n      &lt;\/div>\n\n      {\/* \u30ed\u30fc\u30c7\u30a3\u30f3\u30b0 *\/}\n      {loading &amp;&amp; (\n        &lt;div style={{textAlign:\"center\",padding:\"56px 0\"}}>\n          &lt;div style={{width:38,height:38,margin:\"0 auto 14px\",border:\"2px solid #e8e4de\",borderTopColor:\"#c8a87a\",borderRadius:\"50%\",animation:\"spin 1s linear infinite\"}} \/>\n          &lt;div style={{fontSize:\".88rem\",color:\"#9a9288\"}}>\u661f\u3005\u306b\u554f\u3044\u304b\u3051\u3066\u3044\u307e\u3059\u2026&lt;\/div>\n        &lt;\/div>\n      )}\n\n      {\/* \u30a8\u30e9\u30fc *\/}\n      {err &amp;&amp; &lt;div style={{padding:\"14px 18px\",background:\"#fef8f8\",border:\"1px solid #f0d0d0\",borderRadius:9,fontSize:\".83rem\",color:\"#a04040\"}}>\u30a8\u30e9\u30fc\uff1a{err}&lt;\/div>}\n\n      {\/* \u9451\u5b9a\u7d50\u679c *\/}\n      {readings &amp;&amp; !loading &amp;&amp; (\n        &lt;div>\n          {\/* \u65e5\u4ed8\u30d8\u30c3\u30c0\u30fc *\/}\n          &lt;div style={{display:\"flex\",alignItems:\"center\",justifyContent:\"space-between\",marginBottom:18,flexWrap:\"wrap\",gap:10}}>\n            &lt;div>\n              &lt;div style={{fontFamily:\"Georgia,serif\",fontSize:\"1.25rem\",color:\"#1a1814\"}}>\n                {queried} \u306e\u904b\u52e2\n              &lt;\/div>\n              {readings.summary &amp;&amp; (\n                &lt;div style={{fontSize:\".88rem\",color:\"#a8885a\",marginTop:4,fontStyle:\"italic\"}}>\u300c{readings.summary}\u300d&lt;\/div>\n              )}\n            &lt;\/div>\n            &lt;div style={{fontSize:\".76rem\",color:\"#9a9288\",background:\"#f8f7f5\",border:\"1px solid #e8e4de\",borderRadius:7,padding:\"5px 12px\"}}>\n              {profile.name} \u00b7 \u592a\u967d{dts(profile.pos.Sun).sym}{dts(profile.pos.Sun).sign}\n            &lt;\/div>\n          &lt;\/div>\n\n          {\/* \u904b\u52e2\u30ab\u30fc\u30c9 *\/}\n          &lt;div style={{display:\"grid\",gridTemplateColumns:\"1fr 1fr\",gap:14}}>\n            {(readings.readings||&#91;]).map((r,i)=>(\n              &lt;div key={i} style={{background:\"#fff\",border:\"1px solid #ede9e2\",borderRadius:14,padding:\"20px 22px\",boxShadow:\"0 2px 20px rgba(26,24,20,.06)\",position:\"relative\",overflow:\"hidden\",gridColumn:i===0?\"1\/-1\":\"auto\",transition:\"box-shadow .22s,transform .22s\"}}\n                onMouseEnter={e=>{e.currentTarget.style.boxShadow=\"0 8px 40px rgba(26,24,20,.12)\";e.currentTarget.style.transform=\"translateY(-2px)\";}}\n                onMouseLeave={e=>{e.currentTarget.style.boxShadow=\"0 2px 20px rgba(26,24,20,.06)\";e.currentTarget.style.transform=\"translateY(0)\";}}\n              >\n                &lt;div style={{position:\"absolute\",top:0,left:0,right:0,height:3,background:FORTUNE_COLORS&#91;i].bar}} \/>\n                &lt;div style={{fontSize:\".69rem\",letterSpacing:\".15em\",textTransform:\"uppercase\",color:\"#9a9288\",marginBottom:7,display:\"flex\",alignItems:\"center\",gap:7}}>\n                  &lt;span style={{width:5,height:5,borderRadius:\"50%\",background:FORTUNE_COLORS&#91;i].dot,display:\"inline-block\"}} \/>{r.area}\n                &lt;\/div>\n                &lt;div style={{fontFamily:\"Georgia,serif\",fontSize:\"1.05rem\",color:\"#1a1814\",marginBottom:10,lineHeight:1.35}}>{r.title}&lt;\/div>\n                &lt;div style={{fontSize:\".855rem\",color:\"#4a463e\",lineHeight:1.88,fontWeight:300}}>{r.text}&lt;\/div>\n                &lt;div style={{marginTop:12,display:\"flex\",gap:2,alignItems:\"center\"}}>\n                  {\"\u2605\".repeat(r.stars||3).split(\"\").map((_,j)=>&lt;span key={j} style={{color:\"#c8a87a\",fontSize:\".88rem\"}}>\u2605&lt;\/span>)}\n                  {\"\u2606\".repeat(5-(r.stars||3)).split(\"\").map((_,j)=>&lt;span key={j} style={{color:\"#e8e4de\",fontSize:\".88rem\"}}>\u2606&lt;\/span>)}\n                  &lt;span style={{fontSize:\".72rem\",color:\"#9a9288\",marginLeft:7}}>{r.stars||3} \/ 5&lt;\/span>\n                &lt;\/div>\n                {r.lucky?.length>0 &amp;&amp; (\n                  &lt;div style={{marginTop:11,display:\"flex\",gap:6,flexWrap:\"wrap\"}}>\n                    {r.lucky.map((l,j)=>&lt;span key={j} style={{fontSize:\".73rem\",padding:\"3px 9px\",borderRadius:20,background:\"rgba(200,168,122,.12)\",color:\"#a8885a\",border:\"1px solid rgba(200,168,122,.4)\"}}>{l}&lt;\/span>)}\n                  &lt;\/div>\n                )}\n              &lt;\/div>\n            ))}\n          &lt;\/div>\n        &lt;\/div>\n      )}\n    &lt;\/div>\n  );\n}\n\n\/\/ \u2550\u2550\u2550 \u5171\u901a\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8 \u2550\u2550\u2550\nfunction SectLabel({children}) {\n  return (\n    &lt;div style={{fontSize:\".71rem\",letterSpacing:\".18em\",textTransform:\"uppercase\",color:\"#9a9288\",margin:\"36px 0 18px\",display:\"flex\",alignItems:\"center\",gap:12}}>\n      {children}&lt;span style={{flex:1,height:1,background:\"#e8e4de\",display:\"block\"}} \/>\n    &lt;\/div>\n  );\n}\nfunction PlanetCard({title,children}) {\n  return (\n    &lt;div style={{background:\"#fff\",border:\"1px solid #ede9e2\",borderRadius:12,padding:\"14px 16px\",boxShadow:\"0 1px 8px rgba(26,24,20,.04)\"}}>\n      &lt;div style={{fontSize:\".69rem\",letterSpacing:\".14em\",textTransform:\"uppercase\",color:\"#9a9288\",marginBottom:9,fontWeight:500}}>{title}&lt;\/div>\n      {children}\n    &lt;\/div>\n  );\n}\n\n\/\/ \u2550\u2550\u2550 \u30e1\u30a4\u30f3\u30a2\u30d7\u30ea \u2550\u2550\u2550\nexport default function App() {\n  const &#91;tab,   setTab]    = useState(\"birth\");\n  const &#91;name,  setName]   = useState(\"\");\n  const &#91;date,  setDate]   = useState(\"1990-06-15\");\n  const &#91;time,  setTime]   = useState(\"14:30\");\n  const &#91;place, setPlace]  = useState(\"\u6771\u4eac\");\n  const &#91;profile, setProfile] = useState(null);\n  const &#91;popup, setPopup]  = useState(null);\n  const &#91;preview, setPreview] = useState(null);\n\n  useEffect(()=>{\n    if(!date) return;\n    const &#91;y,m,d]=date.split(\"-\").map(Number);\n    setPreview(dts(calcDeg(toJD(y,m,d,12,0),\"Sun\")));\n  },&#91;date]);\n\n  function generate() {\n    if(!date){alert(\"\u751f\u5e74\u6708\u65e5\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\");return;}\n    const &#91;y,m,d]=date.split(\"-\").map(Number);\n    const &#91;hh,mn]=(time||\"12:00\").split(\":\").map(Number);\n    const pos=buildPos(y,m,d,hh||12,mn||0);\n    setProfile({name:name||\"\u3042\u306a\u305f\",dateStr:date,timeStr:time,place,pos,y,m,d,hh,mn});\n    setTab(\"chart\");\n  }\n\n  const TABS=&#91;&#91;\"birth\",\"\u51fa\u751f\u60c5\u5831\"],&#91;\"chart\",\"\u30c1\u30e3\u30fc\u30c8\"],&#91;\"fortune\",\"\u904b\u52e2\"]];\n\n  return (\n    &lt;div style={{background:\"#f8f7f5\",minHeight:\"100vh\",fontFamily:\"'DM Sans',sans-serif\",fontWeight:300,WebkitFontSmoothing:\"antialiased\"}}>\n      &lt;style>{`\n        @import url('https:\/\/fonts.googleapis.com\/css2?family=DM+Sans:wght@300;400;500&amp;display=swap');\n        @keyframes spin{to{transform:rotate(360deg);}}\n        @keyframes rise{from{opacity:0;transform:translateY(12px);}to{opacity:1;transform:translateY(0);}}\n        *{box-sizing:border-box;} button{font-family:inherit;}\n        @media(max-width:620px){\n          .chart-grid{grid-template-columns:1fr !important;}\n          .essence-grid{grid-template-columns:1fr !important;}\n          .fortune-grid{grid-template-columns:1fr !important;}\n          .birth-grid{grid-template-columns:1fr !important;}\n        }\n      `}&lt;\/style>\n\n      &lt;div style={{maxWidth:860,margin:\"0 auto\",padding:\"0 20px 100px\"}}>\n\n        {\/* \u30d8\u30c3\u30c0\u30fc *\/}\n        &lt;div style={{padding:\"46px 0 22px\",display:\"flex\",alignItems:\"flex-end\",justifyContent:\"space-between\",borderBottom:\"1px solid #e8e4de\"}}>\n          &lt;div>\n            &lt;div style={{fontFamily:\"Georgia,serif\",fontSize:\"2.2rem\",fontWeight:400,letterSpacing:\".06em\",color:\"#1a1814\"}}>\n              AS&lt;em style={{color:\"#a8885a\",fontStyle:\"italic\"}}>tra&lt;\/em>\n            &lt;\/div>\n            &lt;div style={{fontSize:\".78rem\",color:\"#9a9288\",letterSpacing:\".14em\",textTransform:\"uppercase\",marginTop:6}}>\u897f\u6d0b\u5360\u661f\u8853 \u2014 \u661f\u8aad\u307f\u30db\u30ed\u30b9\u30b3\u30fc\u30d7&lt;\/div>\n          &lt;\/div>\n          &lt;div style={{opacity:.28,fontSize:\"1.1rem\",letterSpacing:6,paddingBottom:4}}>\u2609 \u263d \u263f \u2640 \u2642&lt;\/div>\n        &lt;\/div>\n\n        {\/* \u30ca\u30d3 *\/}\n        &lt;div style={{display:\"flex\",borderBottom:\"1px solid #e8e4de\"}}>\n          {TABS.map((&#91;k,l])=>(\n            &lt;button key={k} onClick={()=>setTab(k)} style={{padding:\"14px 22px\",background:\"none\",border:\"none\",fontSize:\".82rem\",fontWeight:400,letterSpacing:\".1em\",textTransform:\"uppercase\",color:tab===k?\"#1a1814\":\"#9a9288\",cursor:\"pointer\",position:\"relative\",transition:\"color .2s\"}}>\n              {l}\n              {tab===k&amp;&amp;&lt;span style={{position:\"absolute\",bottom:-1,left:0,right:0,height:2,background:\"#a8885a\",display:\"block\"}} \/>}\n            &lt;\/button>\n          ))}\n        &lt;\/div>\n\n        {\/* \u30d1\u30cd\u30eb\uff1a\u51fa\u751f\u60c5\u5831 *\/}\n        {tab===\"birth\" &amp;&amp; (\n          &lt;div style={{animation:\"rise .4s cubic-bezier(.16,1,.3,1)\"}}>\n            &lt;SectLabel>\u3042\u306a\u305f\u306e\u30c7\u30fc\u30bf\u3092\u5165\u529b&lt;\/SectLabel>\n            &lt;div style={{background:\"#fff\",border:\"1px solid #ede9e2\",borderRadius:16,padding:\"32px 32px 36px\",boxShadow:\"0 2px 24px rgba(26,24,20,.07)\"}}>\n              &lt;div style={{fontFamily:\"Georgia,serif\",fontSize:\"1.35rem\",marginBottom:7,lineHeight:1.4}}>\n                \u661f\u306f\u3042\u306a\u305f\u304c\u751f\u307e\u308c\u305f&lt;em style={{color:\"#a8885a\",fontStyle:\"italic\"}}>\u77ac\u9593&lt;\/em>\u3092\u899a\u3048\u3066\u3044\u308b\u3002\n              &lt;\/div>\n              &lt;div style={{fontSize:\".86rem\",color:\"#9a9288\",marginBottom:28,lineHeight:1.75}}>\u51fa\u751f\u65e5\u6642\u3068\u5834\u6240\u3092\u5165\u529b\u3059\u308b\u3068\u3001\u3042\u306a\u305f\u3060\u3051\u306e\u30db\u30ed\u30b9\u30b3\u30fc\u30d7\u3092\u751f\u6210\u3057\u307e\u3059\u3002&lt;\/div>\n              &lt;div className=\"birth-grid\" style={{display:\"grid\",gridTemplateColumns:\"1fr 1fr\",gap:\"17px 22px\",marginBottom:20}}>\n                {&#91;\n                  &#91;\"\u304a\u540d\u524d\",\"text\",name,setName,\"\u5c71\u7530 \u592a\u90ce\",null],\n                  &#91;\"\u751f\u5e74\u6708\u65e5\",\"date\",date,setDate,null,null],\n                  &#91;\"\u51fa\u751f\u6642\u523b\",\"time\",time,setTime,null,\"\u4e0d\u660e\u306e\u5834\u5408\u306f 12:00 \u3092\u5165\u529b\"],\n                  &#91;\"\u51fa\u751f\u5730\",\"text\",place,setPlace,\"\u6771\u4eac\",null],\n                ].map((&#91;lbl,type,val,setter,ph,hint])=>(\n                  &lt;div key={lbl} style={{display:\"flex\",flexDirection:\"column\",gap:6}}>\n                    &lt;label style={{fontSize:\".72rem\",letterSpacing:\".13em\",textTransform:\"uppercase\",color:\"#9a9288\",fontWeight:500}}>{lbl}&lt;\/label>\n                    &lt;input type={type} value={val} onChange={e=>setter(e.target.value)} placeholder={ph||\"\"}\n                      style={{background:\"#f8f7f5\",border:\"1.5px solid #e8e4de\",borderRadius:9,padding:\"11px 14px\",color:\"#1a1814\",fontFamily:\"inherit\",fontSize:\".93rem\",fontWeight:300,outline:\"none\",transition:\"border-color .2s,box-shadow .2s\"}}\n                      onFocus={e=>{e.target.style.borderColor=\"#c8a87a\";e.target.style.boxShadow=\"0 0 0 3px rgba(200,168,122,.14)\";}}\n                      onBlur={e=>{e.target.style.borderColor=\"#e8e4de\";e.target.style.boxShadow=\"none\";}}\n                    \/>\n                    {hint&amp;&amp;&lt;span style={{fontSize:\".73rem\",color:\"#9a9288\"}}>{hint}&lt;\/span>}\n                  &lt;\/div>\n                ))}\n              &lt;\/div>\n              {preview&amp;&amp;(\n                &lt;div style={{marginTop:4,marginBottom:20,padding:\"13px 17px\",background:\"rgba(200,168,122,.1)\",border:\"1px solid rgba(200,168,122,.38)\",borderRadius:9,display:\"flex\",alignItems:\"center\",gap:12}}>\n                  &lt;span style={{fontSize:\"1.7rem\"}}>{preview.sym}&lt;\/span>\n                  &lt;div>\n                    &lt;div style={{fontFamily:\"Georgia,serif\",fontSize:\"1rem\"}}>{preview.sign}&lt;\/div>\n                    &lt;div style={{fontSize:\".77rem\",color:\"#9a9288\",marginTop:2}}>\u592a\u967d\u661f\u5ea7: {preview.sign} ({preview.within}\u00b0)&lt;\/div>\n                  &lt;\/div>\n                &lt;\/div>\n              )}\n              &lt;button onClick={generate}\n                style={{width:\"100%\",padding:\"14px\",background:\"#1a1814\",color:\"#fff\",border:\"none\",borderRadius:9,cursor:\"pointer\",fontSize:\".85rem\",fontWeight:500,letterSpacing:\".12em\",textTransform:\"uppercase\",display:\"flex\",alignItems:\"center\",justifyContent:\"center\",gap:9,transition:\"background .2s,transform .15s\"}}\n                onMouseEnter={e=>e.currentTarget.style.background=\"#4a463e\"}\n                onMouseLeave={e=>e.currentTarget.style.background=\"#1a1814\"}\n              >&lt;span>\u2726&lt;\/span> \u30db\u30ed\u30b9\u30b3\u30fc\u30d7\u3092\u751f\u6210\u3059\u308b&lt;\/button>\n            &lt;\/div>\n            {profile&amp;&amp;(\n              &lt;div style={{display:\"flex\",alignItems:\"center\",gap:10,padding:\"10px 15px\",background:\"#fff\",border:\"1px solid #ede9e2\",borderRadius:9,marginTop:18,boxShadow:\"0 1px 6px rgba(26,24,20,.05)\"}}>\n                &lt;div style={{width:30,height:30,borderRadius:\"50%\",background:\"rgba(200,168,122,.12)\",border:\"1px solid rgba(200,168,122,.4)\",display:\"flex\",alignItems:\"center\",justifyContent:\"center\",fontSize:\".85rem\",flexShrink:0}}>\u2609&lt;\/div>\n                &lt;div>\n                  &lt;div style={{fontSize:\".86rem\",fontWeight:500}}>{profile.name}&lt;\/div>\n                  &lt;div style={{fontSize:\".76rem\",color:\"#9a9288\",marginTop:1}}>{profile.dateStr} \u00b7 {profile.place} \u00b7 \u592a\u967d: {dts(profile.pos.Sun).sym}{dts(profile.pos.Sun).sign}&lt;\/div>\n                &lt;\/div>\n              &lt;\/div>\n            )}\n          &lt;\/div>\n        )}\n\n        {\/* \u30d1\u30cd\u30eb\uff1a\u30c1\u30e3\u30fc\u30c8 *\/}\n        {tab===\"chart\" &amp;&amp; (\n          &lt;div style={{animation:\"rise .4s cubic-bezier(.16,1,.3,1)\"}}>\n            &lt;ChartPanel profile={profile} onOpenPopup={(planet,signName,signSym)=>setPopup({planet,signName,signSym})} \/>\n          &lt;\/div>\n        )}\n\n        {\/* \u30d1\u30cd\u30eb\uff1a\u904b\u52e2 *\/}\n        {tab===\"fortune\" &amp;&amp; (\n          &lt;div style={{animation:\"rise .4s cubic-bezier(.16,1,.3,1)\"}}>\n            &lt;SectLabel>\u904b\u52e2\u9451\u5b9a&lt;\/SectLabel>\n            &lt;FortunePanel profile={profile} \/>\n          &lt;\/div>\n        )}\n\n      &lt;\/div>\n\n      {\/* \u30dd\u30c3\u30d7\u30a2\u30c3\u30d7 *\/}\n      {popup&amp;&amp;&lt;SignPopup planet={popup.planet} signName={popup.signName} signSym={popup.signSym} onClose={()=>setPopup(null)} \/>}\n    &lt;\/div>\n  );\n}<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jin_ogp_image_url":"","_jin_last_featured_id":0,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-236","post","type-post","status-publish","format-standard","hentry","category-1"],"_links":{"self":[{"href":"https:\/\/hikanokurashi.com\/index.php?rest_route=\/wp\/v2\/posts\/236","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/hikanokurashi.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/hikanokurashi.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/hikanokurashi.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/hikanokurashi.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=236"}],"version-history":[{"count":2,"href":"https:\/\/hikanokurashi.com\/index.php?rest_route=\/wp\/v2\/posts\/236\/revisions"}],"predecessor-version":[{"id":238,"href":"https:\/\/hikanokurashi.com\/index.php?rest_route=\/wp\/v2\/posts\/236\/revisions\/238"}],"wp:attachment":[{"href":"https:\/\/hikanokurashi.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=236"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/hikanokurashi.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=236"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/hikanokurashi.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=236"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}