// ============================================================================
//  PLAYBOOK APP — Mission Gold visual language throughout
//  Tabs: COVER (poster) / TODAY (daily) / ROAD (overview) / CODE (rules)
// ============================================================================

const { PHASES, CAMPAIGNS, DAY_MENU, QUOTES,
  SEASON_START, SEASON_END,
  STATE_METRICS,
  iso, parseISO, daysBetween, findPhase, dayInPhase,
  weekDates, fmtJp, weekdayJp, weekdayEn,
} = window.PB;

// 親シェル（rowing-rpg-shell）の STATE タブに切替依頼を送る
function openStateTabInShell() {
  try { window.parent.postMessage({ type: "rrpg-open-tab", tab: "state" }, "*"); } catch {}
}

// ─────────────────────────────────────────────────────────────────────────────
//  STATE BRIEF — 4指標サマリー (TODAY タブ内に置く)
// ─────────────────────────────────────────────────────────────────────────────
function StateBrief({ M }) {
  if (!M) return null;
  const hasWarn = (M.warnings || []).length > 0;
  const z = M.hr_zones;
  return (
    <div className={`pb-state-brief ${hasWarn ? "pb-state-brief-warn" : ""}`}>
      <div className="pb-state-brief-head">
        <div className="pb-state-brief-eyebrow">
          <span className="pb-bullet" /> STATE 要約 ／ NOW（見本データ）
        </div>
        <button className="pb-state-brief-link" onClick={openStateTabInShell}>
          STATE タブで詳しく ↗
        </button>
      </div>
      <div className="pb-state-brief-grid">
        <div className="pb-sb-cell">
          <div className="pb-sb-k pb-mono">HOOPER</div>
          <div className="pb-sb-v">{M.hooper.total}<span className="pb-sb-sub">/{M.hooper.max}</span></div>
          <div className="pb-sb-tag pb-mono">{M.hooper.stateLabel}</div>
        </div>
        <div className="pb-sb-cell">
          <div className="pb-sb-k pb-mono">ACWR</div>
          <div className="pb-sb-v">{M.acwr.value}</div>
          <div className="pb-sb-tag pb-mono">{M.acwr.stateLabel}</div>
        </div>
        <div className="pb-sb-cell">
          <div className="pb-sb-k pb-mono">FORM TSB</div>
          <div className="pb-sb-v">{M.tsb.value > 0 ? `+${M.tsb.value}` : M.tsb.value}</div>
          <div className="pb-sb-tag pb-mono">{M.tsb.stateLabel}</div>
        </div>
        <div className="pb-sb-cell">
          <div className="pb-sb-k pb-mono">Z配分 28D</div>
          <div className="pb-sb-v pb-sb-v-sm">{z.actual.z1}/{z.actual.z2}/{z.actual.z3}</div>
          <div className="pb-sb-tag pb-mono">目標 {z.target.z1}/{z.target.z2}/{z.target.z3}</div>
        </div>
      </div>
      {hasWarn && (
        <div className="pb-state-brief-warn-line">
          <span className="pb-mono">⚠ WARN</span> {M.warnings[0].text}
        </div>
      )}
    </div>
  );
}

// ─────────────────────────────────────────────────────────────────────────────
//  Helpers / Hooks
// ─────────────────────────────────────────────────────────────────────────────
// 親シェル(rowing-rpg-shell)に埋め込まれているか
const IS_EMBED = (() => {
  try { return new URLSearchParams(location.search).get("embed") === "1"; }
  catch { return false; }
})();

function useTab() {
  const [tab, setTabState] = React.useState(() => {
    // URLパラメータ tab を最優先（シェルからの初期タブ指定）
    try {
      const urlTab = new URLSearchParams(location.search).get("tab");
      if (urlTab) return urlTab;
    } catch {}
    try { return localStorage.getItem("pb-tab") || "today"; } catch { return "today"; }
  });
  const setTab = (t) => {
    setTabState(t);
    try { localStorage.setItem("pb-tab", t); } catch {}
    window.scrollTo({ top: 0, behavior: "instant" });
  };
  // 親シェルからのタブ切替メッセージを受ける（埋め込み時）
  React.useEffect(() => {
    const handler = (e) => {
      if (e.data && e.data.type === "rrpg-set-tab" && e.data.tab) {
        setTabState(e.data.tab);
        try { localStorage.setItem("pb-tab", e.data.tab); } catch {}
        window.scrollTo({ top: 0, behavior: "instant" });
      }
    };
    window.addEventListener("message", handler);
    return () => window.removeEventListener("message", handler);
  }, []);
  return [tab, setTab];
}

function useToday() {
  // Real today. Snap to dev fallback if outside season for nicer demo.
  const realToday = iso(new Date());
  const fallback = realToday < SEASON_START ? SEASON_START :
                   realToday > SEASON_END ? SEASON_END : realToday;
  return fallback;
}

function useDailyFuel(intervalMs = 6000) {
  const fuels = window.DAILY_FUEL || [];
  // 55件からランダムに10件を選ぶ（ページを開くたびに入れ替え）
  const picks = React.useMemo(() => {
    const idx = fuels.map((_, i) => i);
    for (let i = idx.length - 1; i > 0; i--) {
      const j = Math.floor(Math.random() * (i + 1));
      [idx[i], idx[j]] = [idx[j], idx[i]];
    }
    return idx.slice(0, Math.min(10, idx.length)).map((k) => fuels[k]);
  }, []);
  const [i, setI] = React.useState(0);
  React.useEffect(() => {
    if (picks.length <= 1) return;
    const t = setInterval(() => setI((x) => (x + 1) % picks.length), intervalMs);
    return () => clearInterval(t);
  }, [picks.length]);
  return { fuel: picks[i] || { quote: "", sub: "", src: "" }, idx: i, picks, setI };
}

// ─────────────────────────────────────────────────────────────────────────────
//  TOP BAR
// ─────────────────────────────────────────────────────────────────────────────
function TopBar({ tab, setTab, today }) {
  const d = parseISO(today);
  const u23 = daysBetween(today, "2026-08-23");
  return (
    <div className="pb-topbar">
      <div className="pb-tb-l">
        <div className="pb-mark">T·S</div>
        <div>
          <div className="pb-tb-name">TATSUYA SAKURAMA</div>
          <div className="pb-tb-sub">櫻間 達也 ／ NTT東日本 ／ M1x ／ SENIOR JPN</div>
        </div>
      </div>
      <div className="pb-tb-tabs">
        {[
          ["cover", "COVER", "表紙"],
          ["today", "TODAY", "今日"],
          ["state", "STATE", "状況"],
          ["road", "THE ROAD", "行程"],
          ["code", "THE CODE", "三箇条"],
        ].map(([key, en, jp]) => (
          <button
            key={key}
            className={`pb-tab ${tab === key ? "pb-tab-on" : ""}`}
            onClick={() => setTab(key)}
          >
            <span className="pb-tab-en">{en}</span>
            <span className="pb-tab-jp">{jp}</span>
          </button>
        ))}
      </div>
      <div className="pb-tb-r">
        <div className="pb-tb-meta">
          <div className="pb-tb-k">TODAY</div>
          <div className="pb-tb-v pb-mono">
            {d.getFullYear()}.{String(d.getMonth() + 1).padStart(2, "0")}.{String(d.getDate()).padStart(2, "0")} · {weekdayEn[d.getDay()]}
          </div>
        </div>
        <div className="pb-tb-meta pb-tb-meta-em">
          <div className="pb-tb-k">WCH</div>
          <div className="pb-tb-v pb-mono">
            <span className="pb-red">D-{u23 < 0 ? "DONE" : u23}</span>
          </div>
        </div>
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────────────────────
//  COVER — poster mode
// ─────────────────────────────────────────────────────────────────────────────
function Cover({ today, setTab }) {
  const u23 = Math.max(0, daysBetween(today, "2026-08-23"));
  const wuc = Math.max(0, daysBetween(today, "2026-09-20"));
  const ic  = Math.max(0, daysBetween(today, "2026-05-29"));
  const seasonDays = daysBetween(SEASON_START, SEASON_END) + 1;
  const elapsed = Math.max(0, daysBetween(SEASON_START, today));
  const remaining = Math.max(0, seasonDays - elapsed);

  return (
    <div className="pb-cover">
      <div className="pb-grain" />

      <div className="pb-cover-stamp">
        <div className="pb-stamp-l">
          <div className="pb-mono pb-eyebrow">FILE №</div>
          <div className="pb-mono">SKR-2026/SUM</div>
        </div>
        <div className="pb-stamp-r">
          <div className="pb-mono pb-eyebrow">2km TT / 500m</div>
          <div className="pb-mono">—:—　／　—:—</div>
        </div>
      </div>

      <div className="pb-cover-name">
        <div className="pb-cover-name-row">SAKURAMA</div>
        <div className="pb-cover-name-row pb-cover-outline">TATSUYA</div>
      </div>
      <div className="pb-cover-jp">櫻間 達也 ／ さくらま たつや ／ シニア日本代表</div>

      <div className="pb-cover-headline">
        <div className="pb-cover-h-line">
          <span className="pb-red">{remaining}</span>&nbsp;DAYS
        </div>
        <div className="pb-cover-h-line pb-cover-h-dim">
          TO <span className="pb-strike">REST</span>.
        </div>
        <div className="pb-cover-h-line">
          {remaining}&nbsp;DAYS TO <span className="pb-red">BURN</span>.
        </div>
      </div>

      <div className="pb-cover-foot">
        <div className="pb-cover-foot-col">
          <div className="pb-eyebrow">CAMPAIGN</div>
          <div className="pb-cover-foot-h">2026 SUMMER</div>
          <div className="pb-cover-foot-sub">5月20日 → 9月25日 ／ 18週 ／ 128日</div>
        </div>
        <div className="pb-cover-foot-col">
          <div className="pb-eyebrow">MISSION</div>
          <div className="pb-cover-foot-h">3 STARTS · 3 FLAGS</div>
          <div className="pb-cover-foot-sub">WC1 → 世界選手権 → アジア大会</div>
        </div>
        <div className="pb-cover-foot-col">
          <div className="pb-eyebrow">PEAK</div>
          <div className="pb-cover-foot-h">ONE FULL · TWO ECHOES</div>
          <div className="pb-cover-foot-sub">ダブルピーク：世界選手権 × アジア大会</div>
        </div>
      </div>

      <div className="pb-cover-targets">
        {[
          { en: "WORLD CHAMPS",  jp: "WCH🇳🇱",  d: u23, primary: true },
          { en: "ASIAN GAMES",   jp: "ASIA🇯🇵", d: wuc },
          { en: "WORLD CUP I",   jp: "WC1🇪🇸",  d: ic },
        ].map((t) => (
          <div key={t.en} className={`pb-target ${t.primary ? "pb-target-p" : ""}`}>
            <div className="pb-target-l">
              <div className="pb-target-en">{t.en}</div>
              <div className="pb-target-jp">{t.jp}</div>
            </div>
            <div className="pb-target-r">
              <div className="pb-target-d pb-mono">D-{t.d}</div>
            </div>
          </div>
        ))}
      </div>

      <button className="pb-cover-cta" onClick={() => setTab("today")}>
        <span className="pb-mono">→</span>&nbsp;ENTER TODAY
      </button>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────────────────────
//  TODAY — daily dashboard
// ─────────────────────────────────────────────────────────────────────────────
function Today({ today }) {
  const phase = findPhase(today);
  const dn = phase ? dayInPhase(phase, today) : 0;
  const phaseDay = phase ? `DAY ${dn} / ${phase.days}` : "";
  const phasePct = phase ? Math.min(100, (dn / phase.days) * 100) : 0;

  const todayInfo = DAY_MENU[today] || {};

  // primary countdown — to the soonest upcoming peak race
  const nextPeak = CAMPAIGNS.find((c) => c.targetDate >= today) || CAMPAIGNS[CAMPAIGNS.length - 1];
  const nextD = Math.max(0, daysBetween(today, nextPeak.targetDate));

  const seasonStart = SEASON_START;
  const seasonEnd = SEASON_END;
  const elapsed = Math.max(0, daysBetween(seasonStart, today));
  const total = daysBetween(seasonStart, seasonEnd) + 1;
  const seasonPct = (elapsed / total) * 100;

  const { fuel, idx: fuelIdx, picks: fuelPicks, setI: setFuelI } = useDailyFuel();

  // 週送り（0 = 今週、+1 = 翌週 …）
  const [weekOffset, setWeekOffset] = React.useState(0);
  const weekAnchor = (() => {
    const d = parseISO(today);
    d.setDate(d.getDate() + weekOffset * 7);
    return iso(d);
  })();
  const week = weekDates(weekAnchor);
  const weekLabel =
    weekOffset === 0 ? "THIS WEEK" :
    weekOffset === 1 ? "NEXT WEEK" :
    weekOffset === -1 ? "LAST WEEK" :
    weekOffset > 0 ? `+${weekOffset} WEEKS` : `${weekOffset} WEEKS`;
  const weekLabelJp =
    weekOffset === 0 ? "今週" :
    weekOffset === 1 ? "翌週" :
    weekOffset === -1 ? "前週" :
    weekOffset > 0 ? `${weekOffset}週先` : `${Math.abs(weekOffset)}週前`;
  // SEASON PROGRESS 上の「表示中の週」位置（%）
  const viewPct = Math.max(0, Math.min(100,
    (daysBetween(seasonStart, week[0]) / total) * 100));

  return (
    <div className="pb-today">
      <div className="pb-grain" />

      {/* PRIMARY: countdown hero */}
      <div className="pb-t-hero">
        <div className="pb-t-hero-l">
          <div className="pb-eyebrow"><span className="pb-bullet" /> PRIMARY OBJECTIVE</div>
          <div className="pb-t-hero-h">{nextPeak.nameEn}</div>
          <div className="pb-t-hero-jp">{nextPeak.nameJp} ／ {nextPeak.where}</div>
          <div className="pb-t-hero-role pb-mono">{nextPeak.role}</div>
        </div>
        <div className="pb-t-hero-r">
          <div className="pb-t-cd-num">{nextD}</div>
          <div className="pb-t-cd-stack">
            <div className="pb-t-cd-unit">DAYS</div>
            <div className="pb-t-cd-sub pb-mono">{nextPeak.datesEn}</div>
          </div>
        </div>
      </div>

      {/* 3 targets row */}
      <div className="pb-t-targets">
        {CAMPAIGNS.map((c) => {
          const d = Math.max(0, daysBetween(today, c.targetDate));
          const done = today > c.targetDate;
          const isNext = c.id === nextPeak.id;
          return (
            <div key={c.id} className={`pb-t-tgt ${isNext ? "pb-t-tgt-active" : ""} ${done ? "pb-t-tgt-done" : ""}`}>
              <div className="pb-t-tgt-rank">P{c.rank}</div>
              <div className="pb-t-tgt-mid">
                <div className="pb-t-tgt-name">{c.nameEn}</div>
                <div className="pb-t-tgt-where">{c.where}</div>
                <div className="pb-t-tgt-meta pb-mono">{c.datesEn}</div>
              </div>
              <div className="pb-t-tgt-d">
                <span className="pb-mono pb-t-tgt-d-num">{done ? "✓" : `D-${d}`}</span>
              </div>
            </div>
          );
        })}
      </div>

      {/* STATE BRIEF — 4指標サマリー（クリックで STATE タブへ） */}
      <StateBrief M={STATE_METRICS} />

      {/* TODAY focus card + week */}
      <div className="pb-t-grid">
        <div className="pb-t-todaycard">
          <div className="pb-eyebrow pb-eyebrow-red">TODAY ／ 今日のメニュー</div>
          <div className="pb-t-today-date">
            <span className="pb-mono pb-t-today-iso">{today}</span>
            <span className="pb-t-today-wk">{weekdayJp[parseISO(today).getDay()]}曜</span>
          </div>
          <div className="pb-t-today-menu">
            {todayInfo.menu || (phase ? phase.desc : "OFF")}
          </div>
          {todayInfo.key && <div className="pb-tag pb-tag-key">KEY SESSION ／ 高強度</div>}
          {todayInfo.race && <div className="pb-tag pb-tag-race">RACE DAY ／ 本戦</div>}
          {todayInfo.tag && !todayInfo.key && !todayInfo.race && <div className="pb-tag">{todayInfo.tag}</div>}

          {phase && (
            <div className="pb-t-today-phase">
              <div className="pb-t-today-phase-head">
                <span className="pb-mono pb-eyebrow">CURRENT PHASE</span>
                <span className="pb-mono pb-t-today-phase-day">{phaseDay}</span>
              </div>
              <div className="pb-t-today-phase-row">
                <div className="pb-t-today-phase-emoji">{phase.emoji}</div>
                <div>
                  <div className="pb-t-today-phase-name">{phase.labelEn}</div>
                  <div className="pb-t-today-phase-jp">{phase.label} ／ {phase.desc}</div>
                </div>
              </div>
              <div className="pb-bar">
                <div className={`pb-bar-fill pb-bar-${phase.kind}`} style={{ width: `${phasePct}%` }} />
              </div>
            </div>
          )}
        </div>

        {/* Quote card */}
        <div className="pb-t-quote">
          <div className="pb-eyebrow pb-eyebrow-red">DAILY FUEL ／ 燃料</div>
          <blockquote className="pb-fuel-quote">{fuel.quote}</blockquote>
          {fuel.src && <div className="pb-fuel-src">— {fuel.src}</div>}
          {fuel.sub && <div className="pb-fuel-sub">{fuel.sub}</div>}
          <div className="pb-t-quote-dots pb-fuel-dots">
            {fuelPicks.map((_, i) => (
              <div key={i} className={`pb-dot ${i === fuelIdx ? "pb-dot-on" : ""}`} onClick={() => setFuelI(i)} />
            ))}
          </div>
        </div>
      </div>

      {/* WEEK (週送り) */}
      <div className="pb-t-week">
        <div className="pb-section-head">
          <div className="pb-section-num">02</div>
          <div className="pb-section-titles">
            <div className="pb-section-en">{weekLabel}</div>
            <div className="pb-section-jp">{weekLabelJp}の漕ぎ ／ {fmtJp(week[0])} — {fmtJp(week[6])}</div>
          </div>
          <div className="pb-week-nav">
            <button className="pb-week-btn" onClick={() => setWeekOffset(weekOffset - 1)} aria-label="前の週">◀</button>
            <button className="pb-week-btn pb-week-btn-now" onClick={() => setWeekOffset(0)} disabled={weekOffset === 0}>今週</button>
            <button className="pb-week-btn" onClick={() => setWeekOffset(weekOffset + 1)} aria-label="次の週">▶</button>
          </div>
        </div>
        <div className="pb-week-grid">
          {week.map((d) => {
            const info = DAY_MENU[d] || {};
            const ph = findPhase(d);
            const wd = parseISO(d).getDay();
            const isToday = d === today;
            const isPast = d < today;
            const isTravel = ph && ph.kind === "travel";
            const isCamp = ph && ph.kind === "natl";
            return (
              <div key={d} className={`pb-day ${isToday ? "pb-day-today" : ""} ${isPast ? "pb-day-past" : ""} ${info.key ? "pb-day-key" : ""} ${info.race ? "pb-day-race" : ""}`}>
                <div className="pb-day-bar" style={{ background: ph ? `var(--c-${ph.kind})` : "transparent" }} />
                <div className="pb-day-head">
                  <div className="pb-day-wd">{weekdayEn[wd]}</div>
                  <div className="pb-day-date pb-mono">{fmtJp(d)}</div>
                </div>
                <div className="pb-day-menu">
                  {info.menu || (ph ? ph.label : "—")}
                </div>
                {info.tag && <div className="pb-day-event">{info.emoji ? "" : ""}{info.tag}</div>}
                {info.key && <div className="pb-day-tag">KEY</div>}
                {info.race && <div className="pb-day-tag pb-day-tag-race">RACE</div>}
                {isToday && <div className="pb-day-tag pb-day-tag-now">NOW</div>}
              </div>
            );
          })}
        </div>
        <div className="pb-week-legend">
          <span className="pb-mono">PHASE:</span>
          {(() => {
            // この週に含まれるフェーズ（イベント）を要約表示
            const phs = [...new Set(week.map(d => findPhase(d)).filter(Boolean).map(p => p.id))]
              .map(id => PHASES.find(p => p.id === id));
            return phs.map(p => (
              <span key={p.id} className={`pb-week-leg pb-week-leg-${p.kind}`}>
                {p.emoji} {p.label}
              </span>
            ));
          })()}
        </div>
      </div>

      {/* Season progress strip */}
      <div className="pb-t-season">
        <div className="pb-t-season-head">
          <div className="pb-eyebrow pb-eyebrow-red">SEASON PROGRESS</div>
          <div className="pb-mono">{elapsed} / {total} DAYS · {Math.round(seasonPct)}%</div>
        </div>
        <div className="pb-ribbon-wrap">
          <div className="pb-ribbon">
            {PHASES.map((b, i) => {
              const isCurrent = phase && b.id === phase.id;
              const isRace = b.kind === "race-int" || b.kind === "race-jp";
              return (
                <div key={i} className={`pb-block pb-block-${b.kind} ${isCurrent ? "pb-block-current" : ""}`}
                  style={{ flex: b.weight }}>
                  <div className="pb-block-top" />
                  <div className="pb-block-label">{b.peak ? `★ ${b.label}` : b.label}</div>
                  <div className="pb-block-pop" role="tooltip">
                    <div className="pb-block-pop-name">{b.peak ? `★ ${b.label}` : b.label}</div>
                    <div className="pb-block-pop-meta pb-mono">{b.start.slice(5).replace("-","/")} 〜 {b.end.slice(5).replace("-","/")} · {b.days}日</div>
                  </div>
                </div>
              );
            })}
            {/* 経過フィル */}
            <div className="pb-season-fill" style={{ width: `${seasonPct}%` }} />
            {/* 今日マーカー */}
            <div className="pb-now-marker" style={{ left: `${seasonPct}%` }}>
              <div className="pb-now-arrow" />
              <div className="pb-now-line" />
              <div className="pb-now-label">NOW</div>
            </div>
            {/* 表示中の週マーカー（週送り時のみ） */}
            {weekOffset !== 0 && (
              <div className="pb-view-marker" style={{ left: `${viewPct}%` }}>
                <div className="pb-view-line" />
                <div className="pb-view-label">{weekLabelJp}</div>
              </div>
            )}
          </div>
        </div>
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────────────────────
//  ROAD — overview / chapters / timeline
// ─────────────────────────────────────────────────────────────────────────────
function Road({ today }) {
  const phase = findPhase(today);
  return (
    <div className="pb-road">
      <div className="pb-grain" />

      <div className="pb-r-hero">
        <div className="pb-section-head">
          <div className="pb-section-num">01</div>
          <div className="pb-section-titles">
            <div className="pb-section-en">THE ROAD.</div>
            <div className="pb-section-jp">128日の道のり ／ 5月20日 → 9月25日</div>
          </div>
        </div>
        <div className="pb-r-hero-band">
          <div className="pb-r-hero-band-l">PRINCIPLE</div>
          <div className="pb-r-hero-band-c">
            <div className="pb-r-hero-en">ONE PEAK. TWO ECHOES.</div>
            <div className="pb-r-hero-jp">
              フルピークは <b>WCH🇳🇱</b> に集中、ASIA は地元での第2ピーク。
              WC1・WC3は強化と選考のレース ／ 代表強化スケジュールに沿って <b>ピークへ積み上げる</b>。
            </div>
          </div>
        </div>
      </div>

      {/* TIMELINE */}
      <div className="pb-r-timeline">
        <div className="pb-r-timeline-scroll">
          <div className="pb-r-months">
            <div style={{ flex: 7 }}>MAY · 皐月</div>
            <div style={{ flex: 30 }}>JUNE · 水無月</div>
            <div style={{ flex: 31 }}>JULY · 文月</div>
            <div style={{ flex: 30 }}>AUGUST · 葉月</div>
          </div>
          <div className="pb-r-ribbon">
            {PHASES.map((b, i) => {
              const isCurrent = phase && b.id === phase.id;
              return (
                <div key={i} className={`pb-r-block pb-block-${b.kind} ${b.peak ? "pb-r-peak" : ""} ${isCurrent ? "pb-r-block-current" : ""}`}
                  style={{ flex: b.weight }}>
                  <div className="pb-r-block-top">
                    {b.marker && <div className="pb-r-block-marker">{b.marker}</div>}
                    <div className="pb-r-block-label">{b.label}</div>
                    {b.desc && <div className="pb-r-block-desc">{b.desc}</div>}
                  </div>
                  <div className="pb-r-block-bot">
                    <div className="pb-r-block-date pb-mono">{b.start.slice(5).replace("-", "/")}–{b.end.slice(5).replace("-", "/")}</div>
                    <div className="pb-r-block-days pb-mono">{b.days}D</div>
                  </div>
                  {b.peak && <div className="pb-r-peak-badge">PEAK {b.peak}</div>}
                  <div className="pb-block-pop" role="tooltip">
                    <div className="pb-block-pop-name">{b.peak ? `★ ${b.label}` : b.label}</div>
                    <div className="pb-block-pop-meta pb-mono">{b.start.slice(5).replace("-","/")} 〜 {b.end.slice(5).replace("-","/")} · {b.days}日</div>
                  </div>
                </div>
              );
            })}
          </div>
        </div>
        <div className="pb-r-legend">
          <span className="pb-lg pb-lg-natl">強化合宿（国管理）</span>
          <span className="pb-lg pb-lg-travel">移動・事前合宿</span>
          <span className="pb-lg pb-lg-race-int">代表レース</span>
        </div>
      </div>

      {/* STORY ONE-LINER */}
      <div className="pb-r-story">
        <div className="pb-r-story-tag">STORY</div>
        <div className="pb-r-story-text">
          🚣 5月強化合宿 → 🇪🇸 <b>WC1セビリア（初戦）</b> → ✈️ 帰国・回復 →
          🏋️ WC3向け強化18日 → 🇨🇭 <b>WC3ルツェルン（選考最終）</b> →
          🏋️ 夏期強化48日（土台→ピーキング） → 🇳🇱 蘭事前合宿 →
          ⭐ <b>世界選手権 ＝ P1 FULL PEAK</b> → ✈️ 帰国・回復11日 →
          🚣 長良川合宿9日 → 🏆 <b>アジア大会 ＝ P2 HOME PEAK</b>
        </div>
      </div>

      {/* 3 CHAPTERS */}
      <div className="pb-section-head">
        <div className="pb-section-num">02</div>
        <div className="pb-section-titles">
          <div className="pb-section-en">THREE BATTLES.</div>
          <div className="pb-section-jp">三つの戦場 ／ 優先順位は変えない</div>
        </div>
      </div>
      <div className="pb-r-chapters">
        {CAMPAIGNS.map((c, i) => {
          const d = Math.max(0, daysBetween(today, c.targetDate));
          const done = today > c.targetDate;
          return (
            <div key={c.id} className={`pb-ch pb-ch-${i}`}>
              <div className="pb-ch-l">
                <div className="pb-ch-rank">{c.rank}</div>
                <div className="pb-ch-rank-label">PRIORITY</div>
                <div className="pb-ch-d pb-mono">{done ? "DONE" : `D-${d}`}</div>
              </div>
              <div className="pb-ch-body">
                <div className="pb-ch-where pb-mono">{c.whereEn}</div>
                <div className="pb-ch-en">{c.nameEn}</div>
                <div className="pb-ch-jp">{c.nameJp}</div>
                <div className="pb-ch-meta">
                  <div className="pb-ch-meta-cell">
                    <div className="pb-ch-meta-k pb-mono">DATE</div>
                    <div className="pb-ch-meta-v pb-mono">{c.datesEn}</div>
                  </div>
                  <div className="pb-ch-meta-cell">
                    <div className="pb-ch-meta-k pb-mono">ROLE</div>
                    <div className="pb-ch-meta-v pb-mono">{c.role}</div>
                  </div>
                </div>
                <div className="pb-ch-note">{c.note}</div>
              </div>
            </div>
          );
        })}
      </div>

      {/* PHASE INTENT */}
      <div className="pb-section-head pb-section-head-sub">
        <div className="pb-section-num">03</div>
        <div className="pb-section-titles">
          <div className="pb-section-en">PHASE INTENT.</div>
          <div className="pb-section-jp">各期の意図 ／ なぜそうするか</div>
        </div>
      </div>
      <div className="pb-r-phases">
        {[
          { k: "natl",     emoji: "🚣", t: "A. 5月強化合宿＋WC1", d: "5/20-31 ／ 12日 ／ 国管理",
            now: "WC1直前。Block 2 終盤＋セビリア遠征。",
            us: "シーズン初戦で <b>世界の現在地を確認</b>。WCH選考の前哨戦。" },
          { k: "travel",   emoji: "✈️", t: "B. WC1後・回復", d: "6/1-7 ／ 7日",
            now: "時差調整＋低強度メンテ。全日本選手権期間（出場見送り）。",
            us: "<b>完全休＋Z1軽め</b>。次の高負荷ブロックに備える。" },
          { k: "natl",     emoji: "🏋️", t: "C. WC3向け強化", d: "6/8-25 ／ 18日 ／ 国管理",
            now: "WC3選考の最終評価レースに向けた高負荷期。",
            us: "週Z3×3＋Z2×2＋ウェイト3。<b>SBSの貯金を伸ばす</b>。" },
          { k: "race-int", emoji: "🇨🇭", t: "D. WC3 ルツェルン", d: "6/26-28 ／ 3日 ／ 国管理",
            now: "WCH派遣の最終評価。重点強化種目M1xとして派遣対象。",
            us: "<b>WCH選考確定の鍵</b>。結果でWCH派遣が確定する。" },
          { k: "natl",     emoji: "🏋️", t: "E. 夏期強化①(土台)", d: "6/29-7/26 ／ 28日 ／ 国管理",
            now: "WCH選考確定後の本ピーク作りの土台期。",
            us: "Z3×週3＋Z2×週2＋低強度大量。<b>有酸素土台を厚く</b>。" },
          { k: "natl",     emoji: "⚡", t: "F. 夏期強化②(ピーキング)", d: "7/27-8/15 ／ 20日 ／ 国管理",
            now: "WCH本戦まで残り1ヶ月。高強度ピーキング期。",
            us: "Z3メイン＋テーパー導入。<b>レースペースを刻み込む</b>。" },
          { k: "travel",   emoji: "🇳🇱", t: "G. 蘭事前合宿", d: "8/16-22 ／ 7日 ／ 国管理",
            now: "アムステルダム水域順応。時差ぼけ最少化。",
            us: "コース下見＋スタート確認。<b>本戦に向けて感覚を整える</b>。" },
          { k: "race-int", emoji: "⭐", t: "H. 世界選手権 ★ P1", d: "8/23-30 ／ 8日 ／ 国管理",
            now: "★ FULL PEAK。年間で最も大事な8日間。",
            us: "<b>すべてはここに集約</b>。決勝8/30 ＝ ピーク1。" },
          { k: "travel",   emoji: "✈️", t: "I. 帰国・回復", d: "8/31-9/10 ／ 11日",
            now: "WCH後の深い疲労。アジア大会まで20日。",
            us: "<b>完全休＋低強度メンテ</b>。Z1で土台維持のみ。" },
          { k: "natl",     emoji: "🚣", t: "J. アジア大会前合宿", d: "9/11-19 ／ 9日 ／ 国管理",
            now: "長良川水域順応。ピーク2作り（短期再ピーキング）。",
            us: "Z3＋スタート練で <b>短期ピーキング</b>。地元水域に合わせる。" },
          { k: "race-int", emoji: "🏆", t: "K. アジア大会 ★ P2", d: "9/20-25 ／ 6日 ／ 国管理",
            now: "★ HOME PEAK。地元水域、メダル狙い。",
            us: "WCHの貯金＋短期ピーキングで戦う。<b>決勝9/25 ＝ ピーク2</b>。" },
        ].map((p, i) => (
          <div key={i} className={`pb-r-phase pb-r-phase-${p.k}`}>
            <div className="pb-r-phase-head">
              <div className="pb-r-phase-emoji">{p.emoji}</div>
              <div>
                <div className="pb-r-phase-t">{p.t}</div>
                <div className="pb-r-phase-d pb-mono">{p.d}</div>
              </div>
            </div>
            <div className="pb-r-phase-body">
              <div><span className="pb-r-phase-k">いま:</span> {p.now}</div>
              <div><span className="pb-r-phase-k">方針:</span> <span dangerouslySetInnerHTML={{__html: p.us}} /></div>
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────────────────────
//  CODE — rules + zones
// ─────────────────────────────────────────────────────────────────────────────
function Code() {
  return (
    <div className="pb-code">
      <div className="pb-grain" />
      <div className="pb-section-head">
        <div className="pb-section-num">01</div>
        <div className="pb-section-titles">
          <div className="pb-section-en">THE CODE.</div>
          <div className="pb-section-jp">三箇条 ／ 迷ったらこれを見る</div>
        </div>
      </div>
      <div className="pb-c-laws">
        {[
          { no: "i.", en: "READINESS RULES THE WORK.",
            jp: "計画より、体の声が上。",
            body: "主観疲労 <b>7+</b> ／ 睡眠の質 <b>4-</b> が2日連続 ／ 筋肉痛 <b>7+</b> ／ やる気 <b>3-</b> が3日連続 → 高強度は <b>Z1漕ぎ</b> に置換する。" },
          { no: "ii.", en: "ROW Z1 IN Z1.",
            jp: "軽い日は本気で軽く。",
            body: "スプリット <b>2:25/500m</b> より速くしない。レース本能で勝手に上げない。Z1は燃料を入れる時間。" },
          { no: "iii.", en: "NEVER LOAD JET LAG.",
            jp: "時差の上に負荷を乗せない。",
            body: "7/29-31（独帰国後）／ 8/17-19（加帰国後）の <b>計6日</b> は、絶対に負荷を乗せない。完全休 or Z1のみ。" },
        ].map((r, i) => (
          <div key={i} className="pb-c-law">
            <div className="pb-c-law-no">{r.no}</div>
            <div className="pb-c-law-body">
              <div className="pb-c-law-en">{r.en}</div>
              <div className="pb-c-law-jp">{r.jp}</div>
              <div className="pb-c-law-text" dangerouslySetInnerHTML={{__html: r.body}} />
            </div>
          </div>
        ))}
      </div>

      <div className="pb-section-head pb-section-head-sub">
        <div className="pb-section-num">02</div>
        <div className="pb-section-titles">
          <div className="pb-section-en">INTENSITY ZONES.</div>
          <div className="pb-section-jp">強度ゾーン ／ スプリットは暫定（M1x実測待ち）</div>
        </div>
      </div>
      <div className="pb-c-zones">
        {[
          { tag: "Z1", name: "RECOVERY",   split: "2:25 – 2:45", rate: "18–20", rpe: "3–4" },
          { tag: "Z2", name: "THRESHOLD",  split: "2:05 – 2:15", rate: "22–28", rpe: "6–7" },
          { tag: "Z3", name: "HIGH INT.",  split: "1:55 – 2:05", rate: "30–32", rpe: "8–9" },
          { tag: "RP", name: "RACE PACE",  split: "1:49 – 1:50", rate: "32–36", rpe: "10", rp: true },
        ].map((z, i) => (
          <div key={i} className={`pb-c-zone ${z.rp ? "pb-c-zone-rp" : ""}`}>
            <div className="pb-c-zone-tag">{z.tag}</div>
            <div className="pb-c-zone-body">
              <div className="pb-c-zone-name">{z.name}</div>
              <div className="pb-c-zone-stats pb-mono">
                <span>{z.split} <span className="pb-c-zone-stats-k">/500m</span></span>
                <span>RATE {z.rate}</span>
                <span>RPE {z.rpe}</span>
              </div>
            </div>
          </div>
        ))}
        <div className="pb-c-zones-note">
          <span className="pb-mono pb-eyebrow">CONSTRAINT</span>
          高強度は代表強化合宿で集中管理 ／ 移動・回復期は <b>強度ゼロ</b>、ピーク前は調整優先。
        </div>
      </div>

      {/* Footer */}
      <div className="pb-c-foot">
        <div className="pb-c-foot-l">
          <div className="pb-c-foot-brand">TATSUYA SAKURAMA / 26SS</div>
          <div className="pb-mono pb-c-foot-mono">NTT東日本 × シニア代表 ／ ダブルピーク：WCH × ASIA</div>
        </div>
        <div className="pb-mono pb-c-foot-r">5.25 — 8.30 / 14W / 98D</div>
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────────────────────
//  STATE — link to protected live dashboard
// ─────────────────────────────────────────────────────────────────────────────
function State() {
  return (
    <div className="pb-code">
      <div className="pb-grain" />
      <div className="pb-section-head">
        <div className="pb-section-num">01</div>
        <div className="pb-section-titles">
          <div className="pb-section-en">STATE.</div>
          <div className="pb-section-jp">コンディション ／ 実データ</div>
        </div>
      </div>
      <div className="pb-c-laws">
        <div className="pb-c-law">
          <div className="pb-c-law-no">●</div>
          <div className="pb-c-law-body">
            <div className="pb-c-law-en">CONDITION · LIVE</div>
            <div className="pb-c-law-jp">HRV・安静時心拍・疲労(Hooper)・ACWR・フォーム(TSB)・心拍ゾーン配分</div>
            <div className="pb-c-law-text">Polar / intervals.icu 連携の実データを、保護ダッシュボードで確認できます。健康情報のためログインが必要です。</div>
            <a className="pb-cover-cta" style={{ marginTop: "14px" }} href="https://rowing-rpg-shell.pages.dev/sakurama-state" target="_blank" rel="noopener">
              <span className="pb-mono">→</span>&nbsp;コンディションを見る（要ログイン）
            </a>
          </div>
        </div>
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────────────────────
//  APP
// ─────────────────────────────────────────────────────────────────────────────
function App() {
  const [tab, setTab] = useTab();
  const today = useToday();

  return (
    <div className="pb-app">
      {!IS_EMBED && <TopBar tab={tab} setTab={setTab} today={today} />}
      <div className="pb-main">
        {tab === "cover" && <Cover today={today} setTab={setTab} />}
        {tab === "today" && <Today today={today} />}
        {tab === "state" && <State />}
        {tab === "road" && <Road today={today} />}
        {tab === "code" && <Code />}
      </div>
    </div>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
