// WeaveStudy — Camp (main page)
// Three variations (A: 메가스터디 클래식 / B: 시원스쿨 좌우분할 / C: 다크 프리미엄)

const { useState: useStateCamp } = React;

// pick a featured subset for the home page
function pickFeatured(all) {
  const ids = ["besty", "rily", "damine", "melanya"];
  return ids.map(id => all.find(c => c.id === id)).filter(Boolean);
}
function pickLineup(all) {
  // 8 — PC chars + 2 most popular drim-ju
  const ids = ["besty", "rily", "damine", "melanya", "kiki", "nia", "gale", "karlach"];
  return ids.map(id => all.find(c => c.id === id)).filter(Boolean);
}

function Camp({ navigate, variant = "A", parodyIntensity = "medium" }) {
  const { CHARACTERS, CAMPAIGNS, MEMOIRS, NEWS } = window.WS_DATA;
  const FEATURED = pickFeatured(CHARACTERS);
  const LINEUP = pickLineup(CHARACTERS);
  if (variant === "B") return <CampVariantB {...{ navigate, parodyIntensity, CHARACTERS, FEATURED, LINEUP, CAMPAIGNS, MEMOIRS, NEWS }} />;
  if (variant === "C") return <CampVariantC {...{ navigate, parodyIntensity, CHARACTERS, FEATURED, LINEUP, CAMPAIGNS, MEMOIRS, NEWS }} />;
  return <CampVariantA {...{ navigate, parodyIntensity, CHARACTERS, FEATURED, LINEUP, CAMPAIGNS, MEMOIRS, NEWS }} />;
}

/* ════════════════════════════════════════════════════════════
   VARIANT A — 메가스터디 클래식
   풀밴드 히어로 + 1타 강사진 큰 카드 그리드 + 인기 캠페인 + 모험 회고
   ════════════════════════════════════════════════════════════ */
function CampVariantA({ navigate, CHARACTERS, FEATURED, LINEUP, CAMPAIGNS, MEMOIRS, NEWS }) {
  const dDays = 7; // 다음 긴 휴식까지
  return (
    <main>
      {/* ─ Hero band ─ */}
      <section className="hero-grad-light" style={{ position: "relative", overflow: "hidden", paddingBottom: 0 }}>
        <div className="container" style={{ position: "relative", paddingTop: 64, paddingBottom: 64 }}>
          <div style={{ display: "grid", gridTemplateColumns: "1.1fr 0.9fr", gap: 48, alignItems: "center" }}>
            <div>
              <div style={{ display: "inline-flex", alignItems: "center", gap: 8, marginBottom: 20, flexWrap: "wrap" }}>
                <span className="badge badge-1ta" style={{ fontSize: 12, padding: "5px 10px" }}>2026 정규 캠페인</span>
                <span style={{ fontSize: 13, fontWeight: 600, color: "var(--weave-violet-strong)", letterSpacing: "0.02em" }}>WEAVESTUDY · 비전 인강 1위</span>
              </div>
              <h1 style={{
                fontSize: 52, fontWeight: 800, lineHeight: 1.15, letterSpacing: "-0.035em",
                color: "var(--weave-ink)", margin: 0, fontFamily: "var(--font-serif-display)"
              }}>
                긴 휴식 한 번이면,<br />
                캐릭터 한 명을<br />
                <span style={{ color: "var(--weave-violet)" }}>정복</span>합니다.
              </h1>
              <p style={{ fontSize: 17, lineHeight: 1.6, color: "var(--label-neutral)", marginTop: 20, maxWidth: 480 }}>
                1막부터 3막까지 위브 전 영역 무제한 수강.<br />
                주문 슬롯이 모자란 당신을 위한 단 하나의 커리큘럼.
              </p>
              <div style={{ display: "flex", gap: 12, marginTop: 28, alignItems: "center" }}>
                <button className="btn btn-primary btn-lg" onClick={() => navigate({ name: "campaigns" })}>
                  파티 합류하기
                </button>
                <button className="btn btn-secondary btn-lg" onClick={() => navigate({ name: "library" })}>
                  자료실 둘러보기
                </button>
                <div style={{ marginLeft: 8, fontSize: 13, color: "var(--label-alternative)", lineHeight: 1.4 }}>
                  지금 <strong style={{ color: "var(--weave-violet)" }}>4명</strong>의 동료가<br />합류 대기 중
                </div>
              </div>
            </div>

            {/* D-day widget */}
            <div style={{
              position: "relative",
              background: "white",
              borderRadius: 24,
              boxShadow: "var(--shadow-lg)",
              padding: 28,
              border: "1px solid var(--line-normal)"
            }}>
              <div style={{ fontSize: 12, fontWeight: 700, color: "var(--weave-violet)", letterSpacing: "0.08em", textTransform: "uppercase" }}>
                NEXT LONG REST
              </div>
              <div style={{ display: "flex", alignItems: "baseline", gap: 8, marginTop: 4 }}>
                <span style={{ fontSize: 16, fontWeight: 700, color: "var(--label-normal)" }}>다음 긴 휴식까지</span>
              </div>
              <div style={{ display: "flex", alignItems: "flex-end", gap: 6, marginTop: 12, fontFamily: "var(--font-serif-display)", whiteSpace: "nowrap" }}>
                <span style={{ fontSize: 92, fontWeight: 800, lineHeight: 1, letterSpacing: "-0.06em", color: "var(--weave-ink)", whiteSpace: "nowrap" }}>D-{dDays}</span>
                <span style={{ fontSize: 18, fontWeight: 700, color: "var(--label-alternative)", marginBottom: 12 }}>일</span>
              </div>
              <div className="weave-line" style={{ margin: "20px 0" }} />
              <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr 1fr", gap: 12 }}>
                <MiniStat label="진행 캠페인" value="3" />
                <MiniStat label="누적 세션" value="17" />
                <MiniStat label="합류 동료" value="4" />
              </div>
              <div style={{ marginTop: 20, padding: 12, background: "var(--weave-violet-soft)", borderRadius: 10, fontSize: 12, color: "var(--weave-violet-strong)", lineHeight: 1.5 }}>
                <strong>위더스의 메모:</strong> 캠프 보급품이 충분합니다. 긴 휴식을 진행해 주십시오.
              </div>
            </div>
          </div>

          {/* 운영 알림 strip */}
          <div style={{
            marginTop: 48,
            display: "flex", alignItems: "center", gap: 24,
            background: "white", borderRadius: 16,
            padding: "16px 24px",
            boxShadow: "var(--shadow-xs)",
            border: "1px solid var(--line-normal)"
          }}>
            <div style={{
              display: "inline-flex", alignItems: "center", gap: 6,
              fontSize: 12, fontWeight: 700, color: "white",
              background: "var(--weave-ink)",
              padding: "4px 10px",
              borderRadius: 4
            }}>
              <Icon name="bell" size={12} color="white" /> NOTICE
            </div>
            <div style={{ display: "flex", gap: 24, overflow: "hidden", flex: 1 }}>
              {NEWS.slice(0, 3).map(n => (
                <div key={n.id} style={{ display: "flex", alignItems: "center", gap: 8, fontSize: 13, color: "var(--label-neutral)" }}>
                  <span className="tag tag-violet" style={{ padding: "2px 8px", fontSize: 11 }}>{n.tag}</span>
                  <span style={{ fontWeight: 600 }}>{n.t}</span>
                  <span style={{ color: "var(--label-alternative)", fontFamily: "var(--font-mono)", fontSize: 12 }}>{n.date}</span>
                </div>
              ))}
            </div>
            <a style={{ fontSize: 13, color: "var(--label-alternative)", whiteSpace: "nowrap" }}>전체 알림 →</a>
          </div>
        </div>
      </section>

      {/* ─ Origin Lineup (1타 강사진) ─ */}
      <section className="container" style={{ paddingTop: 96 }}>
        <SectionTitle
          eyebrow="ORIGIN LINEUP"
          title="오리진 라인업"
          sub="당신의 캠프에 합류한 1타 모험가들. 클릭하면 캐릭터 시트가 열립니다."
          action={
            <button className="sec-more" onClick={() => navigate({ name: "origins" })}>
              전체 라인업 보기 <Icon name="chevron-right" size={14} />
            </button>
          }
        />
        <div style={{ display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: 20 }}>
          {FEATURED.map(ch => (
            <OriginCard key={ch.id} character={ch} onClick={() => navigate({ name: "character", id: ch.id })} />
          ))}
        </div>
      </section>

      {/* ─ Popular Campaigns ─ */}
      <section className="container" style={{ paddingTop: 96 }}>
        <SectionTitle
          eyebrow="POPULAR CAMPAIGNS"
          title="인기 캠페인"
          sub="이번 주 가장 많이 수강된 정규 커리큘럼"
          action={
            <button className="sec-more" onClick={() => navigate({ name: "campaigns" })}>
              전체 커리큘럼 <Icon name="chevron-right" size={14} />
            </button>
          }
        />
        <div style={{ display: "grid", gridTemplateColumns: "1.6fr 1fr 1fr", gap: 20 }}>
          {/* Feature campaign — big */}
          <CampaignFeatureCard campaign={CAMPAIGNS[0]} onClick={() => navigate({ name: "campaign", id: CAMPAIGNS[0].id })} />
          <CampaignSmallCard campaign={CAMPAIGNS[1]} onClick={() => navigate({ name: "campaign", id: CAMPAIGNS[1].id })} />
          <CampaignSmallCard campaign={CAMPAIGNS[2]} onClick={() => navigate({ name: "campaign", id: CAMPAIGNS[2].id })} />
        </div>
      </section>

      {/* ─ Adventure Log (신규 모험 일지) ─ */}
      <section className="container" style={{ paddingTop: 96 }}>
        <SectionTitle eyebrow="ADVENTURE LOG" title="신규 모험 일지"
          sub="최근 업데이트된 캐릭터 설정 / 세션 후기" />
        <div style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 20 }}>
          <AdventureLogCard
            title="베스티 — 캔들킵 도서관에서의 마지막 새벽"
            tag="베스티 / 본편 1막"
            author="베스티"
            date="2026.05.18"
            colorKey="cl-sorcerer"
          />
          <AdventureLogCard
            title="라일리 — 광산 입구 협상 회상록"
            tag="라일리 / 판델버"
            author="라일리"
            date="2026.05.15"
            colorKey="cl-warlock"
          />
          <AdventureLogCard
            title="다미네 — 양 떼를 추적한 그 봄"
            tag="다미네 / 단편 #1"
            author="다미네"
            date="2026.05.12"
            colorKey="cl-wizard"
          />
        </div>
      </section>

      {/* ─ Memoirs (모험 회고) ─ */}
      <section style={{ background: "var(--weave-parchment)", marginTop: 96, padding: "96px 0" }}>
        <div className="container">
          <SectionTitle
            eyebrow="MEMOIRS"
            title="모험 회고"
            sub="이 캐릭터를 만들고 나의 인생이 어떻게 바뀌었나"
          />
          <div style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 20 }}>
            {MEMOIRS.map(m => {
              const author = CHARACTERS.find(c => c.id === m.authorId);
              return <MemoirCard key={m.id} memoir={m} author={author} onClick={() => navigate({ name: "character", id: m.authorId })} />;
            })}
          </div>
        </div>
      </section>

      {/* ─ Lower CTA strip ─ */}
      <section className="container" style={{ paddingTop: 96 }}>
        <div style={{
          background: "linear-gradient(135deg, var(--weave-violet) 0%, var(--weave-violet-strong) 100%)",
          borderRadius: 24, padding: "48px 56px",
          color: "white", display: "flex", alignItems: "center", justifyContent: "space-between"
        }}>
          <div>
            <div style={{ fontSize: 12, fontWeight: 700, opacity: 0.7, letterSpacing: "0.1em", textTransform: "uppercase", marginBottom: 8 }}>
              WEAVE PASS
            </div>
            <div style={{ fontSize: 32, fontWeight: 800, letterSpacing: "-0.025em", fontFamily: "var(--font-serif-display)" }}>
              비전 마법을 1등급으로<br />만들어 드립니다
            </div>
            <p style={{ fontSize: 14, opacity: 0.85, marginTop: 12, maxWidth: 420, lineHeight: 1.55 }}>
              모든 캐릭터 시트 · 모든 캠페인 · 모든 세션 기록을 위브 패스 한 장으로.
              본 패스는 정신적 효력만 있으며 실제 결제는 진행되지 않습니다.
            </p>
          </div>
          <div style={{ display: "flex", gap: 12 }}>
            <button className="btn btn-lg" style={{ background: "white", color: "var(--weave-violet-strong)" }}>
              위브 패스 받기
            </button>
            <button className="btn btn-lg" style={{ background: "rgba(255,255,255,0.12)", color: "white", border: "1px solid rgba(255,255,255,0.3)" }}>
              짧은 휴식 체험판
            </button>
          </div>
        </div>
      </section>
    </main>
  );
}

/* ════════════════════════════════════════════════════════════
   VARIANT B — 시원스쿨 좌우 분할 + 미니멀 그리드
   ════════════════════════════════════════════════════════════ */
function CampVariantB({ navigate, CHARACTERS, FEATURED, LINEUP, CAMPAIGNS, MEMOIRS, NEWS }) {
  const byId = (id) => CHARACTERS.find(c => c.id === id);
  const gale = byId("gale");
  const besty = byId("besty");
  const rily = byId("rily");
  const damine = byId("damine");
  return (
    <main>
      <section style={{ background: "white", borderBottom: "1px solid var(--line-normal)" }}>
        <div className="container" style={{ paddingTop: 80, paddingBottom: 80 }}>
          <div style={{ display: "grid", gridTemplateColumns: "1.05fr 1fr", gap: 64, alignItems: "center" }}>
            <div>
              <div style={{ display: "inline-flex", alignItems: "center", gap: 8, marginBottom: 24 }}>
                <span style={{ width: 6, height: 6, borderRadius: 99, background: "var(--weave-teal-deep)" }}></span>
                <span style={{ fontSize: 13, fontWeight: 700, color: "var(--weave-teal-deep)", letterSpacing: "0.05em" }}>
                  지금 4명의 모험가가 위브에 접속 중
                </span>
              </div>
              <h1 style={{
                fontSize: 64, fontWeight: 800, lineHeight: 1.08, letterSpacing: "-0.04em",
                color: "var(--weave-ink)", margin: 0
              }}>
                당신의 캠프에<br />합류한 위저드,<br />
                <span style={{ display: "inline-block", background: "linear-gradient(90deg, var(--weave-violet) 0%, var(--weave-teal-deep) 100%)", WebkitBackgroundClip: "text", color: "transparent" }}>
                  단 한 명. 게일.
                </span>
              </h1>
              <p style={{ fontSize: 17, lineHeight: 1.7, color: "var(--label-neutral)", marginTop: 24, maxWidth: 480 }}>
                위브스터디는 졍의 드림주 라인업과 D&D 자캐들의 설정·관계성·세션 기록을
                인강 사이트의 워딩으로 정리한 아카이브입니다.
              </p>
              <div style={{ display: "flex", gap: 12, marginTop: 32 }}>
                <button className="btn btn-primary btn-lg" onClick={() => navigate({ name: "origins" })}>
                  오리진 라인업 보기
                </button>
                <button className="btn btn-ghost btn-lg" onClick={() => navigate({ name: "library" })}>
                  자료실 →
                </button>
              </div>
              <div style={{ display: "flex", gap: 24, marginTop: 56 }}>
                <BigStat label="합류 동료" value="4" sub="명" />
                <BigStat label="진행 캠페인" value="4" sub="개" />
                <BigStat label="누적 세션" value="17" sub="회" />
                <BigStat label="평균 평점" value="5.0" sub="/5" />
              </div>
            </div>

            {/* Right: stacked portrait cards */}
            <div className="stacked-portrait-area" style={{ position: "relative", height: 540 }}>
              {gale && <StackedPortrait c={gale} pos={{ left: 10, top: 0, rotate: -4, z: 1 }} onClick={() => navigate({ name: "character", id: gale.id })} />}
              {damine && <StackedPortrait c={damine} pos={{ left: 130, top: 40, rotate: 2, z: 2 }} onClick={() => navigate({ name: "character", id: damine.id })} />}
              {rily && <StackedPortrait c={rily} pos={{ left: 250, top: 20, rotate: -2, z: 3 }} onClick={() => navigate({ name: "character", id: rily.id })} />}
              {besty && <StackedPortrait c={besty} pos={{ left: 100, top: 200, rotate: 4, z: 4 }} hero onClick={() => navigate({ name: "character", id: besty.id })} />}
            </div>
          </div>
        </div>
      </section>

      {/* Origin lineup — minimal list */}
      <section className="container" style={{ paddingTop: 96 }}>
        <SectionTitle eyebrow="ORIGIN LINEUP" title="오리진 라인업" sub="1타 모험가 — 클릭으로 캐릭터 시트 열람" />
        <div style={{ display: "grid", gridTemplateColumns: "repeat(2, 1fr)", gap: 16 }}>
          {LINEUP.map(ch => <OriginListRow key={ch.id} character={ch} onClick={() => navigate({ name: "character", id: ch.id })} />)}
        </div>
      </section>

      {/* Popular campaigns */}
      <section className="container" style={{ paddingTop: 96 }}>
        <SectionTitle eyebrow="POPULAR CAMPAIGNS" title="인기 캠페인" />
        <div style={{ display: "grid", gridTemplateColumns: "repeat(2, 1fr)", gap: 20 }}>
          {CAMPAIGNS.map(c => <CampaignSmallCard key={c.id} campaign={c} onClick={() => navigate({ name: "campaign", id: c.id })} />)}
        </div>
      </section>

      {/* Memoirs */}
      <section className="container" style={{ paddingTop: 96 }}>
        <SectionTitle eyebrow="MEMOIRS" title="모험 회고" />
        <div style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 20 }}>
          {MEMOIRS.map(m => {
            const author = CHARACTERS.find(c => c.id === m.authorId);
            return <MemoirCard key={m.id} memoir={m} author={author} onClick={() => navigate({ name: "character", id: m.authorId })} />;
          })}
        </div>
      </section>
    </main>
  );
}

/* ════════════════════════════════════════════════════════════
   VARIANT C — 다크 프리미엄 (캠프 야간 모드)
   ════════════════════════════════════════════════════════════ */
function CampVariantC({ navigate, CHARACTERS, FEATURED, LINEUP, CAMPAIGNS, MEMOIRS, NEWS }) {
  return (
    <main>
      {/* Dark hero band — 캠프파이어 야간 톤 */}
      <section className="hero-grad-dark bg-runes-dark" style={{ position: "relative", overflow: "hidden", color: "white" }}>
        <div className="container" style={{ paddingTop: 80, paddingBottom: 96, position: "relative" }}>
          <div style={{ display: "flex", alignItems: "center", gap: 12, marginBottom: 24 }}>
            <span style={{
              fontSize: 11, fontWeight: 700, letterSpacing: "0.12em",
              padding: "5px 10px",
              border: "1px solid rgba(255,255,255,0.2)",
              borderRadius: 999,
              color: "rgba(255,255,255,0.85)"
            }}>NIGHT AT CAMP</span>
            <span style={{ fontSize: 13, color: "rgba(255,255,255,0.5)" }}>
              모닥불 옆 · 캠프 보급품 충분 · 위더스가 책장 옆에 있습니다
            </span>
          </div>

          <div style={{ display: "grid", gridTemplateColumns: "1.4fr 1fr", gap: 64, alignItems: "flex-end" }}>
            <div>
              <h1 style={{
                fontSize: 84, fontWeight: 800, lineHeight: 1.02, letterSpacing: "-0.04em",
                color: "white", margin: 0, fontFamily: "var(--font-serif-display)"
              }}>
                위브 전 영역,<br />
                <span style={{ color: "var(--weave-violet-bright)", fontStyle: "italic" }}>무제한 수강.</span>
              </h1>
              <p style={{ fontSize: 18, lineHeight: 1.6, color: "rgba(255,255,255,0.7)", marginTop: 28, maxWidth: 540 }}>
                긴 휴식 한 번이면 캐릭터 한 명을 정복합니다.<br />
                위브에 접속한 모든 모험가를 위한 프리미엄 비전 인강 — 위브스터디.
              </p>
              <div style={{ display: "flex", gap: 12, marginTop: 36, alignItems: "center" }}>
                <button className="btn btn-lg" style={{ background: "white", color: "var(--weave-ink)" }} onClick={() => navigate({ name: "origins" })}>
                  오리진 라인업 →
                </button>
                <button className="btn btn-lg" style={{ background: "transparent", color: "white", border: "1px solid rgba(255,255,255,0.3)" }} onClick={() => navigate({ name: "library" })}>
                  자나사의 만물 가이드
                </button>
              </div>
            </div>

            {/* Now playing card */}
            <div style={{
              background: "rgba(255,255,255,0.06)",
              backdropFilter: "blur(16px)",
              border: "1px solid rgba(255,255,255,0.12)",
              borderRadius: 20,
              padding: 24
            }}>
              <div style={{ fontSize: 11, fontWeight: 700, letterSpacing: "0.12em", color: "var(--weave-teal)", textTransform: "uppercase" }}>NOW IN SESSION</div>
              <div style={{ marginTop: 12, fontSize: 22, fontWeight: 700, color: "white", letterSpacing: "-0.02em" }}>
                본편 — 위브의 정점
              </div>
              <div style={{ fontSize: 13, color: "rgba(255,255,255,0.5)", marginTop: 4 }}>
                2막 진행 중 · 라스트 라이트 · 베스티 + 게일
              </div>
              <div className="progress" style={{ marginTop: 16, background: "rgba(255,255,255,0.1)" }}>
                <span style={{ width: "74%" }} />
              </div>
              <div style={{ display: "flex", justifyContent: "space-between", marginTop: 8, fontSize: 11, fontFamily: "var(--font-mono)", color: "rgba(255,255,255,0.5)" }}>
                <span>74% 진행</span>
                <span>다음 세션 · D-7</span>
              </div>

              <div className="weave-line" style={{ margin: "20px 0", opacity: 0.5 }} />

              <div style={{ display: "flex", gap: 8, flexWrap: "wrap" }}>
                {FEATURED.map(c => (
                  <button key={c.id} onClick={() => navigate({ name: "character", id: c.id })}
                          style={{ display: "flex", alignItems: "center", gap: 8, padding: "8px 12px",
                                   background: "rgba(255,255,255,0.06)", borderRadius: 999, color: "white", fontSize: 12, fontWeight: 600 }}>
                    <div style={{
                      width: 22, height: 22, borderRadius: 99,
                      background: `linear-gradient(135deg, ${c.portraitColors[0]}, ${c.portraitColors[1]})`,
                      fontSize: 10, fontWeight: 800, display: "flex", alignItems: "center", justifyContent: "center"
                    }}>{c.name[0]}</div>
                    {c.name}
                  </button>
                ))}
              </div>
            </div>
          </div>
        </div>

        {/* glow lines */}
        <div style={{
          position: "absolute", left: 0, right: 0, bottom: 0, height: 1,
          background: "linear-gradient(90deg, transparent, var(--weave-violet-bright), var(--weave-teal), transparent)",
          opacity: 0.5
        }} />
      </section>

      {/* Origin lineup — dark portrait grid */}
      <section style={{ background: "var(--weave-ink)", color: "white", padding: "96px 0" }}>
        <div className="container">
          <div className="sec-header">
            <div>
              <div className="sec-eyebrow" style={{ color: "var(--weave-teal)" }}>ORIGIN LINEUP</div>
              <div className="sec-title" style={{ color: "white" }}>오리진 라인업
                <small style={{ color: "rgba(255,255,255,0.5)" }}>당신의 캠프에 합류한 모험가들</small>
              </div>
            </div>
            <button className="sec-more" style={{ color: "rgba(255,255,255,0.7)" }} onClick={() => navigate({ name: "origins" })}>
              전체 보기 <Icon name="chevron-right" size={14} />
            </button>
          </div>
          <div style={{ display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: 20 }}>
            {LINEUP.map(c => <DarkOriginCard key={c.id} character={c} onClick={() => navigate({ name: "character", id: c.id })} />)}
          </div>
        </div>
      </section>

      {/* Light section — campaigns & memoirs */}
      <section className="container" style={{ paddingTop: 96 }}>
        <SectionTitle eyebrow="POPULAR CAMPAIGNS" title="인기 캠페인" action={
          <button className="sec-more" onClick={() => navigate({ name: "campaigns" })}>
            전체 커리큘럼 <Icon name="chevron-right" size={14} />
          </button>
        } />
        <div style={{ display: "grid", gridTemplateColumns: "repeat(2, 1fr)", gap: 20 }}>
          {CAMPAIGNS.slice(0, 4).map(c => (
            <CampaignSmallCard key={c.id} campaign={c} onClick={() => navigate({ name: "campaign", id: c.id })} />
          ))}
        </div>
      </section>

      <section className="container" style={{ paddingTop: 96 }}>
        <SectionTitle eyebrow="MEMOIRS" title="모험 회고" />
        <div style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 20 }}>
          {MEMOIRS.map(m => {
            const author = CHARACTERS.find(c => c.id === m.authorId);
            return <MemoirCard key={m.id} memoir={m} author={author} onClick={() => navigate({ name: "character", id: m.authorId })} />;
          })}
        </div>
      </section>
    </main>
  );
}

/* ════════════════════════════════════════════════════════════
   SUB-COMPONENTS (used by all variants)
   ════════════════════════════════════════════════════════════ */

function MiniStat({ label, value }) {
  return (
    <div style={{ textAlign: "center" }}>
      <div style={{ fontSize: 11, color: "var(--label-alternative)", fontWeight: 700, letterSpacing: "0.05em" }}>{label}</div>
      <div style={{ fontSize: 22, fontWeight: 800, color: "var(--weave-ink)", marginTop: 2, fontFamily: "var(--font-mono)" }}>{value}</div>
    </div>
  );
}

function BigStat({ label, value, sub }) {
  return (
    <div>
      <div style={{ fontSize: 12, fontWeight: 600, color: "var(--label-alternative)", letterSpacing: "0.05em" }}>{label}</div>
      <div style={{ display: "flex", alignItems: "baseline", gap: 4, marginTop: 4 }}>
        <span style={{ fontSize: 36, fontWeight: 800, color: "var(--weave-ink)", lineHeight: 1, letterSpacing: "-0.025em" }}>{value}</span>
        <span style={{ fontSize: 14, color: "var(--label-alternative)", fontWeight: 600 }}>{sub}</span>
      </div>
    </div>
  );
}

// Big "오리진 라인업" card — variant A
function OriginCard({ character, onClick }) {
  return (
    <button className="card card-hover" onClick={onClick} style={{ textAlign: "left", padding: 0, background: "white" }}>
      <div style={{ padding: 12 }}>
        <Portrait character={character} size="md" style={{ width: "100%", height: 240 }} />
      </div>
      <div style={{ padding: "4px 16px 20px" }}>
        <div style={{ display: "flex", alignItems: "center", gap: 6, marginBottom: 8 }}>
          <span className="badge badge-1ta">{character.rank.replace(" 1타", "")}</span>
          {character.isDreamju && <span className="badge badge-outline" style={{ fontSize: 10 }}>드림주</span>}
          {character.likes > 1500 && <span className="badge badge-hot">HOT</span>}
        </div>
        <div style={{ fontSize: 20, fontWeight: 800, color: "var(--weave-ink)", letterSpacing: "-0.02em" }}>
          {character.name}
          <span style={{ fontSize: 13, fontWeight: 500, color: "var(--label-alternative)", marginLeft: 6, letterSpacing: 0 }}>{character.nameEn}</span>
        </div>
        <div style={{ fontSize: 12, color: "var(--label-alternative)", marginTop: 4 }}>
          {character.race} · {character.class} · {character.bg}
        </div>
        <div style={{
          marginTop: 12, padding: 12,
          background: "var(--fill-normal)", borderRadius: 10,
          fontSize: 13, color: "var(--label-neutral)", fontWeight: 600,
          lineHeight: 1.45
        }}>
          "{character.catchphrase}"
        </div>
        <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginTop: 12 }}>
          <div style={{ display: "flex", alignItems: "center", gap: 6, fontSize: 12, color: "var(--label-alternative)" }}>
            <Icon name="heart-fill" size={12} color="#FF3D5A" />
            {character.likes.toLocaleString()}
          </div>
          <div style={{ display: "flex", alignItems: "center", gap: 4, fontSize: 13, color: "var(--weave-violet)", fontWeight: 700 }}>
            캐릭터 시트 <Icon name="chevron-right" size={12} color="var(--weave-violet)" />
          </div>
        </div>
      </div>
    </button>
  );
}

// Smaller variant for variant B
function OriginListRow({ character, onClick }) {
  return (
    <button className="card card-hover" onClick={onClick}
            style={{ display: "flex", gap: 16, padding: 16, textAlign: "left" }}>
      <Portrait character={character} size="sm" style={{ width: 96, height: 124, flexShrink: 0 }} showBadge={false} />
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ display: "flex", alignItems: "center", gap: 6, marginBottom: 8 }}>
          <span className="badge badge-1ta">{character.rank}</span>
          {character.isDreamju && <span className="badge badge-outline" style={{ fontSize: 10 }}>드림주</span>}
        </div>
        <div style={{ fontSize: 20, fontWeight: 800, color: "var(--weave-ink)" }}>
          {character.name}
          <span style={{ fontSize: 13, fontWeight: 500, color: "var(--label-alternative)", marginLeft: 6 }}>{character.nameEn}</span>
        </div>
        <div style={{ fontSize: 12, color: "var(--label-alternative)", marginTop: 4 }}>
          {character.race} · {character.class} · {character.bg}
        </div>
        <div style={{
          marginTop: 10, fontSize: 13, color: "var(--label-neutral)",
          fontWeight: 600, lineHeight: 1.45,
          overflow: "hidden",
          display: "-webkit-box",
          WebkitBoxOrient: "vertical", WebkitLineClamp: 2
        }}>"{character.catchphrase}"</div>
      </div>
    </button>
  );
}

// Dark variant origin card
function DarkOriginCard({ character, onClick }) {
  return (
    <button onClick={onClick} style={{
      background: "rgba(255,255,255,0.04)",
      border: "1px solid rgba(255,255,255,0.08)",
      borderRadius: 16, overflow: "hidden",
      textAlign: "left",
      transition: "transform 160ms, background 160ms, border-color 160ms",
      cursor: "pointer"
    }}
    onMouseEnter={e => {
      e.currentTarget.style.background = "rgba(255,255,255,0.08)";
      e.currentTarget.style.borderColor = "rgba(255,255,255,0.2)";
      e.currentTarget.style.transform = "translateY(-2px)";
    }}
    onMouseLeave={e => {
      e.currentTarget.style.background = "rgba(255,255,255,0.04)";
      e.currentTarget.style.borderColor = "rgba(255,255,255,0.08)";
      e.currentTarget.style.transform = "translateY(0)";
    }}>
      <Portrait character={character} size="md" style={{ width: "100%", height: 260 }} />
      <div style={{ padding: 16 }}>
        <div style={{ fontSize: 11, fontWeight: 700, color: "var(--weave-teal)", letterSpacing: "0.05em" }}>{character.rank}</div>
        <div style={{ fontSize: 20, fontWeight: 800, color: "white", marginTop: 4 }}>{character.name}</div>
        <div style={{ fontSize: 12, color: "rgba(255,255,255,0.5)", marginTop: 4 }}>
          {character.race} · {character.class}
        </div>
        <p style={{ fontSize: 12, color: "rgba(255,255,255,0.6)", marginTop: 10, lineHeight: 1.5 }}>"{character.catchphrase}"</p>
      </div>
    </button>
  );
}

function StackedPortrait({ c, pos, hero, onClick }) {
  const [hover, setHover] = useStateCamp(false);
  return (
    <button onClick={onClick}
            onMouseEnter={() => setHover(true)}
            onMouseLeave={() => setHover(false)}
            style={{
      position: "absolute",
      left: pos.left, top: pos.top, zIndex: hover ? 10 : pos.z,
      transform: `rotate(${pos.rotate}deg) ${hover ? "scale(1.04)" : "scale(1)"}`,
      transition: "transform 220ms cubic-bezier(0.4,0,0.2,1)",
      padding: 12,
      background: "white", borderRadius: 18,
      boxShadow: hover ? "var(--shadow-xl)" : "var(--shadow-lg)",
      cursor: "pointer"
    }}>
      <Portrait character={c} size={hero ? "lg" : "md"} />
      <div style={{ padding: "12px 4px 4px" }}>
        <div style={{ fontSize: 11, fontWeight: 700, color: "var(--weave-violet)", letterSpacing: "0.05em" }}>{c.rank}</div>
        <div style={{ fontSize: hero ? 22 : 18, fontWeight: 800, color: "var(--weave-ink)" }}>{c.name}</div>
      </div>
    </button>
  );
}

function CampaignFeatureCard({ campaign, onClick }) {
  const { CHARACTERS } = window.WS_DATA;
  return (
    <button className="card card-hover" onClick={onClick} style={{ textAlign: "left", padding: 0, gridRow: "span 2" }}>
      <div style={{
        height: 280, position: "relative",
        background: "linear-gradient(135deg, var(--weave-violet) 0%, var(--weave-violet-strong) 60%, var(--weave-ink) 100%)",
        padding: 32, color: "white",
        display: "flex", flexDirection: "column", justifyContent: "space-between"
      }}>
        <div style={{
          position: "absolute", inset: 0,
          backgroundImage: "radial-gradient(circle, rgba(255,255,255,0.10) 1px, transparent 1.5px)",
          backgroundSize: "26px 26px", opacity: 0.6
        }} />
        <div style={{ position: "relative" }}>
          <span className="tag tag-ink" style={{ background: "rgba(0,0,0,0.3)", color: "white", border: "1px solid rgba(255,255,255,0.2)" }}>
            {campaign.acts.length}막 구성
          </span>
        </div>
        <div style={{ position: "relative" }}>
          <div style={{ fontSize: 14, opacity: 0.7, marginBottom: 6 }}>{campaign.nameSub}</div>
          <div style={{ fontSize: 32, fontWeight: 800, letterSpacing: "-0.025em", fontFamily: "var(--font-serif-display)" }}>{campaign.name}</div>
          <div style={{ fontSize: 13, opacity: 0.8, marginTop: 6 }}>{campaign.tagline}</div>
        </div>
      </div>
      <div style={{ padding: 24 }}>
        <div className="progress"><span style={{ width: `${campaign.progress * 100}%` }} /></div>
        <div style={{ display: "flex", justifyContent: "space-between", marginTop: 8, fontSize: 12 }}>
          <span style={{ color: "var(--label-alternative)" }}>전체 진행도</span>
          <span style={{ fontWeight: 700, color: "var(--weave-violet)", fontFamily: "var(--font-mono)" }}>{Math.round(campaign.progress * 100)}%</span>
        </div>
        <div style={{ marginTop: 16, display: "flex", alignItems: "center", gap: 8 }}>
          <span style={{ fontSize: 12, color: "var(--label-alternative)" }}>등장 캐릭터</span>
          <div style={{ display: "flex" }}>
            {campaign.members.map((id, i) => {
              const c = CHARACTERS.find(x => x.id === id);
              if (!c) return null;
              return (
                <div key={id} style={{
                  width: 28, height: 28, borderRadius: 99,
                  background: `linear-gradient(135deg, ${c.portraitColors[0]}, ${c.portraitColors[1]})`,
                  color: "white", display: "flex", alignItems: "center", justifyContent: "center",
                  fontSize: 11, fontWeight: 800,
                  border: "2px solid white",
                  marginLeft: i === 0 ? 0 : -8
                }}>{c.name[0]}</div>
              );
            })}
          </div>
        </div>
      </div>
    </button>
  );
}

function CampaignSmallCard({ campaign, onClick }) {
  const { CHARACTERS } = window.WS_DATA;
  return (
    <button className="card card-hover" onClick={onClick} style={{ textAlign: "left", padding: 20, display: "block" }}>
      <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 12 }}>
        <span className="tag tag-violet">{campaign.acts.length}막</span>
        {campaign.progress >= 1 && <span className="tag tag-teal">수료 완료</span>}
        {campaign.progress < 1 && campaign.progress > 0 && <span className="tag tag-gold">진행 중</span>}
      </div>
      <div style={{ fontSize: 18, fontWeight: 800, color: "var(--weave-ink)", letterSpacing: "-0.02em" }}>{campaign.name}</div>
      <div style={{ fontSize: 12, color: "var(--label-alternative)", marginTop: 4 }}>{campaign.nameSub}</div>
      <p style={{ fontSize: 13, color: "var(--label-neutral)", marginTop: 12, marginBottom: 16, lineHeight: 1.5 }}>{campaign.tagline}</p>
      <div className="progress"><span style={{ width: `${campaign.progress * 100}%` }} /></div>
      <div style={{ display: "flex", justifyContent: "space-between", marginTop: 10, fontSize: 12 }}>
        <span style={{ color: "var(--label-alternative)" }}>{campaign.members.length}명 등장</span>
        <span style={{ fontWeight: 700, color: "var(--weave-violet)", fontFamily: "var(--font-mono)" }}>{Math.round(campaign.progress * 100)}%</span>
      </div>
    </button>
  );
}

function AdventureLogCard({ title, tag, author, date, colorKey }) {
  return (
    <button className="card card-hover" style={{ textAlign: "left", padding: 0, background: "white" }}>
      <div className={`portrait ${colorKey}`} style={{ height: 160 }}>
        <div className="portrait-rune" />
        <div style={{ position: "relative", fontSize: 11, fontWeight: 700, color: "white", letterSpacing: "0.05em" }}>
          {tag}
        </div>
      </div>
      <div style={{ padding: 20 }}>
        <div style={{ fontSize: 17, fontWeight: 700, color: "var(--weave-ink)", lineHeight: 1.4, letterSpacing: "-0.02em" }}>{title}</div>
        <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginTop: 12, fontSize: 12, color: "var(--label-alternative)" }}>
          <span>{author} 작성</span>
          <span style={{ fontFamily: "var(--font-mono)" }}>{date}</span>
        </div>
      </div>
    </button>
  );
}

function MemoirCard({ memoir, author, onClick }) {
  return (
    <button className="card card-hover" onClick={onClick}
            style={{ background: "white", textAlign: "left", padding: 24, display: "flex", flexDirection: "column", gap: 12 }}>
      <div style={{ display: "flex", alignItems: "center", gap: 4 }}>
        {Array.from({ length: 5 }).map((_, i) => (
          <Icon key={i} name={i < memoir.rating ? "star-fill" : "star"} size={16} color="#F5C45B" />
        ))}
        <span style={{ marginLeft: 6, fontSize: 12, fontWeight: 700, color: "var(--label-alternative)" }}>5.0</span>
      </div>
      <div style={{ fontSize: 18, fontWeight: 800, color: "var(--weave-ink)", lineHeight: 1.35, letterSpacing: "-0.02em" }}>
        "{memoir.title}"
      </div>
      <p style={{ fontSize: 13, color: "var(--label-neutral)", lineHeight: 1.6, margin: 0 }}>{memoir.excerpt}</p>
      <div style={{ display: "flex", gap: 6, flexWrap: "wrap" }}>
        {memoir.tags.map(t => <span key={t} className="tag" style={{ fontSize: 11 }}>{t}</span>)}
      </div>
      <div style={{ marginTop: "auto", paddingTop: 12, borderTop: "1px solid var(--line-normal)", display: "flex", alignItems: "center", gap: 10 }}>
        {author && <div style={{
          width: 36, height: 36, borderRadius: 99,
          background: `linear-gradient(135deg, ${author.portraitColors[0]}, ${author.portraitColors[1]})`,
          color: "white", display: "flex", alignItems: "center", justifyContent: "center", fontSize: 14, fontWeight: 800
        }}>{author.name[0]}</div>}
        <div>
          <div style={{ fontSize: 13, fontWeight: 700, color: "var(--weave-ink)" }}>{author?.name} 모험가</div>
          <div style={{ fontSize: 11, color: "var(--label-alternative)" }}>{author?.class} · {author?.rank}</div>
        </div>
      </div>
    </button>
  );
}

window.Camp = Camp;
