// 赛博宝宝前端（2026-10-21 从 index.html 的内联 <script type="text/babel"> 原样搬出）：App 的面板、故事弹窗、做菜中、探险结算、七夕灯笼、医生来信、成长期、图纸、Toast、公告。
// index.html 按顺序加载 app/*.jsx，前面文件定义的全局（函数、常量、组件）后面的文件直接用。
// App 拆成几段函数，按原来的顺序每次渲染都调用；上一段的局部变量放进 bag 递给下一段（hook 调用顺序不变）。
function renderAppOverlays(bag) {
  const { actionLoading, closeGrowthResolved, blueprintSeen, cookingRecipe, daddyName, doQuickAction, doctorLetter, endingData, finishLootResult, growthPopup,
    growthResolvedPopup, handleAdventureCollect, handleAdventureStart, handleAdventureTowel, handleBuild, handleCook, handleGift, handleRedeem,
    handleStoryClose, isAdventuring, lanternComplete, lanternNeedsMyWish, lanternPanel, lanternStory, lanternSubmitting, lanternWish, lanternWishes,
    lootResult, mamaName, noticeSeen, panel, playPendingStories, pupiSprite, pushSubscribed, pushSupported, refresh, setBlueprintSeen,
    setDoctorLetter, setEndingData, setGrowthPopup, setGrowthResolvedPopup, setLanternPanel, setLanternStory, setLanternWish, setNoticeSeen,
    setPanel, setState, setToast, state, storyEvent, submitLanternWish, subscribePush, toast, unsubscribePush, weatherState } = bag;
  return (<>
      {/* 面板 */}
      {panel === 'feed' && <FeedPanel inventory={state.inventory} coins={state.coins} babyName={state.name || '宝宝'} boughtMealName={state.boughtMealName} craving={state.craving} nextSnackAt={state.nextSnackAt} onClose={() => setPanel(null)} onFeed={id => doQuickAction('/feed', id ? { meal_id: id } : {})} />}
      {panel === 'cook' && <KitchenPanel inventory={state.inventory} coins={state.coins} day={state.day} youAre={state.youAre} yourName={state.yourName} partnerName={state.partnerName} onClose={() => setPanel(null)} onCook={handleCook} onBuild={handleBuild} />}
      {panel === 'adventure' && !isAdventuring && <AdventurePanel adventure={state.adventure} day={state.day} hunger={state.hunger} inventory={state.inventory} backpackSlots={state.backpackSlots} coins={state.coins} towelReserved={state.towelReserved} onClose={() => setPanel(null)} onStart={handleAdventureStart} onCollect={handleAdventureCollect} onToggleTowel={handleAdventureTowel} youAre={state.youAre} yourName={state.yourName} partnerName={state.partnerName} weather={weatherState} />}
      {panel === 'chat' && <ChatPanel day={state.day} stage={state.stage} parentName={state.yourName} babyName={state.name || '宝宝'} onClose={() => setPanel(null)} />}
      {panel === 'comfort' && <ComfortPanel babyName={state.name || '宝宝'} youAre={state.youAre} yourName={state.yourName} partnerName={state.partnerName}
        comfortProgress={state.comfortProgress?.[state.youAre === 'daddy' ? 'daddy' : 'mama'] || 0}
        onClose={() => setPanel(null)}
        onComforted={() => { setPanel(null); refresh(); }} />}
      {panel === 'study' && <StudyPanel inventory={state.inventory} gifts={state.gifts} petPoints={state.petPoints} onClose={() => setPanel(null)} babyName={state.name} parentName={state.yourName} pushSupported={pushSupported} pushSubscribed={pushSubscribed} onSubscribePush={subscribePush} onUnsubscribePush={unsubscribePush}
        isDaddy={state.youAre === 'daddy'} giftCredits={state.giftCredits} otherName={state.partnerName || '另一位家长'}
        onRedeem={handleRedeem} onGift={handleGift} />}
      {panel === 'message' && <MessagePanel youAre={state.youAre} yourName={state.yourName} partnerName={state.partnerName} babyName={state.name} onClose={() => setPanel(null)} />}
      {panel === 'debug' && <DebugPanel state={state} onClose={() => setPanel(null)} onRefresh={refresh} />}

      {/* 故事弹窗 */}
      {storyEvent && <StoryDialog event={storyEvent} onClose={handleStoryClose} parentName={state.yourName} partnerName={state.partnerName} babyName={state.name} youAre={state.youAre} onRefresh={refresh} />}
      {endingData && <EndingScreen data={endingData} onRestart={() => {
        localStorage.removeItem('xz_token');
        setEndingData(null);
        setState(null);
      }} />}

      {/* 做菜中 */}
      {cookingRecipe && (
        <div className="cooking-overlay">
          <div className="cooking-content">
            <div className="cooking-pot">🍳</div>
            <div className="cooking-steam">
              <span className="steam s1">~</span>
              <span className="steam s2">~</span>
              <span className="steam s3">~</span>
            </div>
            <div className="cooking-name">正在做 {cookingRecipe}……</div>
            <div className="cooking-dots"><span>·</span><span>·</span><span>·</span></div>
          </div>
        </div>
      )}

      {/* Loading */}
      {actionLoading && (
        <div className="action-loading-overlay">
          <div className="action-spinner" />
          <div className="action-loading-text">请稍等……</div>
        </div>
      )}

      {/* 探险结算画面 */}
      {lootResult && (
        <div className="loot-modal-overlay" onClick={finishLootResult}>
          <div className="loot-modal" onClick={e => e.stopPropagation()}>
            {lootResult.failed ? (<>
              <h3>😵 探险失败了……</h3>
              <div className="loot-time">探险了 {lootResult.elapsed} 小时</div>
              <div style={{ color: '#c66', fontSize: 14, margin: '12px 0' }}>
                宝宝晕倒被路人送回来了
              </div>
              {lootResult.gotBed && (
                <div style={{ color: '#D79B6D', fontSize: 13, margin: '4px 0', lineHeight: 1.6 }}>🛏️ 好在怀里还抱着一张床回来<br/>✨ 效果：饥饿衰减 -50%！</div>
              )}
              {lootResult.lost?.length > 0 && (<>
                <div style={{ color: '#A08D7D', fontSize: 13, marginBottom: 8 }}>丢失了：</div>
                <div style={{ color: '#c66', fontSize: 14 }}>
                  {lootResult.lost.map((name, i) => <div key={i}>❌ {name}</div>)}
                </div>
              </>)}
            </>) : (<>
              <h3>🎉 探险归来！</h3>
              <div className="loot-time">探险了 {lootResult.elapsed} 小时</div>
              {lootResult.mapSummary?.special && (
                <div className="adv-special-cell">
                  <img src={`${ASSETS}/${ADV_SPECIAL_IMG[lootResult.mapSummary.special.id] || 'items/individual/mistery_item.png'}`} alt={lootResult.mapSummary.special.name} />
                  <div>
                    <span className="tag">特别收获</span>
                    <div className="t">{lootResult.mapSummary.special.name}</div>
                    {lootResult.mapSummary.special.placeName && <div className="w">在「{lootResult.mapSummary.special.placeName}」找到的</div>}
                  </div>
                </div>
              )}
              {lootResult.gotBed && (
                <div style={{ color: '#D79B6D', fontSize: 13, margin: '4px 0', lineHeight: 1.6 }}>🛏️ 这次探险，带回了一张床！<br/>✨ 效果：饥饿衰减 -50%！</div>
              )}
              {/* 拒食回执（蔬菜沙拉），后端已经换好宝宝名 */}
              {(lootResult.mealNotes || []).map((t, i) => (
                <div key={`mn${i}`} style={{ color: '#A08D7D', fontSize: 13, margin: '4px 0' }}>🥗 {t}</div>
              ))}
              {/* 指南针：5 小时没人接，她自己走回来的（后端已换好宝宝名） */}
              {lootResult.selfReturnNote && (
                <div style={{ color: '#7B9A5B', fontSize: 13, margin: '4px 0' }}>🧭 {lootResult.selfReturnNote}</div>
              )}
              {/* 📷 相纸：路上拍的拍立得（贴进当天的日记） */}
              {lootResult.mapSummary?.photo && (
                <div style={{ color: '#6E5A4B', fontSize: 13, margin: '4px 0' }}>📷 在「{lootResult.mapSummary.photo.placeName}」拍了一张拍立得：「{lootResult.mapSummary.photo.say}」<br/><span style={{ color: '#A08D7D', fontSize: 12 }}>今晚会贴进日记里～</span></div>
              )}
              {/* 小信封：路上寄回家的那封信 */}
              {lootResult.mapSummary?.letter?.text && (
                <div style={{ color: '#6E5A4B', fontSize: 13, margin: '6px 0', padding: '8px 10px', background: 'rgba(244,163,184,0.12)', borderRadius: 10, lineHeight: 1.7, textAlign: 'left' }}>💌 路上寄回家的信{lootResult.mapSummary.letter.placeName ? `（在「${lootResult.mapSummary.letter.placeName}」写的）` : ''}：<br/>{lootResult.mapSummary.letter.text}</div>
              )}
              {(() => {
                const LR = window.LootReceipt, { big, rows } = LR.split(lootResult, state);
                return (<>
                  {big.length > 0 && <div className="loot-grid">{big.map((item, i) => (
                    <div className="loot-card" key={i}>
                      {LR.imgOf(ASSETS, item) ? <img src={LR.imgOf(ASSETS, item)} alt={item.name} /> : <div style={{ fontSize: 28 }}>{LR.TYPE_EMOJI[item.type] || '📦'}</div>}
                      <div className="loot-name">{item.name}{item.count > 1 ? ' ×' + item.count : ''}</div>
                      <div className="loot-type">{LR.TYPE_EMOJI[item.type] || ''} {LR.TYPE_NAME[item.type] || item.type}</div>
                      {item.kite && <div className="loot-type" style={{ color: '#C9809A' }}>🪁 风筝带回来的</div>}
                    </div>))}
                  </div>}
                  {rows.length > 0 && <div className="loot-rows">{rows.map((r, i) => (
                    <div className="loot-row" key={i}><span className="loot-row-place">{r.place}</span>
                      <span className="loot-row-items">{r.items.map((it, j) => (
                        <span className="loot-chip" key={j} title={it.name + (it.kite ? '（风筝带回来的）' : '')}>
                          {it.kite && <span className="loot-chip-tag">🪁</span>}<img src={LR.imgOf(ASSETS, it)} alt={it.name} />
                          {it.count > 1 && <span className="loot-chip-n">×{it.count}</span>}{it.who && <span className="loot-chip-who">{it.who}帮捡</span>}
                        </span>))}</span>
                    </div>))}
                  </div>}
                </>);
              })()}
            </>)}
            {lootResult.growthResolved && (
              <div style={{ margin: '16px 0 8px', padding: 12, background: 'rgba(255,200,150,0.2)', borderRadius: 12, textAlign: 'center' }}>
                <img src={`${ASSETS}/story/${lootResult.growthResolved.image}`} alt="" style={{ width: '80%', maxWidth: 280, borderRadius: 12, marginBottom: 8 }} />
                <div style={{ fontSize: 15, fontWeight: 'bold', color: '#D79B6D', marginBottom: 6 }}>{lootResult.growthResolved.title}</div>
                <div style={{ fontSize: 13, color: '#6E5A4B', lineHeight: 1.8 }}>{lootResult.growthResolved.text}</div>
              </div>
            )}
            <button className="loot-close-btn" onClick={finishLootResult}>好的！</button>
          </div>
        </div>
      )}

      {/* 七夕限定：不进回忆册，三个人的愿望只走合作任务 */}
      {lanternStory && (
        <div className="story-overlay">
          <div className="loot-modal lantern-story-card" onClick={e => e.stopPropagation()}>
            <div className="lantern-hero">
              <div className="lantern-baby" style={{ backgroundImage: `url(${ASSETS}/character/pupi/${pupiSprite})` }} />
              <img className="lantern-held" src={`${ASSETS}/furniture/individual/qixi_lantern.png`} alt="许愿灯" />
            </div>
            {lanternStory.step === 'intro' && (<>
              <h3>找到一盏许愿灯！</h3>
              <div style={{ color: '#6E5A4B', lineHeight: 1.8, margin: '12px 0' }}>{state.name || '宝宝'}把灯笼举到你面前：<br/>“{state.yourName || '你'}许个愿吧。”</div>
              <button className="loot-close-btn" onClick={() => setLanternStory({ step: 'wish', babyWish: '' })}>写一个愿望</button>
            </>)}
            {lanternStory.step === 'wish' && (<>
              <h3>{state.yourName || '你的'}愿望</h3>
              <textarea className="lantern-wish-input" value={lanternWish} onChange={e => setLanternWish(e.target.value)} maxLength={120} autoFocus placeholder="写一句想留给这个家的愿望……" />
              <div style={{ textAlign: 'right', color: '#B6A193', fontSize: 11 }}>{lanternWish.length}/120</div>
              <button className="loot-close-btn" disabled={!lanternWish.trim() || lanternSubmitting} onClick={submitLanternWish}>{lanternSubmitting ? '正在点灯……' : '把愿望放进灯里'}</button>
            </>)}
            {lanternStory.step === 'baby' && (<>
              <h3>{state.name || '宝宝'}也许好了</h3>
              <div className="lantern-wishes">
                <div className="lantern-wish"><b>{state.yourName || '你'}</b>{lanternWish.trim()}</div>
                <div className="lantern-wish"><b>{state.name || '宝宝'}</b>{lanternStory.babyWish}</div>
              </div>
              <div style={{ color: '#9A7D69', lineHeight: 1.7 }}>先把灯挂在风铃旁边。<br/>等{state.partnerName || '另一位家长'}也来许愿，它就会亮起来哦。</div>
              <button className="loot-close-btn" onClick={() => { setLanternStory(null); playPendingStories(); }}>挂起来</button>
            </>)}
          </div>
        </div>
      )}

      {lanternPanel && (
        <div className="story-overlay" onClick={() => setLanternPanel(false)}>
          <div className="loot-modal lantern-story-card" onClick={e => e.stopPropagation()}>
            <img src={`${ASSETS}/furniture/individual/qixi_lantern.png`} alt="七夕许愿灯" style={{ width: 82, filter: lanternComplete ? 'drop-shadow(0 0 12px rgba(255,175,80,.75))' : 'saturate(.55) brightness(.72)' }} />
            <h3>七夕许愿灯</h3>
            {lanternComplete ? (
              <div className="lantern-wishes">
                <div className="lantern-wish"><b>{mamaName || '第一位家长'}</b>{lanternWishes.mama || lanternWishes.mama_wish}</div>
                <div className="lantern-wish"><b>{state.name || '宝宝'}</b>{lanternWishes.baby || lanternWishes.baby_wish}</div>
                <div className="lantern-wish"><b>{daddyName || '第二位家长'}</b>{lanternWishes.daddy || lanternWishes.daddy_wish}</div>
              </div>
            ) : lanternNeedsMyWish ? (
              <div style={{ color: '#8E7666', margin: '14px 0', lineHeight: 1.8 }}>{state.name || '宝宝'}把灯笼捡回来了，<br/>还没有人许愿呢。</div>
            ) : <div style={{ color: '#8E7666', margin: '14px 0', lineHeight: 1.8 }}>灯里已经藏好两个愿望。<br/>还在等{state.partnerName || '另一位家长'}许愿哦。</div>}
            {lanternNeedsMyWish
              ? <button className="loot-close-btn" onClick={() => { setLanternPanel(false); setLanternWish(''); setLanternStory({ step: 'intro', babyWish: '' }); }}>去许愿</button>
              : <button className="loot-close-btn" onClick={() => setLanternPanel(false)}>收好</button>}
          </div>
        </div>
      )}

      {/* 医生来信 */}
      {doctorLetter && (
        <div className="story-overlay" onClick={() => setDoctorLetter(null)}>
          <div className="doctor-letter" onClick={e => e.stopPropagation()}>
            <img src="assets/story/hospital.png" alt="" style={{ width: '100%', borderRadius: 12, marginBottom: 12 }} />
            <div style={{ textAlign: 'center', fontSize: 18, fontWeight: 'bold', color: '#6E5A4B', marginBottom: 12 }}>🏥 医生来信</div>
            {doctorLetter}
            <button onClick={() => setDoctorLetter(null)}
              style={{ display: 'block', width: '100%', marginTop: 16, padding: '10px', background: 'linear-gradient(135deg, #D79B6D, #e0ac80)', color: 'white', border: 'none', borderRadius: 12, fontSize: 14, fontWeight: 'bold', cursor: 'pointer' }}>
              知道了……
            </button>
          </div>
        </div>
      )}

      {/* 成长期弹窗 */}
      {growthPopup && (
        <div className="story-overlay" onClick={() => { localStorage.setItem(growthPopup.key, '1'); setGrowthPopup(null); }}>
          <div className="doctor-letter" onClick={e => e.stopPropagation()} style={{ textAlign: 'center' }}>
            <div style={{ fontSize: 48, marginBottom: 8 }}>{growthPopup.icon}</div>
            <div style={{ fontSize: 18, fontWeight: 'bold', color: '#6E5A4B', marginBottom: 12 }}>{growthPopup.title}</div>
            <div style={{ fontSize: 14, color: '#8B7355', lineHeight: 1.8, whiteSpace: 'pre-line', marginBottom: 16 }}>{growthPopup.desc}</div>
            <button onClick={() => { localStorage.setItem(growthPopup.key, '1'); setGrowthPopup(null); }}
              style={{ display: 'block', width: '100%', padding: '10px', background: 'linear-gradient(135deg, #D79B6D, #e0ac80)', color: 'white', border: 'none', borderRadius: 12, fontSize: 14, fontWeight: 'bold', cursor: 'pointer' }}>
              知道啦
            </button>
          </div>
        </div>
      )}

      {growthResolvedPopup && (
        <div className="story-overlay" onClick={closeGrowthResolved}>
          <div className="doctor-letter" onClick={e => e.stopPropagation()} style={{ textAlign: 'center' }}>
            {growthResolvedPopup.image && <img src={`${ASSETS}/story/${growthResolvedPopup.image}`} alt="" style={{ width: '80%', maxWidth: 280, borderRadius: 12, marginBottom: 8 }} />}
            <div style={{ fontSize: 15, fontWeight: 'bold', color: '#D79B6D', marginBottom: 6 }}>{growthResolvedPopup.title}</div>
            <div style={{ fontSize: 13, color: '#6E5A4B', lineHeight: 1.8, whiteSpace: 'pre-line' }}>{growthResolvedPopup.text}</div>
            <button onClick={closeGrowthResolved}
              style={{ display: 'block', width: '100%', marginTop: 16, padding: '10px', background: 'linear-gradient(135deg, #D79B6D, #e0ac80)', color: 'white', border: 'none', borderRadius: 12, fontSize: 14, fontWeight: 'bold', cursor: 'pointer' }}>
              知道啦
            </button>
          </div>
        </div>
      )}

      {/* 图纸解锁：到日子才出现，出现就弹一次（2026-08-03 小玉点单） */}
      {state?.blueprintNotice?.id && blueprintSeen !== state.blueprintNotice.id && (
        <div className="story-overlay" onClick={() => { localStorage.setItem(`xz_blueprint_seen_${state.babyId}`, state.blueprintNotice.id); setBlueprintSeen(state.blueprintNotice.id); }}>
          <div className="doctor-letter" onClick={e => e.stopPropagation()} style={{ textAlign: 'center' }}>
            <div style={{ fontSize: 40, marginBottom: 8 }}>📐</div>
            <div style={{ fontSize: 15, fontWeight: 'bold', color: '#D79B6D', marginBottom: 6 }}>{state.blueprintNotice.title}</div>
            <div style={{ fontSize: 13, color: '#6E5A4B', lineHeight: 1.8, whiteSpace: 'pre-line' }}>{state.blueprintNotice.text}</div>
            <button onClick={() => { localStorage.setItem(`xz_blueprint_seen_${state.babyId}`, state.blueprintNotice.id); setBlueprintSeen(state.blueprintNotice.id); }}
              style={{ display: 'block', width: '100%', marginTop: 16, padding: '10px', background: 'linear-gradient(135deg, #D79B6D, #e0ac80)', color: 'white', border: 'none', borderRadius: 12, fontSize: 14, fontWeight: 'bold', cursor: 'pointer' }}>
              这就去做
            </button>
          </div>
        </div>
      )}

      {/* Toast */}
      {toast && <Toast message={toast} onDone={() => setToast('')} />}
      {/* 全服公告：一个 id 只弹一次，改 id 才会重新弹（2026-07-28） */}
      {state?.notice?.id && noticeSeen !== state.notice.id && (
        <div style={{ position: 'fixed', inset: 0, zIndex: 300, background: 'rgba(0,0,0,0.3)', display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 20 }}
          onClick={e => e.target === e.currentTarget && (localStorage.setItem('xz_notice_seen', state.notice.id), setNoticeSeen(state.notice.id))}>
          <div style={{ background: '#FFFDF9', borderRadius: 20, padding: '20px 20px 14px', maxWidth: 340, width: '100%', border: '1.5px solid #EEDFCC', boxShadow: '0 10px 34px rgba(110,90,75,0.2)' }}>
            <div style={{ fontSize: 16, fontWeight: 'bold', color: '#6E5A4B', marginBottom: 10 }}>📣 {state.notice.title}</div>
            <div style={{ fontSize: 13.5, color: '#7d6b5c', lineHeight: 1.75, whiteSpace: 'pre-wrap' }}>{state.notice.text}</div>
            <button onClick={() => { localStorage.setItem('xz_notice_seen', state.notice.id); setNoticeSeen(state.notice.id); }}
              style={{ marginTop: 14, width: '100%', padding: 11, border: 'none', borderRadius: 12, background: 'linear-gradient(#ffe9c9, #f7d6a8)', color: '#7a5c3a', fontSize: 14, cursor: 'pointer' }}>
              知道啦
            </button>
          </div>
        </div>
      )}
  </>);
}
