// ============================================================================
//  PLAYBOOK APP — generic, data-driven (reads window.PB + window.ATHLETE)
//  Tabs: COVER / TODAY / STATE / THE ROAD / THE CODE
// ============================================================================

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

const AT = window.ATHLETE;

// ─────────────────────────────────────────────────────────────────────────────
//  Helpers / Hooks
// ─────────────────────────────────────────────────────────────────────────────
const IS_EMBED = (() => {
  try { return new URLSearchParams(location.search).get("embed") === "1"; }
  catch { return false; }
})();

function useTab() {
  const [tab, setTabState] = React.useState(() => {
    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 };
}

// season span helper (M月D日 → M月D日 ／ N週 ／ N日)
function seasonSpanText() {
  const days = daysBetween(SEASON_START, SEASON_END) + 1;
  const weeks = Math.round(days / 7);
  const s = parseISO(SEASON_START), e = parseISO(SEASON_END);
  const fjp = (d) => `${d.getMonth() + 1}月${d.getDate()}日`;
  return { days, weeks, text: `${fjp(s)} → ${fjp(e)} ／ ${weeks}週 ／ ${days}日`,
    short: `${SEASON_START.slice(5).replace("-", ".")} — ${SEASON_END.slice(5).replace("-", ".")} / ${weeks}W / ${days}D` };
}

// ─────────────────────────────────────────────────────────────────────────────
//  TOP BAR
// ─────────────────────────────────────────────────────────────────────────────
function TopBar({ tab, setTab, today }) {
  const d = parseISO(today);
  const next = CAMPAIGNS.find((c) => c.targetDate >= today) || CAMPAIGNS[CAMPAIGNS.length - 1];
  const nextD = next ? daysBetween(today, next.targetDate) : 0;
  const nextShort = next ? next.nameEn : "";
  return (
    <div className="pb-topbar">
      <div className="pb-tb-l">
        <div className="pb-mark">{AT.mark}</div>
        <div>
          <div className="pb-tb-name">{AT.given} · {AT.surname}</div>
          <div className="pb-tb-sub">{AT.jp} ／ {AT.club} ／ {AT.event} ／ {AT.squad} 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">{nextShort}</div>
          <div className="pb-tb-v pb-mono">
            <span className="pb-red">D-{nextD < 0 ? "DONE" : nextD}</span>
          </div>
        </div>
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────────────────────
//  COVER — poster mode
// ─────────────────────────────────────────────────────────────────────────────
function Cover({ today, setTab }) {
  const seasonDays = daysBetween(SEASON_START, SEASON_END) + 1;
  const elapsed = Math.max(0, daysBetween(SEASON_START, today));
  const remaining = Math.max(0, seasonDays - elapsed);
  const span = seasonSpanText();

  const targets = CAMPAIGNS.slice(0, 4).map((c) => ({
    en: c.nameEn,
    jp: c.nameJp,
    d: Math.max(0, daysBetween(today, c.targetDate)),
    primary: c.rank === 1,
  }));

  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">{AT.fileNo}</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">{AT.surname}</div>
        <div className="pb-cover-name-row pb-cover-outline">{AT.given}</div>
      </div>
      <div className="pb-cover-jp">{AT.jp} ／ {AT.event} ／ {AT.squad}日本代表</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">{span.text}</div>
        </div>
        <div className="pb-cover-foot-col">
          <div className="pb-eyebrow">MISSION</div>
          <div className="pb-cover-foot-h">{AT.event} ／ {AT.squad}</div>
          <div className="pb-cover-foot-sub">{AT.trackFlow}</div>
        </div>
        <div className="pb-cover-foot-col">
          <div className="pb-eyebrow">PEAK</div>
          <div className="pb-cover-foot-h">RACE THE PLAN</div>
          <div className="pb-cover-foot-sub">{AT.trackNote}</div>
        </div>
      </div>

      <div className="pb-cover-targets">
        {targets.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)}週前`;
  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>

      {/* 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>

      {/* 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;
            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.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;
              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>
                  {b.desc && <div className="pb-block-pop-desc">{b.desc}</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>
  );
}

// ─────────────────────────────────────────────────────────────────────────────
//  STATE — condition tab
// ─────────────────────────────────────────────────────────────────────────────
function State() {
  const hasData = !!AT.stateUrl;
  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">
            {hasData ? "コンディション ／ 実データあり" : "コンディション ／ データ未連携"}
          </div>
        </div>
      </div>
      <div className="pb-c-laws">
        <div className="pb-c-law">
          <div className="pb-c-law-no">{hasData ? "●" : "—"}</div>
          <div className="pb-c-law-body">
            {hasData ? (
              <>
                <div className="pb-c-law-en">CONDITION · LIVE</div>
                <div className="pb-c-law-jp">HRV・安静時心拍・疲労(Hooper)・ACWR・フォーム・心拍ゾーン</div>
                <div className="pb-c-law-text">
                  この選手は Polar / intervals.icu と連携済みです。HRV・安静時心拍・疲労(Hooper指数)・ACWR(急性慢性負荷比)・フォーム・心拍ゾーン配分を専用のコンディションページで確認できます（要ログイン）。
                </div>
                <a className="pb-cover-cta" href={AT.stateUrl} target="_blank" rel="noopener">
                  <span className="pb-mono">→</span>&nbsp;コンディションを見る（要ログイン）
                </a>
              </>
            ) : (
              <>
                <div className="pb-c-law-en">CONDITION · NOT LINKED</div>
                <div className="pb-c-law-jp">データ未連携</div>
                <div className="pb-c-law-text">
                  この選手はまだ Polar / intervals.icu と連携していません。連携後にここで HRV・疲労(Hooper)・心拍ゾーン配分などを表示します（未連携の数値は出しません）。
                </div>
              </>
            )}
          </div>
        </div>
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────────────────────
//  ROAD — overview / chapters / timeline
// ─────────────────────────────────────────────────────────────────────────────
function Road({ today }) {
  const phase = findPhase(today);
  const span = seasonSpanText();
  const storyLine = PHASES.map((p) => `${p.emoji} ${p.label}`).join(" → ");

  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">{span.days}日の道のり ／ {span.text}</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">RACE THE PLAN.</div>
            <div className="pb-r-hero-jp">
              {AT.trackFlow} ／ {AT.trackNote}
            </div>
          </div>
        </div>
      </div>

      {/* TIMELINE */}
      <div className="pb-r-timeline">
        <div className="pb-r-timeline-scroll">
          <div className="pb-r-months">
            <div style={{ flex: 12 }}>MAY · 皐月</div>
            <div style={{ flex: 30 }}>JUNE · 水無月</div>
            <div style={{ flex: 31 }}>JULY · 文月</div>
            <div style={{ flex: 31 }}>AUGUST · 葉月</div>
            <div style={{ flex: 30 }}>SEP · 長月</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>
                  {b.desc && <div className="pb-block-pop-desc">{b.desc}</div>}
                  </div>
                </div>
              );
            })}
          </div>
        </div>
        <div className="pb-r-legend">
          <span className="pb-lg pb-lg-natl">国指示・強化合宿</span>
          <span className="pb-lg pb-lg-design">所属・調整</span>
          <span className="pb-lg pb-lg-off">完全オフ</span>
          <span className="pb-lg pb-lg-travel">海外遠征</span>
          <span className="pb-lg pb-lg-race-int">代表本戦</span>
          <span className="pb-lg pb-lg-race-jp">国内大会</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">
          {storyLine}
        </div>
      </div>

      {/* CHAPTERS */}
      <div className="pb-section-head">
        <div className="pb-section-num">02</div>
        <div className="pb-section-titles">
          <div className="pb-section-en">THE 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 — generated from PHASES */}
      <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">
        {PHASES.map((p, i) => (
          <div key={i} className={`pb-r-phase pb-r-phase-${p.kind}`}>
            <div className="pb-r-phase-head">
              <div className="pb-r-phase-emoji">{p.emoji}</div>
              <div>
                <div className="pb-r-phase-t">{p.label}</div>
                <div className="pb-r-phase-d pb-mono">{p.start.slice(5)}–{p.end.slice(5)} ／ {p.days}日</div>
              </div>
            </div>
            <div className="pb-r-phase-body">
              <div>{p.desc}</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: "レース本能で勝手に上げない。Z1は燃料を入れる時間。" },
          { no: "iii.", en: "SHOW UP HONEST.",
            jp: "自分の状態を正直に共有する。",
            body: "主観データはチームの判断材料。隠さず、誇張せず、正確に。" },
        ].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">強度ゾーン ／ レート・RPE基準（スプリットは個人別）</div>
        </div>
      </div>
      <div className="pb-c-zones">
        {[
          { tag: "Z1", name: "RECOVERY",   rate: "18–20", rpe: "3–4" },
          { tag: "Z2", name: "THRESHOLD",  rate: "22–28", rpe: "6–7" },
          { tag: "Z3", name: "HIGH INT.",  rate: "30–32", rpe: "8–9" },
          { tag: "RP", name: "RACE PACE",  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>SPLIT <span className="pb-c-zone-stats-k">個人別</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>
          高強度(Z3/RP)は週あたりの本数を管理する。
        </div>
      </div>

      {/* Footer */}
      <div className="pb-c-foot">
        <div className="pb-c-foot-l">
          <div className="pb-c-foot-brand">{AT.en} / 26SS</div>
          <div className="pb-mono pb-c-foot-mono">{AT.event} ／ {AT.squad} 日本代表</div>
        </div>
        <div className="pb-mono pb-c-foot-r">{seasonSpanText().short}</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 />);
