// All page sections
const { useEffect, useRef, useState } = React;

// ---------- shared ----------
function MagBtn({ children, onClick, dark = true, style = {} }) {
  const ref = useRef(null);
  const onMove = (e) => {
    const r = ref.current.getBoundingClientRect();
    const x = e.clientX - r.left - r.width / 2;
    const y = e.clientY - r.top - r.height / 2;
    ref.current.style.transform = `translate(${x * 0.18}px, ${y * 0.22}px)`;
  };
  const onLeave = () => { ref.current.style.transform = ""; };
  return (
    <button
      ref={ref}
      onMouseMove={onMove}
      onMouseLeave={onLeave}
      onClick={onClick}
      className="mbtn"
      style={dark ? style : { ...style, background: "transparent", color: "var(--ink)", border: "1px solid var(--ink)" }}
    >
      {children}
    </button>
  );
}

function Eyebrow({ n, children }) {
  return (
    <div className="eyebrow">
      <span className="num">{n}</span>
      <span>{children}</span>
    </div>
  );
}

function Reveal({ children, as: As = "span" }) {
  return <As className="reveal"><span>{children}</span></As>;
}

function CountUp({ to, duration = 1800, prefix = "", suffix = "" }) {
  const [val, setVal] = useState(0);
  const ref = useRef(null);
  useEffect(() => {
    const obs = new IntersectionObserver(([e]) => {
      if (e.isIntersecting) {
        const start = performance.now();
        const step = (t) => {
          const p = Math.min(1, (t - start) / duration);
          const eased = 1 - Math.pow(1 - p, 3);
          setVal(Math.floor(eased * to));
          if (p < 1) requestAnimationFrame(step);
        };
        requestAnimationFrame(step);
        obs.disconnect();
      }
    }, { threshold: 0.5 });
    if (ref.current) obs.observe(ref.current);
    return () => obs.disconnect();
  }, [to]);
  const fmt = (n) => n.toLocaleString("en-US");
  return <span ref={ref}>{prefix}{fmt(val)}{suffix}</span>;
}

// ---------- HERO ----------
function Hero({ onScrollDown, onOpenResume }) {
  const date = new Date();
  const stamp = `${date.getFullYear()} · ${String(date.getMonth() + 1).padStart(2, "0")} · ${String(date.getDate()).padStart(2, "0")}`;
  return (
    <section style={{ paddingTop: 120, paddingBottom: 60, minHeight: "100vh" }}>
      <div className="container">
        <div style={{ display: "grid", gridTemplateColumns: "1.1fr .9fr", gap: 60, alignItems: "center" }} className="hero-grid">
          {/* left */}
          <div>
            <div className="mono" style={{ marginBottom: 28, color: "var(--mute)" }}>
              CN · {stamp} / Vol.01
            </div>
            <h1 className="serif" style={{ fontSize: "clamp(56px, 8.5vw, 132px)", lineHeight: .98, margin: 0, letterSpacing: "-.02em" }}>
              <div className="reveal"><span>作品集</span></div>
              <div className="reveal" style={{ marginTop: -6 }}><span>已经</span></div>
              <div className="reveal" style={{ marginTop: -6 }}><span>送达<span style={{ fontFamily: '"Instrument Serif",Georgia,serif', fontStyle: "italic", fontWeight: 400 }}>。</span></span></div>
            </h1>
            <p className="fu" style={{ maxWidth: 480, marginTop: 36, fontSize: 17, lineHeight: 1.75, color: "var(--ink-2)", fontFamily: '"Noto Serif SC","Songti SC","STSong","SimSun",serif', fontWeight: 400 }}>
              等待已结束。这是 <em style={{ fontFamily: '"Instrument Serif",Georgia,serif', fontSize: 19 }}>Shangguan Qingyue</em> 的内容作品集，
              里面装着拍摄、剪辑、文案与品牌策划的最新成果。
              请妥善开箱，从此处开始浏览。
            </p>

            {/* installer-style card */}
            <div className="fu card" style={{ marginTop: 44, padding: 28, maxWidth: 460 }}>
              <div className="mono" style={{ fontSize: 11, color: "var(--mute)", marginBottom: 18 }}>目录 · INDEX  v1.0</div>
              <ol style={{ listStyle: "none", padding: 0, margin: 0, display: "grid", gap: 12 }}>
                {[
                  ["关于我", "#about"],
                  ["公众号作品", "#wechat"],
                  ["视频与剪辑", "#video"],
                  ["品牌合作", "#brand"],
                ].map(([t, h], i) => (
                  <li key={t} style={{ display: "flex", alignItems: "center", gap: 14, fontFamily: '"Noto Serif SC","Songti SC","STSong","SimSun",serif', fontWeight: i === 0 ? 700 : 400, color: i === 0 ? "var(--ink)" : "var(--mute)" }}>
                    <span style={{ width: 22, height: 22, borderRadius: "50%", border: `1px solid ${i === 0 ? "var(--ink)" : "var(--line-2)"}`, display: "inline-flex", alignItems: "center", justifyContent: "center", fontFamily: '"JetBrains Mono",ui-monospace,"Courier New",monospace', fontSize: 10 }}>{i + 1}</span>
                    <a href={h} style={{ flex: 1, fontSize: 16 }}>{t}</a>
                  </li>
                ))}
              </ol>
              <div style={{ marginTop: 24, display: "flex", gap: 12, flexWrap: "wrap" }}>
                <MagBtn onClick={onScrollDown}>
                  <span>开始浏览</span>
                  <span className="arr">→</span>
                </MagBtn>
                <MagBtn onClick={onOpenResume} dark={false}>
                  <span>查看简历</span>
                  <span className="arr">↗</span>
                </MagBtn>
              </div>
            </div>
          </div>

          {/* right — kraft box */}
          <div style={{ position: "relative" }}>
            <window.KraftBox name="上官清越" subtitle="内容作品集" />
            <div className="mono" style={{ position: "absolute", left: 0, bottom: -8, fontSize: 11, color: "var(--mute)" }}>
              ↑ 跟随光标轻倾 · move pointer to tilt
            </div>
          </div>
        </div>
      </div>
    </section>
  );
}

// ---------- ABOUT ----------
function About({ stats }) {
  const skills = [
    "视频剪辑 / 剪映 · PR · FCPX",
    "实地拍摄 / 校园纪实 · 旅拍探店",
    "文案策划 / 选题 · 脚本",
    "品牌合作 / 营销策划",
    "公众号运营 / 图文排版",
    "小红书运营 / 摄影约拍",
    "AI 创作 / 豆包 · 即梦 · Gemini",
    "调色 · 配乐 · 字幕包装",
  ];
  return (
    <section id="about">
      <div className="container">
        <Eyebrow n="01">关于 · ABOUT</Eyebrow>
        <h2 className="sec-title fu">
          一个把 <span className="italic" style={{ fontSize: ".9em" }}>idea</span> 寄到 <br />
          屏幕另一端的人。
        </h2>

        <div style={{ display: "grid", gridTemplateColumns: ".9fr 1.1fr", gap: 80, marginTop: 80, alignItems: "start" }} className="about-grid">
          {/* portrait + caption */}
          <div className="fu">
            <div style={{ aspectRatio: "4/5", border: "1px solid var(--line-2)", overflow: "hidden", position: "relative", background: "var(--cream-2)" }}>
              <img src="assets/portrait.jpg" alt="上官清越" style={{ width: "100%", height: "100%", objectFit: "cover", display: "block" }} />
            </div>
            <div style={{ display: "flex", justifyContent: "space-between", marginTop: 14, fontFamily: '"JetBrains Mono",ui-monospace,"Courier New",monospace', fontSize: 11, color: "var(--mute)" }}>
              <span>浙江 · 杭州</span>
              <span>2026 / Vol.01</span>
            </div>
          </div>

          <div>
            <p className="fu" style={{ fontFamily: '"Noto Serif SC","Songti SC","STSong","SimSun",serif', fontSize: 22, lineHeight: 1.7, margin: 0, color: "var(--ink-2)", textWrap: "balance" }}>
              广告学在读，把日常拆成镜头、把镜头剪成故事。
              拥有政府单位新媒体实习经验与完整品牌营销策划项目经历，
              兼具<b>内容策划</b>、<b>新媒体运营</b>、<b>视频拍摄剪辑</b>全链条能力。
              熟悉短视频与小红书内容生态，审美在线、执行力强，擅长借助 AI 工具辅助视觉创作。
            </p>

            <div className="fu" style={{ marginTop: 36 }}>
              <div className="mono" style={{ fontSize: 11, color: "var(--mute)", marginBottom: 14 }}>内容方向 · CONTENT DIRECTIONS</div>
              <div style={{ display: "flex", flexWrap: "wrap", gap: 10 }}>
                {skills.map((s) => (
                  <span key={s} className="tag"><span className="d"></span>{s}</span>
                ))}
              </div>
            </div>

            {/* experience timeline */}
            <div className="fu" style={{ marginTop: 48, display: "grid", gap: 18 }}>
              {[
                ["2026.04—NOW", "战马品牌线下营销策划 · 项目负责人", "主题：放自己一马，蓄能再战。全案策略 / 主题落地 / 线下场景 / 传播链路。"],
                ["2026.01—2026.03", "呼和浩特市赛罕区委宣传部 · 新媒体影像实习生", "宣传视频全流程剪辑、调色、字幕包装；公众号日常运营与数据复盘。"],
                ["2024.09—2028.06", "浙江传媒学院 · 广告学 · 本科", "聚焦内容策划与新媒体方向，参与多项校园活动策划与现场视觉拍摄。"],
              ].map(([when, title, body]) => (
                <div key={when} style={{ display: "grid", gridTemplateColumns: "180px 1fr", gap: 32, padding: "14px 0", borderTop: "1px dashed var(--line-2)" }}>
                  <div className="mono" style={{ fontSize: 11, color: "var(--mute)" }}>{when}</div>
                  <div>
                    <div className="serif" style={{ fontSize: 19, fontWeight: 700 }}>{title}</div>
                    <div style={{ fontSize: 14, color: "var(--mute)", marginTop: 6, lineHeight: 1.6, fontFamily: '"Noto Sans SC","PingFang SC","Microsoft YaHei",sans-serif' }}>{body}</div>
                  </div>
                </div>
              ))}
            </div>
          </div>
        </div>
      </div>
    </section>
  );
}

// ---------- WECHAT ----------
const WECHAT = [
  {
    title: "福马闹新春 · 民艺耀云端——钩编篇",
    excerpt: "一组「福马闹新春」主题钩编玩偶创作，把十二生肖与传统手工带到云端，记录民艺数字化呈现的小尝试。",
    date: "2026.03.18",
    reads: "33",
    likes: "1",
    cover: "assets/wechat-01.jpg",
    url: "https://mp.weixin.qq.com/s/j20Lf_EnL77s7fi-iToekQ",
  },
  {
    title: "「挥毫迎骏岁 · 彩墨贺新春」区美协会员日迎新春书画活动顺利举行",
    excerpt: "区美协会员日活动现场记录：书画家齐聚挥毫泼墨，把春联与福字写进新一年的开年仪式。",
    date: "2026.02.03",
    reads: "311",
    likes: "11",
    cover: "assets/wechat-02.jpg",
    url: "https://mp.weixin.qq.com/s/9MMJDqCTwWIS0Ae8Fc0q3A",
  },
  {
    title: "福马闹新春 · 民艺耀云端——年画第一期",
    excerpt: "走进民艺工作室，记录年画手艺人现场作画的全过程，把传统年画一笔一画地带到云端。",
    date: "2026.03.02",
    reads: "92",
    likes: "10",
    cover: "assets/wechat-03.jpg",
    url: "https://mp.weixin.qq.com/s/88gq4mY-zmOAW3rCvyt7pQ",
  },
];

function WeChatGrid() {
  return (
    <section id="wechat" style={{ background: "var(--cream-2)" }}>
      <div className="container">
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "end", flexWrap: "wrap", gap: 20 }}>
          <div>
            <Eyebrow n="02">公众号 · WECHAT</Eyebrow>
            <h2 className="sec-title fu">公众号<span className="italic" style={{ fontSize: ".85em" }}>·</span>作品</h2>
          </div>
          <div className="mono fu" style={{ color: "var(--mute)", fontSize: 11 }}>共 {WECHAT.length} 篇 · 按发布时间倒序</div>
        </div>

        <div style={{ marginTop: 72, display: "grid", gridTemplateColumns: "repeat(3,1fr)", gap: 28 }} className="grid-3">
          {WECHAT.map((w, i) => {
            const hasUrl = !!w.url;
            return (
              <a
                key={i}
                href={w.url || "#"}
                target={hasUrl ? "_blank" : undefined}
                rel={hasUrl ? "noopener noreferrer" : undefined}
                onClick={hasUrl ? undefined : (e) => e.preventDefault()}
                className="card fu"
                style={{ display: "block", textDecoration: "none", cursor: hasUrl ? "pointer" : "default" }}
              >
                <div style={{ aspectRatio: "4/3", overflow: "hidden", position: "relative", background: "var(--cream-2)" }}>
                  {w.cover ? (
                    <img src={w.cover} alt={w.title} style={{ width: "100%", height: "100%", objectFit: "cover", display: "block", transition: "transform .6s cubic-bezier(.2,.7,.2,1)" }} onMouseEnter={e => e.currentTarget.style.transform = "scale(1.04)"} onMouseLeave={e => e.currentTarget.style.transform = "scale(1)"} />
                  ) : (
                    <div className="imgph" style={{ width: "100%", height: "100%" }}>
                      <div className="label">/public/wechat/{String(i + 1).padStart(2, "0")}.jpg</div>
                    </div>
                  )}
                  <div className="mono" style={{ position: "absolute", top: 12, left: 12, fontSize: 10, background: "var(--paper)", padding: "3px 8px", border: "1px solid var(--line-2)", zIndex: 2 }}>NO.{String(i + 1).padStart(2, "0")}</div>
                </div>
                <div style={{ padding: 22 }}>
                  <div className="mono" style={{ fontSize: 10, color: "var(--mute)", display: "flex", justifyContent: "space-between" }}>
                    <span>{w.date}</span>
                    <span>阅读 {w.reads}{w.likes ? ` · 赞 ${w.likes}` : ""}</span>
                  </div>
                  <h3 className="serif" style={{ fontSize: 21, lineHeight: 1.35, margin: "14px 0 10px" }}>{w.title}</h3>
                  <p style={{ margin: 0, fontSize: 14, lineHeight: 1.65, color: "var(--mute)", display: "-webkit-box", WebkitLineClamp: 2, WebkitBoxOrient: "vertical", overflow: "hidden" }}>{w.excerpt}</p>
                  <div style={{ marginTop: 18, display: "flex", justifyContent: "space-between", alignItems: "center" }}>
                    <span className="mono" style={{ fontSize: 10, color: "var(--ink)" }}>{hasUrl ? "阅读全文 →" : "敬请期待 ·"}</span>
                    <span style={{ width: 28, height: 28, border: "1px solid var(--line-2)", display: "inline-flex", alignItems: "center", justifyContent: "center", borderRadius: "50%" }}>↗</span>
                  </div>
                </div>
              </a>
            );
          })}
        </div>
      </div>
    </section>
  );
}

// ---------- VIDEO ----------
const VIDEOS = [
  { title: "聚于邻里 · 赛罕区社区宣传片", type: "实习作品 · 宣传片", dur: "03:19", desc: "呼和浩特市赛罕区委宣传部新媒体影像实习期间的全流程剪辑作品，主题围绕「温暖、聚于邻里」的社区生活切片：从素材整理、剪辑、调色到字幕包装与节奏把控独立完成。", src: "assets/video-01.mp4" },
  { title: "《一起去看流星雨》· 校园翻拍短片", type: "翻拍 · 短片", dur: "03:49", desc: "经典青春剧片段的校园翻拍，从分镜、拍摄到后期调色与流星雨视效全流程参与，作为视听语言练习与情绪短片输出。", src: "assets/video-02.mp4" },
  { title: "校园创作 · 日常剪影", type: "校园 · 创作", dur: "05:07", desc: "广告系日常的校园创作记录，把课堂、社团与校园街景剪成一段轻节奏的影像，练习手持运镜、自然光拍摄与音画节奏匹配。", src: "assets/video-03.mp4" },
];

function VideoGrid({ onPlay }) {
  return (
    <section id="video">
      <div className="container">
        <Eyebrow n="03">视频 · MOTION</Eyebrow>
        <h2 className="sec-title fu">剪辑与<span className="italic" style={{ fontSize: ".85em" }}> ·</span> 拍摄作品</h2>

        <div style={{ marginTop: 72, display: "grid", gap: 28 }} className="video-list">
          {VIDEOS.map((v, i) => (
            <button key={i} onClick={() => onPlay(v)} className="card fu video-row" style={{ textAlign: "left", padding: 0, display: "grid", gridTemplateColumns: "minmax(280px, 46%) 1fr", gap: 0, width: "100%", alignItems: "stretch" }}>
              <div
                style={{ aspectRatio: "16/9", overflow: "hidden", borderRight: "1px solid var(--line-2)", position: "relative", background: "#1a1815" }}
                onMouseEnter={e => { const vid = e.currentTarget.querySelector("video"); if (vid) { vid.play().catch(() => {}); } }}
                onMouseLeave={e => { const vid = e.currentTarget.querySelector("video"); if (vid) { vid.pause(); vid.currentTime = 0; } }}
              >
                <video
                  src={v.src}
                  preload="metadata"
                  muted
                  playsInline
                  loop
                  style={{ width: "100%", height: "100%", objectFit: "cover", display: "block" }}
                />
                <div className="play-ov" style={{ position: "absolute", inset: 0, display: "flex", alignItems: "center", justifyContent: "center", background: "rgba(20,15,10,0)", transition: "background .35s ease", pointerEvents: "none" }}>
                  <div className="play-btn" style={{ width: 76, height: 76, borderRadius: "50%", background: "var(--ink)", color: "var(--cream)", display: "flex", alignItems: "center", justifyContent: "center", transform: "scale(.85)", opacity: 0, transition: "transform .35s ease, opacity .35s ease" }}>
                    <svg width="22" height="22" viewBox="0 0 24 24"><polygon points="6,4 22,12 6,20" fill="currentColor" /></svg>
                  </div>
                </div>
                <div className="mono" style={{ position: "absolute", right: 14, bottom: 14, background: "rgba(20,15,10,.78)", color: "var(--cream)", padding: "4px 10px", fontSize: 10 }}>{v.dur}</div>
                <div className="mono" style={{ position: "absolute", top: 14, left: 14, background: "var(--paper)", padding: "4px 10px", fontSize: 10, border: "1px solid var(--line-2)" }}>{v.type}</div>
              </div>
              <div style={{ padding: "30px 32px", display: "flex", flexDirection: "column", gap: 14, justifyContent: "center" }}>
                <div className="mono" style={{ fontSize: 10, color: "var(--mute)" }}>NO.{String(i + 1).padStart(2, "0")} · {v.type} · {v.dur}</div>
                <h3 className="serif" style={{ fontSize: "clamp(20px, 2vw, 26px)", lineHeight: 1.3, margin: 0 }}>{v.title}</h3>
                <p style={{ margin: 0, fontSize: 14, lineHeight: 1.75, color: "var(--ink-2)" }}>{v.desc}</p>
                <span className="mono" style={{ fontSize: 10, color: "var(--mute)", marginTop: 6 }}>↗ 点击播放</span>
              </div>
            </button>
          ))}
        </div>
      </div>
      <style>{`
        .card:hover .play-ov{background:rgba(20,15,10,.32) !important}
        .card:hover .play-btn{transform:scale(1) !important;opacity:1 !important}
        @media (max-width: 760px){
          .video-row{grid-template-columns:1fr !important}
          .video-row .imgph{border-right:0 !important;border-bottom:1px solid var(--line-2)}
        }
      `}</style>
    </section>
  );
}

// ---------- BRAND ----------
const POSTERS = [
  {
    name: "战马 WARHORSE",
    type: "线下营销策划 · KV 主视觉",
    date: "2026.04",
    h: 520,
    img: "assets/warhorse-poster.jpg",
    imgs: ["assets/warhorse-poster.jpg", "assets/warhorse-banner.jpg"],
    role: "项目负责人",
    slogan: "放自己一马，蓄能再战。",
    desc: "为战马能量饮料定制的线下营销视觉方案，承接「放自己一马，蓄能再战」主题。以赛博朋克霓虹街景作为城市底景，多色易拉罐阵列对应产品矩阵，前置两名奔跑运动员强化「能量再爆发」的情绪，配合品牌红色书法字与电流光效，把「醒神 · 战意 · 重启」的视觉冲击拉满。",
    highlights: [
      "主题策略 / 给被生活内耗的年轻人一个再战的理由",
      "视觉语言 / 赛博朋克霓虹 × 国潮书法 × 阵列产品矩阵",
      "产出物 / KV 主视觉、横向 banner、线下场景延展物料",
      "负责环节 / 策略 · 主题落地 · 视觉指导 · AI 工具协作",
    ],
  },
  {
    name: "电影《超脱》自制海报",
    type: "平面设计 · 致敬海报",
    date: "2025.10",
    h: 600,
    img: "assets/detachment-poster.jpg",
    imgs: ["assets/detachment-poster.jpg"],
    role: "个人创作",
    slogan: "I never felt my soul so deeply form me, so far away.",
    desc: "向 Tony Kaye 导演的电影《Detachment · 超脱》致敬的自制海报：把片中 Henry Barthes 的剧照、内心独白与抽离感视觉化，用拼贴方式留住主角那种「灵魂悬浮在身体之外」的瞬间。",
    highlights: [
      "灵感来源 / 电影《Detachment》中 Henry 在地铁上独白的桥段",
      "视觉语言 / 剧照拼贴 × 橙色印刷字体 × 复古胶片划痕",
      "排版 / 80s 教育杂志页 × 美式街头海报混合调性",
      "个人产出 / 选图 · 文案抽取 · 版式 · 字体处理 · 色调统一",
    ],
  },
  {
    name: "小红书约拍摄影集",
    type: "人像摄影 · 个人内容矩阵",
    date: "2025.07—NOW",
    h: 460,
    img: "assets/xhs-01.jpg",
    imgs: ["assets/xhs-01.jpg"],
    imgObjectPosition: "top",
    role: "约拍主理人",
    slogan: "一次按下快门，留住一段我和我的猫没说出口的话。",
    desc: "个人小红书约拍账号「我和我的猫说起过你」(Halcyon_Vellich) 的内容合集——涵盖呼和浩特周边古风约拍、汉服与 cos 正片、敕勒川草原蒙古袍写真、家庭合影与宝宝满月礼等。从选题、约客、布景拍摄、修图到内容发布全程独立完成。",
    highlights: [
      "账号 / 小红书 @我和我的猫说起过你 · Halcyon_Vellich",
      "数据 / 257 关注 · 59 粉丝 · 143 获赞与收藏",
      "内容矩阵 / 古风约拍 · cos 正片 · 草原蒙古袍 · 家庭写真 · 满月礼",
      "全流程独立 / 选题 · 约客 · 拍摄 · 修图 · 文案 · 发布",
    ],
  },
];

function BrandWall({ onOpen }) {
  return (
    <section id="brand" style={{ background: "var(--cream-2)" }}>
      <div className="container">
        <Eyebrow n="04">品牌 · BRANDS</Eyebrow>
        <h2 className="sec-title fu">品牌方合作项目<span className="italic" style={{ fontSize: ".85em" }}>·</span>个人项目</h2>

        <div style={{ marginTop: 72, display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 24 }} className="brand-grid">
          {POSTERS.map((p, i) => (
            <button key={i} onClick={() => onOpen(p)} className="card fu" style={{ padding: 0, display: "flex", flexDirection: "column", width: "100%", textAlign: "left" }}>
              <div style={{ aspectRatio: "3/4", width: "100%", overflow: "hidden", position: "relative", background: "var(--cream-2)" }}>
                {p.img ? (
                  <img src={p.img} alt={p.name} style={{ width: "100%", height: "100%", objectFit: "cover", objectPosition: p.imgObjectPosition || "center", display: "block", transition: "transform .6s cubic-bezier(.2,.7,.2,1)" }} onMouseEnter={e => e.currentTarget.style.transform = "scale(1.05)"} onMouseLeave={e => e.currentTarget.style.transform = "scale(1)"} />
                ) : (
                  <div className="imgph" style={{ width: "100%", height: "100%" }}>
                    <div className="label">POSTER · {p.name}</div>
                  </div>
                )}
              </div>
              <div style={{ padding: 18, display: "flex", justifyContent: "space-between", gap: 16, flex: 1 }}>
                <div>
                  <div className="serif" style={{ fontSize: 18, fontWeight: 700 }}>{p.name}</div>
                  <div style={{ fontSize: 12, color: "var(--mute)", marginTop: 4 }}>{p.type}</div>
                </div>
                <div className="mono" style={{ fontSize: 10, color: "var(--mute)", whiteSpace: "nowrap" }}>{p.date}</div>
              </div>
            </button>
          ))}
        </div>

        {/* Logo wall */}
        <div className="fu" style={{ marginTop: 80, padding: "40px 0", borderTop: "1px solid var(--line-2)", borderBottom: "1px solid var(--line-2)" }}>
          <div className="mono" style={{ fontSize: 11, color: "var(--mute)", marginBottom: 24, textAlign: "center" }}>合作过的品牌 · TRUSTED BY</div>
          <div className="marquee">
            <div className="track">
              {[...POSTERS, ...POSTERS].map((p, i) => (
                <div key={i} className="logo-cell" style={{ flex: "0 0 auto", padding: "0 8px", fontFamily: '"Noto Serif SC","Songti SC","STSong","SimSun",serif', fontWeight: 700, fontSize: 22, color: "var(--mute-2)", filter: "saturate(0)", transition: "filter .35s ease, color .35s ease" }}
                  onMouseEnter={e => { e.currentTarget.style.filter = "saturate(1)"; e.currentTarget.style.color = "var(--ink)"; }}
                  onMouseLeave={e => { e.currentTarget.style.filter = "saturate(0)"; e.currentTarget.style.color = "var(--mute-2)"; }}
                >{p.name}</div>
              ))}
            </div>
          </div>
        </div>
      </div>
    </section>
  );
}

// ---------- CONTACT ----------
function Contact() {
  const [copied, setCopied] = useState("");
  const copy = (txt, key) => {
    navigator.clipboard?.writeText(txt);
    setCopied(key);
    setTimeout(() => setCopied(""), 1600);
  };
  const channels = [
    { k: "email", label: "邮箱", val: "yoyo202422@126.com", copyable: true },
    { k: "wechat", label: "微信", val: "BlUE-XXXONE", copyable: true },
    { k: "phone", label: "电话", val: "15754815570", copyable: true },
  ];
  return (
    <section id="contact">
      <div className="container">
        <Eyebrow n="05">联系 · CONTACT</Eyebrow>
        <h2 className="sec-title fu" style={{ maxWidth: 980 }}>
          期待与你的 <span className="italic" style={{ fontSize: ".9em" }}>collaboration</span>。
        </h2>

        <div style={{ marginTop: 80, maxWidth: 720 }} className="fu">
          <p style={{ fontFamily: '"Noto Serif SC","Songti SC","STSong","SimSun",serif', fontSize: 19, lineHeight: 1.7, color: "var(--ink-2)", margin: 0 }}>
            如果你正在筹备一支短片、一场线下活动，或者一个想被认真讲述的品牌故事——
            欢迎写信给我，我会尽快回复。
          </p>
          <div style={{ marginTop: 36, display: "grid", gap: 0 }}>
            {channels.map((c) => (
              <button
                key={c.k}
                onClick={() => c.copyable && copy(c.val, c.k)}
                style={{ display: "grid", gridTemplateColumns: "120px 1fr auto", alignItems: "center", padding: "20px 0", borderTop: "1px solid var(--line-2)", textAlign: "left", cursor: c.copyable ? "pointer" : "default" }}
              >
                <span className="mono" style={{ fontSize: 11, color: "var(--mute)" }}>{c.label.toUpperCase()}</span>
                <span className="serif" style={{ fontSize: 22 }}>{c.val}</span>
                <span className="mono" style={{ fontSize: 10, color: copied === c.k ? "var(--moss)" : "var(--mute)" }}>
                  {c.copyable ? (copied === c.k ? "✓ COPIED" : "点击复制") : "—"}
                </span>
              </button>
            ))}
            <div style={{ borderTop: "1px solid var(--line-2)" }}></div>
          </div>
        </div>
      </div>
    </section>
  );
}

// ---------- FOOTER ----------
function Footer() {
  return (
    <footer>
      <div className="container" style={{ display: "flex", flexWrap: "wrap", gap: 24, justifyContent: "space-between", alignItems: "end" }}>
        <div>
          <div className="serif" style={{ fontSize: 44, lineHeight: 1, color: "var(--ink)" }}>上官清越</div>
          <div className="mono" style={{ fontSize: 11, marginTop: 12, color: "var(--mute)" }}>© 2026 SHANGGUAN QINGYUE · ALL RIGHTS RESERVED</div>
          <div className="mono" style={{ fontSize: 11, marginTop: 6, color: "var(--mute)" }}>浙ICP备 0000000号-1 · 备案号占位</div>
        </div>
        <div style={{ display: "flex", gap: 16, alignItems: "center" }}>
          {["WeChat", "XHS", "Bilibili", "Douyin"].map(s => (
            <a key={s} href="#" className="tag" style={{ fontSize: 12 }}>{s}</a>
          ))}
        </div>
      </div>
      <div className="container mono" style={{ fontSize: 10, marginTop: 36, color: "var(--mute)", display: "flex", justifyContent: "space-between" }}>
        <span>—— 包裹已签收 ——</span>
        <span>Made with kraft & care · Hangzhou</span>
      </div>
    </footer>
  );
}

Object.assign(window, { Hero, About, WeChatGrid, VideoGrid, BrandWall, Contact, Footer });
