// app.jsx — 삼떱살롱 (gethering) v3 — 모바일 랜딩페이지

const { useState, useEffect } = React;

const TOKENS = {
  green: '#50FF8A',
  black: '#000000',
  white: '#FFFFFF'
};

// ─────────────────────────────────────────────
// SECTION 1 — 로고 (애니메이션)
// ─────────────────────────────────────────────
function LogoSection({ logoAnim }) {
  return (
    <section
      data-screen-label="01 Logo"
      style={{
        background: TOKENS.green,
        padding: '0 0 0',
        position: 'relative',
        overflow: 'hidden'
      }}>
      <div
        className={logoAnim ? 'pop-in' : ''}
        style={{
          width: '92%',
          margin: '0 auto',
          marginTop: -6,
          marginBottom: 8
        }}>
        <img
          src="assets/logo-with-character.png"
          alt="삼떱살롱"
          style={{
            width: '100%',
            height: 'auto',
            display: 'block',
            userSelect: 'none'
          }}
          draggable={false} />
      </div>
    </section>
  );
}

// ─────────────────────────────────────────────
// SECTION 2 — 전광판 마퀴
// ─────────────────────────────────────────────
function MarqueeSection() {
  return (
    <section
      data-screen-label="02 Marquee"
      style={{
        background: TOKENS.black,
        padding: '18px 0',
        overflow: 'hidden',
        position: 'relative'
      }}>
      <div className="marquee-track-img">
        <img src="assets/marquee-text.png" alt="" className="marquee-img" draggable={false} />
        <img src="assets/marquee-text.png" alt="" className="marquee-img" draggable={false} aria-hidden="true" />
      </div>
    </section>
  );
}

// ─────────────────────────────────────────────
// SECTION 3 — 05.21 이벤트 + 카운트다운
// ─────────────────────────────────────────────
function EventSection({ targetDate, planeFrame }) {
  const [now, setNow] = useState(Date.now());
  useEffect(() => {
    const id = setInterval(() => setNow(Date.now()), 1000);
    return () => clearInterval(id);
  }, []);

  const target = new Date(targetDate).getTime();
  const diff = Math.max(0, target - now);
  const days = Math.floor(diff / (1000 * 60 * 60 * 24));
  const hours = Math.floor(diff / (1000 * 60 * 60) % 24);
  const mins = Math.floor(diff / (1000 * 60) % 60);
  const secs = Math.floor(diff / 1000 % 60);

  const pad = (n) => String(n).padStart(2, '0');

  return (
    <section
      data-screen-label="03 Event 05.21"
      data-event-section
      style={{
        background: TOKENS.green,
        padding: '50px 0 40px',
        textAlign: 'center',
        position: 'relative',
        overflow: 'visible'
      }}>

      <div style={{
        fontFamily: '"Cafe24PROUP", "Galmuri11Bold", "Galmuri11", monospace',
        fontSize: 64,
        fontWeight: 400,
        color: TOKENS.black,
        lineHeight: 1,
        letterSpacing: '0.02em'
      }}>
        05.21
      </div>

      <div style={{
        fontFamily: '"Gaegu", "Cafe24Ssukssuk", cursive',
        fontSize: 44,
        fontWeight: 700,
        color: TOKENS.black,
        marginTop: 8,
        lineHeight: 1.1
      }}>
        목요일
      </div>

      <div style={{
        margin: '24px auto 0',
        width: 'fit-content',
        background: TOKENS.black,
        color: TOKENS.green,
        padding: '14px 18px 12px',
        borderRadius: 4,
        fontFamily: '"Galmuri11Bold", "Galmuri11", monospace',
        boxShadow: '4px 4px 0 0 rgba(0,0,0,0.15)'
      }}>
        <div style={{
          fontSize: 9,
          letterSpacing: '0.2em',
          opacity: 0.8,
          marginBottom: 6
        }}>
          D-COUNTDOWN
        </div>
        <div style={{
          display: 'flex',
          gap: 6,
          alignItems: 'baseline',
          fontSize: 26,
          lineHeight: 1,
          fontVariantNumeric: 'tabular-nums'
        }}>
          <CDUnit n={pad(days)} label="DAYS" />
          <span style={{ opacity: 0.5 }}>:</span>
          <CDUnit n={pad(hours)} label="HRS" />
          <span style={{ opacity: 0.5 }}>:</span>
          <CDUnit n={pad(mins)} label="MIN" />
          <span style={{ opacity: 0.5 }}>:</span>
          <CDUnit n={pad(secs)} label="SEC" blink />
        </div>
      </div>

      <div
        data-plane-host
        style={{
          marginTop: 28,
          width: '100%',
          position: 'relative',
          overflow: 'visible',
        }}
      >
        <img
          src="assets/character-tagline.png"
          alt="삼성역에서 전설의 시작을 만들어봐요"
          style={{
            width: '100%',
            height: 'auto',
            display: 'block',
            userSelect: 'none'
          }}
          draggable={false} />
        {planeFrame && (
          <div
            aria-hidden="true"
            style={{
              position: 'absolute',
              left: `${planeFrame.x}%`,
              top: `${planeFrame.y}%`,
              transform: `translate(-50%, -50%) rotate(${planeFrame.rot}deg)`,
              opacity: planeFrame.opacity,
              pointerEvents: 'none',
              zIndex: 9999,
              mixBlendMode: 'multiply',
              willChange: 'top, left, transform, opacity',
            }}
          >
            <PaperPlane size={48} />
          </div>
        )}
      </div>
    </section>
  );
}

function PaperPlane({ size = 48 }) {
  return (
    <svg width={size} height={size * 0.7} viewBox="0 0 100 70" fill="none" style={{ overflow: 'visible' }}>
      <path d="M 18 38 Q 5 42 -25 50" stroke="#000" strokeWidth="2" strokeDasharray="3 5" strokeLinecap="round" fill="none" opacity="0.55" />
      <path d="M 5 30 L 95 8 L 50 36 Z" fill="#ffffff" stroke="#000" strokeWidth="2" strokeLinejoin="round" />
      <path d="M 5 30 L 50 36 L 35 58 Z" fill="#000" stroke="#000" strokeWidth="2" strokeLinejoin="round" />
      <path d="M 50 36 L 95 8 L 35 58 Z" fill="#999" stroke="#000" strokeWidth="2" strokeLinejoin="round" />
      <path d="M 50 36 L 95 8" stroke="#000" strokeWidth="2" strokeLinecap="round" />
    </svg>
  );
}

function CDUnit({ n, label, blink = false }) {
  return (
    <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 3 }}>
      <span className={blink ? 'cd-blink' : ''} style={{ fontFamily: '"Cafe24PROUP", "Galmuri11Bold", monospace' }}>{n}</span>
      <span style={{ fontSize: 7, letterSpacing: '0.15em', opacity: 0.7 }}>{label}</span>
    </div>
  );
}

// ─────────────────────────────────────────────
// SECTION 4 — Why부터 끝까지
// ─────────────────────────────────────────────
function RestSection() {
  const words = ['부딪히고', '협력하고', '합치고'];
  const oneSet = [];
  for (let i = 0; i < 6; i++) {
    words.forEach((w, idx) => {
      oneSet.push({ kind: 'word', text: w, key: `${i}-${idx}` });
      oneSet.push({ kind: 'sep', key: `${i}-${idx}-s` });
    });
  }
  return (
    <section data-screen-label="04 Rest (image)" style={{ background: TOKENS.black, lineHeight: 0 }}>
      <img
        src="assets/section-why-top.png"
        alt="Why 우리가 모이는 이유"
        style={{ display: 'block', width: '100%', height: 'auto', userSelect: 'none' }}
        draggable={false}
      />
      <div style={{ background: TOKENS.green, padding: '16px 16px', lineHeight: 0 }}>
        <img
          src="assets/why-illustration.png"
          alt="디자이너 개발자 마케터 크리에이터 충돌"
          style={{ width: '100%', height: 'auto', display: 'block', userSelect: 'none' }}
          draggable={false}
        />
      </div>
      <img
        src="assets/section-why-bottom.png"
        alt="우리의 의견충돌은 결함이 아니라 기능이에요"
        style={{ display: 'block', width: '100%', height: 'auto', userSelect: 'none' }}
        draggable={false}
      />
      <div style={{ background: TOKENS.black, padding: '20px 32px 56px', lineHeight: 0 }}>
        <img
          src="assets/closing-text.png"
          alt="타협하지 마세요 부딪히고 다시 합쳐보세요"
          style={{ width: '100%', height: 'auto', display: 'block', userSelect: 'none' }}
          draggable={false}
        />
      </div>
      <HowSection />
      <TimelineSection />
      <WhoSection />
      <div style={{ background: TOKENS.green, padding: '14px 0', overflow: 'hidden', position: 'relative', lineHeight: 1 }}>
        <div className="marquee-track-text">
          {[...oneSet.map(o => ({...o, key: o.key + '-a'})), ...oneSet.map(o => ({...o, key: o.key + '-b'}))].map((it) => (
            it.kind === 'word'
              ? <span key={it.key} className="marquee-text-item">{it.text}</span>
              : <span key={it.key} className="marquee-text-sep" aria-hidden="true">·</span>
          ))}
        </div>
      </div>
      <div style={{ background: TOKENS.black, height: 40 }} aria-hidden="true" />
      <FAQSection />
      <ApplySection />
    </section>
  );
}

// ─────────────────────────────────────────────
// SECTION 5 — How (3 step)
// ─────────────────────────────────────────────
function HowSection() {
  const steps = [
    { n: '01', title: '한 팀 4명', sub: '디자이너 / 개발자 / 마케터 / 크리에이터' },
    { n: '02', title: '2시간 → 1 MVP', sub: '아이디어 → 프로토타입 → 팀장 발표까지' },
    { n: '03', title: '사업의 현실감', sub: '화이트보드 말고, 진짜 부딪히는 협업' },
  ];
  return (
    <section
      data-screen-label="05 How"
      style={{ background: TOKENS.green, color: TOKENS.black, padding: '40px 24px 48px' }}
    >
      <div style={{ textAlign: 'center', marginBottom: 32, lineHeight: 0, display: 'flex', justifyContent: 'center', alignItems: 'baseline', gap: 4 }}>
        <img
          src="assets/header-how.png"
          alt="How"
          style={{ height: 36, width: 'auto', userSelect: 'none' }}
          draggable={false}
        />
        <span style={{
          fontFamily: '"Cafe24PROUP", "Galmuri11Bold", monospace',
          fontSize: 36,
          color: TOKENS.black,
          lineHeight: 1,
        }}>?</span>
      </div>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 20 }}>
        {steps.map((s) => (
          <div key={s.n} style={{
            border: `2px solid ${TOKENS.black}`,
            borderRadius: 4,
            padding: '18px 18px 16px',
            background: TOKENS.black,
            color: '#fff',
            position: 'relative',
          }}>
            <div style={{
              fontFamily: '"Galmuri11Bold", "Galmuri11", monospace',
              fontSize: 14,
              opacity: 0.7,
              marginBottom: 14,
              letterSpacing: '0.08em',
            }}>{s.n}</div>
            <div style={{
              fontFamily: '"Cafe24PROUP", "Cafe24Ssukssuk", "Gaegu", system-ui',
              fontSize: 22,
              fontWeight: 700,
              lineHeight: 1.25,
              marginBottom: 6,
            }}>{s.title}</div>
            <div style={{ fontSize: 13, lineHeight: 1.5, opacity: 0.85 }}>{s.sub}</div>
          </div>
        ))}
      </div>
    </section>
  );
}

// ─────────────────────────────────────────────
// SECTION 5b — Timeline (19:30 ~ 22:30)
// ─────────────────────────────────────────────
function TimelineSection() {
  const items = [
    { time: '19:30', dur: '10m', title: '팀빌딩',            sub: '자동 매칭, 명함 대신 닉네임' },
    { time: '19:40', dur: '15m', title: '아이스브레이킹',    sub: '5분 미니토론, 팀장 정하기' },
    { time: '19:55', dur: '20m', title: 'BM / 아이템 결정',  sub: '제조 / SaaS / 플랫폼 등 아이템 자율, 한 줄로 정의' },
    { time: '20:15', dur: '90m', title: 'MVP 빌드 타임',     flame: true, sub: '디자인 / 코드 / 카피 / 홍보 동시 진행 — 충돌? 부딪히면서 쌓아가보자구요' },
    { time: '21:45', dur: '5m',  title: '제출 컷오프',       sub: '렌더링 / PPT / 웹 / 영상 등 형식 자유' },
    { time: '21:50', dur: '40m', title: '공유 + 인사이트',   sub: '팀당 2~3분 발표, 피드백하기' },
  ];
  return (
    <section
      data-screen-label="05b Timeline"
      style={{ background: TOKENS.green, color: TOKENS.black, padding: '12px 24px 48px' }}
    >
      <div style={{ display: 'flex', justifyContent: 'center', marginBottom: 16 }}>
        <div style={{
          background: '#fff',
          border: `2px solid ${TOKENS.black}`,
          padding: '6px 18px',
          fontFamily: '"Galmuri11Bold", "Galmuri11", monospace',
          fontSize: 13,
          lineHeight: 1.2,
          letterSpacing: '0.12em',
          borderRadius: 2,
        }}>
          TIMELINE
        </div>
      </div>
      <div style={{
        textAlign: 'center',
        fontFamily: '"Cafe24Ssukssuk", "Gaegu", system-ui',
        fontSize: 17,
        fontWeight: 700,
        marginBottom: 28,
        lineHeight: 1.4,
      }}>
        우리의 3시간은 이렇게 흘러갑니다
      </div>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
        {items.map((it, i) => (
          <div key={i} style={{
            background: '#fff',
            border: `2px solid ${TOKENS.black}`,
            borderRadius: 4,
            padding: '14px 16px 14px',
            display: 'flex',
            gap: 14,
            alignItems: 'flex-start',
          }}>
            <div style={{
              flexShrink: 0,
              minWidth: 64,
              display: 'flex',
              flexDirection: 'column',
              alignItems: 'flex-start',
              gap: 6,
              paddingTop: 1,
            }}>
              <div style={{
                fontFamily: '"Galmuri11Bold", "Galmuri11", monospace',
                fontSize: 18,
                lineHeight: 1.1,
                letterSpacing: '0.02em',
              }}>{it.time}</div>
              <div style={{
                display: 'flex',
                alignItems: 'center',
                gap: 4,
                fontFamily: '"Galmuri11", monospace',
                fontSize: 11,
                lineHeight: 1.2,
                opacity: 0.65,
                letterSpacing: '0.04em',
              }}>
                <span>{it.dur}</span>
                {it.flame && <span style={{ fontSize: 16, lineHeight: 1 }}>🔥</span>}
              </div>
            </div>
            <div style={{
              width: 1.5,
              alignSelf: 'stretch',
              background: TOKENS.black,
              opacity: 0.3,
              flexShrink: 0,
            }} />
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{
                fontFamily: '"Cafe24Ssukssuk", "Gaegu", system-ui',
                fontSize: 21,
                fontWeight: 700,
                lineHeight: 1.2,
                marginBottom: 6,
              }}>{it.title}</div>
              <div style={{ fontSize: 12, lineHeight: 1.5, opacity: 0.7 }}>{it.sub}</div>
            </div>
          </div>
        ))}
      </div>
      <div style={{
        marginTop: 18,
        textAlign: 'center',
        fontFamily: '"Cafe24Ssukssuk", "Gaegu", system-ui',
        fontSize: 14,
        fontWeight: 700,
        opacity: 0.85,
      }}>
        이후 자유시간 ~
      </div>
    </section>
  );
}

// ─────────────────────────────────────────────
// SECTION 6 — Who? (4 직군)
// ─────────────────────────────────────────────
function WhoSection() {
  return (
    <section
      data-screen-label="06 Who"
      style={{ background: TOKENS.black, color: TOKENS.green, padding: '48px 24px 0' }}
    >
      <div style={{ textAlign: 'center', marginBottom: 32, lineHeight: 0 }}>
        <img
          src="assets/header-who.png"
          alt="Who?"
          style={{ height: 36, width: 'auto', display: 'inline-block', userSelect: 'none' }}
          draggable={false}
        />
      </div>
      <div style={{ marginBottom: 16, lineHeight: 0 }}>
        <img src="assets/who-designer.jpg" alt="DESIGNER — 화면/흐름/경험/감각" style={{ display: 'block', width: '100%', height: 'auto', userSelect: 'none' }} draggable={false} />
      </div>
      <div style={{ marginBottom: 16, lineHeight: 0 }}>
        <img src="assets/who-developer.jpg" alt="DEVELOPER — 기능/작동/현실" style={{ display: 'block', width: '100%', height: 'auto', userSelect: 'none' }} draggable={false} />
      </div>
      <div style={{ marginBottom: 16, lineHeight: 0 }}>
        <img src="assets/who-marketer.jpg" alt="MARKETER — 고객/시장/숫자" style={{ display: 'block', width: '100%', height: 'auto', userSelect: 'none' }} draggable={false} />
      </div>
      <div style={{ marginBottom: 0, lineHeight: 0 }}>
        <img src="assets/who-creator.jpg" alt="CREATOR — 스토리/카피/컨텐츠" style={{ display: 'block', width: '100%', height: 'auto', userSelect: 'none' }} draggable={false} />
      </div>
      <div style={{ height: 40 }} aria-hidden="true" />
    </section>
  );
}

// ─────────────────────────────────────────────
// SECTION 7 — FAQ (아코디언)
// ─────────────────────────────────────────────
function FAQItem({ q, a, isOpen, onToggle }) {
  return (
    <div style={{ borderBottom: `1.5px solid ${TOKENS.black}` }}>
      <button
        onClick={onToggle}
        style={{
          width: '100%',
          background: 'transparent',
          border: 'none',
          padding: '16px 4px',
          textAlign: 'left',
          display: 'flex',
          alignItems: 'flex-start',
          justifyContent: 'space-between',
          gap: 12,
          cursor: 'pointer',
          color: TOKENS.black,
          fontFamily: '"Pretendard", "Pretendard Variable", system-ui, sans-serif',
          fontSize: 15,
          fontWeight: 600,
          lineHeight: 1.4,
        }}
      >
        <span>{q}</span>
        <span style={{
          fontFamily: '"Galmuri11Bold", monospace',
          fontSize: 18,
          flexShrink: 0,
          transform: isOpen ? 'rotate(45deg)' : 'rotate(0deg)',
          transition: 'transform 0.2s',
        }}>+</span>
      </button>
      <div style={{
        maxHeight: isOpen ? 200 : 0,
        overflow: 'hidden',
        transition: 'max-height 0.3s ease',
      }}>
        <div style={{
          padding: '0 4px 16px',
          fontSize: 13,
          lineHeight: 1.6,
          color: TOKENS.black,
          opacity: 0.85,
          fontFamily: '"Pretendard", "Pretendard Variable", system-ui, sans-serif',
          fontWeight: 400,
        }}>{a}</div>
      </div>
    </div>
  );
}

function FAQSection() {
  const [openIdx, setOpenIdx] = useState(null);
  const faqs = [
    { q: '꼭 4직군 중 하나여야 하나요?', a: '네, 디자이너 / 개발자 / 마케터 / 크리에이터 중 본인이 가장 잘 맡을 수 있는 역할을 선택해주세요. 기획/PM 등은 그날 팀에서 자연스럽게 분담합니다.' },
    { q: '결과물의 형식은 정해져 있나요?', a: '아니요. 영상, 슬라이드, 라이브 데모, 프로토타입 — 무엇이든 OK. 2시간 안에 "보여줄 수 있는 한 개"만 만들어 오시면 됩니다.' },
    { q: '혼자 와도 되나요?', a: '네, 혼자 오시는 분이 더 많아요. 현장에서 직군별로 매칭해서 새 팀을 짜드립니다.' },
    { q: '환불 정책은요?', a: '5/14까지는 100% 환불 가능합니다. 그 이후에는 환불이 어려워요(현장 운영비 때문).' },
    { q: '준비물은 뭔가요?', a: '본인의 작업 도구(노트북, 카메라 등). 음료/간식은 현장에 준비되어 있어요.' },
    { q: '진짜로 싸워도 되나요?', a: '되도록 부딪히세요. 다만 사람이 아니라 아이디어와 부딪히기. 끝나고 같이 맥주 한잔까지가 한 세트입니다.' },
  ];
  return (
    <section
      data-screen-label="07 FAQ"
      style={{ background: TOKENS.green, padding: '40px 24px 44px', color: TOKENS.black }}
    >
      <div style={{ textAlign: 'center', marginBottom: 24, lineHeight: 0 }}>
        <img
          src="assets/header-faq.png"
          alt="FAQ"
          style={{ height: 36, width: 'auto', display: 'inline-block', userSelect: 'none' }}
          draggable={false}
        />
      </div>
      <div style={{ borderTop: `1.5px solid ${TOKENS.black}` }}>
        {faqs.map((f, i) => (
          <FAQItem
            key={i}
            q={f.q}
            a={f.a}
            isOpen={openIdx === i}
            onToggle={() => setOpenIdx(openIdx === i ? null : i)}
          />
        ))}
      </div>
    </section>
  );
}

// ─────────────────────────────────────────────
// SECTION 8 — Apply (폼 + CTA)
// ─────────────────────────────────────────────
function ApplySection() {
  const [form, setForm] = useState({
    name: '',
    contact: '',
    role: '',
    bio: '',
    agree: false,
  });
  const [submitted, setSubmitted] = useState(false);
  const inputBase = {
    width: '100%',
    background: '#50FF8A',
    border: `1.5px solid ${TOKENS.green}`,
    color: TOKENS.black,
    padding: '12px 14px',
    fontSize: 14,
    fontFamily: '"Pretendard", "Pretendard Variable", system-ui, sans-serif',
    boxSizing: 'border-box',
    borderRadius: 2,
    outline: 'none',
  };
  const labelStyle = {
    display: 'block',
    fontFamily: '"Galmuri11", monospace',
    fontSize: 11,
    letterSpacing: '0.08em',
    color: TOKENS.green,
    marginBottom: 20,
    opacity: 0.85,
  };

  const onSubmit = (e) => {
    e.preventDefault();
    if (!form.name || !form.contact || !form.role || !form.agree) {
      alert('이름 / 연락처 / 직책 / 동의는 필수입니다.');
      return;
    }
    if (typeof window.sendInfraumLead === 'function') {
      window.sendInfraumLead({
        name: form.name,
        contact: form.contact,
        role: form.role,
        bio: form.bio,
      });
    }
    setSubmitted(true);
  };

  if (submitted) {
    return (
      <section
        data-screen-label="08 Apply (done)"
        style={{
          background: TOKENS.black,
          color: TOKENS.green,
          padding: '60px 24px 80px',
          textAlign: 'center',
        }}
      >
        <div style={{
          fontFamily: '"Galmuri11Bold", monospace',
          fontSize: 32,
          marginBottom: 16,
          letterSpacing: '0.04em',
        }}>
          신청 완료!
        </div>
        <div style={{ fontSize: 14, lineHeight: 1.6, opacity: 0.85 }}>
          제출 후 카카오톡으로<br/>입금 안내가 발송됩니다.<br/>
          <span style={{ color: '#fff', fontWeight: 700 }}>5/14까지 100% 환불</span>
        </div>
      </section>
    );
  }

  return (
    <section
      data-screen-label="08 Apply"
      id="apply-section"
      style={{ background: TOKENS.black, color: TOKENS.green, padding: '48px 24px 64px' }}
    >
      <div style={{ textAlign: 'center', marginBottom: 28, lineHeight: 0 }}>
        <img
          src="assets/header-apply.png"
          alt="APPLY"
          style={{ height: 36, width: 'auto', display: 'inline-block', userSelect: 'none' }}
          draggable={false}
        />
      </div>
      <form onSubmit={onSubmit} style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
        <div>
          <label style={labelStyle}>NAME</label>
          <input
            style={inputBase}
            value={form.name}
            onChange={(e) => setForm({ ...form, name: e.target.value })}
            placeholder="이름"
          />
        </div>
        <div>
          <label style={labelStyle}>CONTACT</label>
          <input
            style={inputBase}
            value={form.contact}
            onChange={(e) => setForm({ ...form, contact: e.target.value })}
            placeholder="010-0000-0000"
          />
        </div>
        <div>
          <label style={labelStyle}>ROLE</label>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8 }}>
            {['디자이너', '개발자', '마케터', '크리에이터'].map((r) => (
              <button
                type="button"
                key={r}
                onClick={() => setForm({ ...form, role: r })}
                style={{
                  background: form.role === r ? TOKENS.black : TOKENS.green,
                  color: form.role === r ? TOKENS.green : TOKENS.black,
                  border: `1.5px solid ${TOKENS.green}`,
                  padding: '10px 0',
                  fontSize: 13,
                  fontFamily: '"Cafe24Ssukssuk", system-ui',
                  fontWeight: 700,
                  borderRadius: 2,
                  cursor: 'pointer',
                  transition: 'all 0.15s',
                }}
              >
                {r}
              </button>
            ))}
          </div>
        </div>
        <div>
          <label style={labelStyle}>한 줄 자기소개</label>
          <input
            style={inputBase}
            value={form.bio}
            onChange={(e) => setForm({ ...form, bio: e.target.value })}
            placeholder="저는 ___입니다."
          />
        </div>
        <label style={{
          display: 'flex',
          alignItems: 'flex-start',
          gap: 10,
          cursor: 'pointer',
          fontSize: 12,
          lineHeight: 1.5,
          color: TOKENS.green,
          opacity: 0.9,
          marginTop: 4,
        }}>
          <input
            type="checkbox"
            checked={form.agree}
            onChange={(e) => setForm({ ...form, agree: e.target.checked })}
            style={{
              accentColor: TOKENS.green,
              width: 16,
              height: 16,
              marginTop: 1,
              flexShrink: 0,
            }}
          />
          <span>
            의견충돌과 즉흥 협업이 발생할 수 있음에 동의하며, 개인정보(이름·연락처) 수집·이용에 동의합니다.
          </span>
        </label>
        <button
          type="submit"
          style={{
            marginTop: 12,
            background: TOKENS.green,
            color: TOKENS.black,
            border: 'none',
            padding: '18px 0',
            fontFamily: '"Pretendard", system-ui, sans-serif',
            fontSize: 17,
            letterSpacing: '0.01em',
            borderRadius: 2,
            cursor: 'pointer',
            fontWeight: 700,
            display: 'inline-flex',
            alignItems: 'center',
            justifyContent: 'center',
            gap: 8,
          }}
        >
          <span>신청 제출하기</span>
          <span style={{
            display: 'inline-flex',
            alignItems: 'baseline',
            gap: 2,
            fontWeight: 600,
            opacity: 0.85,
            fontFamily: '"Pretendard", system-ui, sans-serif',
          }}>
            <span>₩</span>
            <span>40,000</span>
          </span>
        </button>
        <div style={{
          fontSize: 11,
          lineHeight: 1.55,
          color: TOKENS.green,
          opacity: 0.6,
          textAlign: 'center',
          marginTop: 4,
        }}>
          제출 후 카카오톡으로 입금 안내가 갑니다 · 5/14까지 100% 환불
        </div>
      </form>
    </section>
  );
}

// ─────────────────────────────────────────────
// MAIN APP
// ─────────────────────────────────────────────
function App() {
  const [logoAnim, setLogoAnim] = useState(false);
  const [planeFrame, setPlaneFrame] = useState({ x: -10, y: 100, rot: -20, opacity: 0 });
  const [showFab, setShowFab] = useState(false);

  const TARGET_DATE = "2026-05-21T19:30:00";

  const scrollToApply = () => {
    const target = document.getElementById('apply-section');
    if (!target) return;
    const top = target.getBoundingClientRect().top + window.scrollY - 20;
    window.scrollTo({ top, behavior: 'smooth' });
  };

  useEffect(() => {
    const id = setTimeout(() => setLogoAnim(true), 100);
    return () => clearTimeout(id);
  }, []);

  useEffect(() => {
    const saved = parseFloat(localStorage.getItem('gethering:scrollTop') || '0');
    if (saved) window.scrollTo(0, saved);

    const calc = () => {
      localStorage.setItem('gethering:scrollTop', String(window.scrollY));

      const sec = document.querySelector('[data-plane-host]');
      if (sec) {
        const secRect = sec.getBoundingClientRect();
        const total = window.innerHeight + sec.offsetHeight;
        const traveled = window.innerHeight - secRect.top;
        const rawP = Math.max(0, Math.min(1, traveled / total));
        const START = 0.35, END = 0.85;
        const p = Math.max(0, Math.min(1, (rawP - START) / (END - START)));

        const x0=-25, x1=50, x2=125;
        const y0=68, y1=88, y2=20;
        const x = (1-p)*(1-p)*x0 + 2*(1-p)*p*x1 + p*p*x2;
        const y = (1-p)*(1-p)*y0 + 2*(1-p)*p*y1 + p*p*y2;
        const dx = 2*(1-p)*(x1-x0) + 2*p*(x2-x1);
        const dy = 2*(1-p)*(y1-y0) + 2*p*(y2-y1);
        const rot = Math.atan2(dy, dx) * 180 / Math.PI;
        const fade = 0.04;
        let opacity = 1;
        if (p < fade) opacity = p / fade;
        else if (p > 1 - fade) opacity = (1 - p) / fade;
        setPlaneFrame({ x, y, rot, opacity: Math.max(0, Math.min(1, opacity)) });
      }

      const apply = document.getElementById('apply-section');
      if (apply) {
        const scrolledPastTop = window.scrollY > 60;
        const applyRect = apply.getBoundingClientRect();
        const applyVisible = applyRect.top < window.innerHeight - 80;
        setShowFab(scrolledPastTop && !applyVisible);
      }
    };

    calc();
    window.addEventListener('scroll', calc, { passive: true });
    window.addEventListener('resize', calc);
    return () => {
      window.removeEventListener('scroll', calc);
      window.removeEventListener('resize', calc);
    };
  }, []);

  return (
    <div>
      <LogoSection logoAnim={logoAnim} />
      <MarqueeSection />
      <EventSection targetDate={TARGET_DATE} planeFrame={planeFrame} />
      <RestSection />

      <button
        onClick={scrollToApply}
        aria-label="신청하기"
        style={{
          position: 'fixed',
          right: 20,
          bottom: 24,
          zIndex: 9999,
          background: TOKENS.green,
          color: TOKENS.black,
          border: `2px solid ${TOKENS.black}`,
          borderRadius: 999,
          padding: '14px 22px',
          fontFamily: '"Cafe24Ssukssuk", "Gaegu", system-ui',
          fontWeight: 700,
          fontSize: 16,
          letterSpacing: '0.02em',
          cursor: 'pointer',
          boxShadow: '0 4px 0 0 rgba(0,0,0,0.9), 0 8px 24px rgba(0,0,0,0.35)',
          opacity: showFab ? 0.85 : 0,
          transform: showFab ? 'translateY(0) scale(1)' : 'translateY(12px) scale(0.92)',
          pointerEvents: showFab ? 'auto' : 'none',
          transition: 'opacity 0.25s ease, transform 0.25s cubic-bezier(0.34, 1.56, 0.64, 1)',
          userSelect: 'none',
          whiteSpace: 'nowrap',
        }}
      >
        신청하기 →
      </button>
    </div>
  );
}

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