/* global React */
// GLOBAL BRAND CONTENT — dark editorial portfolio (premium studio case index).
// Level 1: minimal horizontal case cards. Level 2: full "Case File" detail.
// Self-contained: injects its own dark theme CSS + exposes window.GBCSections.
(function () {
  const { useEffect, useRef, useState } = React;

  // ---------------------------------------------------------------- content
  const GBC_DATA = {
    title: "GLOBAL BRAND CONTENT",
    cn: "国际品牌内容与商业传播",
    eyebrow: "PROJECT FILE · AX-02 · COMMERCIAL WORK",
    statement:
    "以国际品牌为对象，展示我如何完成从品牌洞察、主题概念、内容框架到互动机制的创意提案。",

    proposals: [
    {
      no: "01",
      brand: "Lufthansa Group",
      line2: "2024 China Social Media Proposal · 三航司方案集合",
      type: "Multi-Brand Social Proposal",
      typeCn: "集团 · 三航司社媒方案",
      // multi-airline case → CaseFile renders the group / 3-route layout
      groupTagline: "One Group, Three Airline Voices",
      groupTaglineCn: "一个集团，三种航司品牌表达",
      concept: "再次定义飞行",
      conceptEn: "Transforming the Sky",
      summary:
      "为 Lufthansa Group 旗下三大航司建立差异化中国社媒方向：Lufthansa 重新定义飞行体验，SWISS 回归理想生活与自然诗意，Austrian 以艺术、文化与灵感构建目的地叙事。",
      roleShort: "Creative Strategy / Content Planning / Copywriting / Proposal Structure",
      roleNote:
      "我参与创意策略、内容框架、年度社媒方向与提案文案，将三家航司不同的品牌资产转译为面向中国社媒语境的传播概念与内容系统。",
      airlines: [
      {
        code: "LH",
        no: "01",
        name: "Lufthansa German Airlines",
        nameCn: "汉莎德国航空",
        cover: "assets/gbc/lufthansa-cover.png",
        concept: "再次定义飞行",
        conceptEn: "Transforming the Sky: Redefining the Journey",
        summary:
        "围绕 Lufthansa 的民航历史、Allegris 产品体验与全球航线资产，将「飞行」从交通工具转译为人生旅程、文化探索与高品质出行体验。",
        visuals: ["再次定义飞行 KV", "Social Message House", "2024 Annual Content Plan"],
        ability: "品牌主张提炼 / 年度社媒内容框架 / 产品卖点转译",
        accent: "#1d4e89"
      },
      {
        code: "LX",
        no: "02",
        name: "Swiss International Airlines",
        nameCn: "瑞士国际航空",
        cover: "assets/gbc/swiss-cover.png",
        concept: "如诗归途",
        conceptEn: "Back to the Poetic Sanctuary",
        conceptAlt: "Back to Ideal Life · 回归向往的生活",
        summary:
        "围绕瑞士目的地、自然、户外、舒适与家的感受，将 SWISS 打造成「回归理想生活」的诗意旅行入口。",
        visuals: ["如诗归途主视觉", "Back to Spring / Freedom / Fairy Tale / Dream 四季内容", "瑞士自然 · 户外 · 伯恩山犬 · Lindt 联名等内容点"],
        ability: "目的地内容包装 / 生活方式叙事 / 季节化社媒内容规划",
        accent: "#d0021b"
      },
      {
        code: "OS",
        no: "03",
        name: "Austrian Airlines",
        nameCn: "奥地利航空",
        cover: "assets/gbc/austrian-cover.png",
        concept: "飞达灵感之境",
        conceptEn: "Fly to Embrace Inspiration",
        summary:
        "围绕奥地利的音乐、艺术、历史、美食与精神休憩感，将 Austrian Airlines 转译为通往灵感与文化体验的航程。",
        visuals: ["飞达灵感之境主视觉", "奥航灵感四季年度内容页", "Music / Food & Wine / Culture / History 四个内容方向"],
        ability: "文化资产转译 / 航司品牌语气区分 / 目的地情绪包装",
        accent: "#c8102e"
      }],

      proves: [
      "Multi-brand content strategy",
      "Brand localization",
      "Annual social media planning",
      "Differentiated brand voice",
      "Proposal writing & creative structure"],

      provesCn:
      "这个案例证明我能在同一集团框架下，为不同航司提炼差异化品牌表达，并转译为适合中国社媒语境的年度内容方案。",
      cover: "assets/gbc/lhgroup-cover.png",
      pdf: "pdfs/lufthansa-proposal.pdf",
      mono: "LH · LX · OS",
      accent: "#6f97c4"
    },
    {
      no: "02",
      brand: "VERO MODA",
      line2: "「她即万象｜头排看秀」主题直播活动",
      type: "Fashion Live Campaign",
      typeCn: "主题直播活动创意方案",
      concept: "VONDERLAND",
      conceptEn: "奇遇记",
      summary:
      "以 Alice in Wonderland 为灵感，将女性多元表达转译为一场 “VONDERLAND 奇遇记” 式的时尚直播体验。",
      roleShort: "Creative Concept / Live Show Narrative / Experience Planning",
      coreConcept: "VONDERLAND 奇遇记 · 以爱丽丝奇境为喻，把直播间变成一个可探索、可叙事的时尚奇遇空间。",
      audience: "关注时尚表达、自我探索与直播购物体验的年轻女性用户。",
      mechanism:
      "以「衣橱」为入口，将直播空间拆解为奇遇启程、秘境奇闻、回归新生等章节；通过失重、错位、巨物、解构等超现实视觉语言，呈现不同产品线与女性多元身份。",
      highlight:
      <span className="p1" style={{ display: "block", fontSize: "18px", color: "rgb(196, 195, 190)" }}>垂 直 空 间 秀 场 、模 特 “ 飞 行 ” 登 场 &amp; 微 观 场 景 视 角，打 造 超 现 实 主 义 时 尚 剧 场。</span>,

      cover: "assets/gbc/veromoda-shot.png",
      pdf: "pdfs/vero-moda-proposal.pdf",
      mono: "VM",
      accent: "#c79bab"
    },
    {
      no: "03",
      brand: "Heineken / 喜啤",
      line2: "喜啤宇宙创世纪互动装置方案",
      type: "Interactive Installation Proposal",
      typeCn: "线下互动装置方案",
      concept: "喜啤宇宙",
      conceptEn: "创世纪 · GENESIS",
      summary:
      "围绕 AIGC、Z 世代与元宇宙表达，设计一个让参与者从观众变成玩家与创造者的互动装置。",
      roleShort: "Experience Concept / Interaction Mechanism / Proposal Copy",
      coreConcept: "喜啤宇宙 · 创世纪 — 既是玩家，也是创造者。把线下啤酒节体验转化为可生成、可分享、可传播的品牌宇宙。",
      audience: "Z 世代年轻人、线下活动参与者、潮流科技体验爱好者、愿意参与社交分享的啤酒节用户。",
      mechanism:
      "通过互动问答、身份生成、数字分身、视觉装置与共创流程，让参与者进入「喜啤宇宙」，完成从现实参与到数字身份生成的体验旅程。",
      highlight:
      "把品牌互动从「打卡装置」升级为「身份生成与宇宙共创」，让用户不仅拍照，也能带走一个属于自己的数字身份和传播素材。",
      cover: "assets/gbc/heineken-cover.png",
      pdf: "pdfs/heineken-proposal.pdf",
      mono: "HK",
      accent: "#7fc99a"
    }]

  };

  const CASE_SECTIONS = [
  ["coreConcept", "Core Concept", "核心概念"],
  ["audience", "Target Audience", "目标受众"],
  ["mechanism", "Mechanism", "机制设计"],
  ["highlight", "Communication Highlight", "传播亮点"]];


  // ----------------------------------------------------------------- helpers
  function Reveal({ as = "div", className = "", children, style }) {
    const ref = useRef(null);
    useEffect(() => {
      const el = ref.current;
      if (!el) return;
      const io = new IntersectionObserver(
        (es) => es.forEach((e) => {if (e.isIntersecting) {el.classList.add("in");io.unobserve(el);}}),
        { threshold: 0.14 }
      );
      io.observe(el);
      return () => io.disconnect();
    }, []);
    const Tag = as;
    return <Tag ref={ref} className={"pf-rv " + className} style={style}>{children}</Tag>;
  }

  // ------------------------------------------------------------ Case File L2
  function CaseFile({ p, onClose }) {
    const [tab, setTab] = useState(0);
    useEffect(() => {
      const onKey = (e) => {if (e.key === "Escape") onClose();};
      window.addEventListener("keydown", onKey);
      return () => window.removeEventListener("keydown", onKey);
    }, [onClose]);

    const multi = Array.isArray(p.airlines) && p.airlines.length > 0;
    const air = multi ? p.airlines[tab] : null;

    return (
      <div className="cf" style={{ "--accent": multi ? air.accent : p.accent }}>
        <div className="cf-bar">
          <div className="cf-bar-l">
            <span className="cf-no">{p.no} / CASE FILE</span>
            <span className="cf-name">{p.brand}</span>
            <span className="cf-type">{p.type} · {p.typeCn}</span>
          </div>
          <button className="cf-close" onClick={onClose} aria-label="Close case file">Close ✕</button>
        </div>

        <div className="cf-scroll">
          <div className="cf-img" style={{ backgroundImage: `url(${multi ? air.cover : p.cover})` }} />

          {multi ?
          <>
              {/* 01 CASE HEADER */}
              <div className="cf-head">
                <div className="cf-concept-label">01 · CASE HEADER · 案例总览</div>
                <h2 className="cf-concept">{p.groupTagline}</h2>
                <div className="cf-concept-en">{p.groupTaglineCn}</div>
                <p className="cf-summary">{p.summary}</p>
              </div>

              {/* 02 MY ROLE */}
              <div className="cf-meta">
                <div className="cf-meta-k">02 · MY ROLE · 我的角色</div>
                <div className="cf-meta-v">{p.roleShort}</div>
                <p className="cf-meta-note">{p.roleNote}</p>
              </div>

              {/* 03 THREE AIRLINE ROUTES */}
              <div className="cf-block">
                <div className="cf-block-h">03 · THREE AIRLINE ROUTES <span>三航司方向</span></div>
                <div className="cf-tabs" role="tablist">
                  {p.airlines.map((a, i) =>
                <button
                  key={a.code}
                  role="tab"
                  aria-selected={i === tab}
                  className={"cf-tab" + (i === tab ? " on" : "")}
                  style={{ "--ta": a.accent }}
                  onClick={() => setTab(i)}>
                  
                      <span className="cf-tab-code">{a.no} · {a.code}</span>
                      <span className="cf-tab-name">{a.name}</span>
                      <span className="cf-tab-cn">{a.concept}</span>
                    </button>
                )}
                </div>

                <div className="cf-air" key={air.code}>
                  <div className="cf-air-kv" style={{ backgroundImage: `url(${air.cover})` }}>
                    <span className="cf-air-badge">{air.code} · {air.name}</span>
                  </div>
                  <div className="cf-air-body">
                    <div className="cf-air-label">CORE CONCEPT · 核心概念</div>
                    <h3 className="cf-air-concept">{air.concept}</h3>
                    <div className="cf-air-en">{air.conceptEn}</div>
                    {air.conceptAlt && <div className="cf-air-alt">{air.conceptAlt}</div>}
                    <p className="cf-air-sum">{air.summary}</p>

                    <div className="cf-air-sub">VISUAL SUGGESTIONS · 视觉建议</div>
                    <ul className="cf-chips">
                      {air.visuals.map((v) => <li key={v} className="cf-chip">{v}</li>)}
                    </ul>

                    <div className="cf-air-proof">
                      <span className="cf-air-proof-k">ABILITY PROOF · 能力证明</span>
                      <span className="cf-air-proof-v">{air.ability}</span>
                    </div>
                  </div>
                </div>
              </div>

              {/* 04 WHAT THIS CASE PROVES */}
              <div className="cf-block">
                <div className="cf-block-h">04 · WHAT THIS CASE PROVES <span>案例证明</span></div>
                <ul className="cf-proves">
                  {p.proves.map((t, i) =>
                <li key={t} className="cf-prove"><span className="cf-prove-n">{String(i + 1).padStart(2, "0")}</span>{t}</li>
                )}
                </ul>
                <p className="cf-proves-cn">{p.provesCn}</p>
              </div>
            </> :

          <>
              <div className="cf-head">
                <div className="cf-concept-label">CORE CONCEPT · 核心概念</div>
                <h2 className="cf-concept">{p.concept}</h2>
                <div className="cf-concept-en">{p.conceptEn}</div>
                <p className="cf-summary">{p.summary}</p>
              </div>

              <div className="cf-meta">
                <div className="cf-meta-k">MY ROLE · 我的角色</div>
                <div className="cf-meta-v">{p.roleShort}</div>
              </div>

              <div className="cf-sections">
                {CASE_SECTIONS.map(([k, en, cn], i) =>
              <div className="cf-sec" key={k}>
                    <div className="cf-sec-h">
                      <span className="cf-sec-n">0{i + 1}</span>
                      <span className="cf-sec-en">{en}</span>
                      <span className="cf-sec-cn">{cn}</span>
                    </div>
                    <p className="cf-sec-body">{p[k]}</p>
                  </div>
              )}
              </div>

              {Array.isArray(p.visualPages) && p.visualPages.length > 0 &&
            <div className="cf-block">
                  <div className="cf-block-h">SELECTED VISUAL PAGES <span>精选视觉页</span></div>
                  <ul className="cf-visuals">
                    {p.visualPages.map((v, i) =>
                <li key={v} className="cf-visual"><span className="cf-visual-n">{String(i + 1).padStart(2, "0")}</span><span className="cf-visual-t">{v}</span></li>
                )}
                  </ul>
                  <p className="cf-visual-note">{p.image ? "＊ 完整方案视觉如下。" : "＊ 完整视觉页见提案 PDF。"}</p>
                </div>
            }
            </>
          }

          {p.image &&
          <div className="cf-shot">
              <div className="cf-shot-h">FULL PROPOSAL VISUAL <span>完整方案视觉</span></div>
              <img className="cf-shot-img" src={p.image} alt={p.brand + " proposal"} loading="lazy" />
            </div>
          }
          {p.pdf &&
          <div className="cf-foot">
              <a className="cf-btn primary" href={p.pdf} target="_blank" rel="noopener noreferrer">Open Proposal PDF <span className="ar">↗</span></a>
              <a className="cf-btn ghost" href={p.pdf} download><span className="ar">↓</span> Download PDF</a>
            </div>
          }
        </div>
      </div>);

  }

  // ---------------------------------------------------------------- L1 list
  function GBCSections({ d, data }) {
    const P = data || GBC_DATA;
    const [openCase, setOpenCase] = useState(null);

    return (
      <div className="pf">
        {/* ===== HERO ===== */}
        <header className="pf-hero">
          <div className="pf-eyebrow">{P.eyebrow}</div>
          <h1 className="pf-title">{P.title}</h1>
          <div className="pf-title-cn">{P.cn}</div>
          <p className="pf-statement">{P.statement}</p>
          <div className="pf-meta">
            <span className="pf-meta-k">CASE INDEX</span>
            <span className="pf-meta-v">{String(P.proposals.length).padStart(2, "0")} SELECTED PROPOSALS · 完全同级</span>
          </div>
        </header>

        {/* ===== CASE LIST ===== */}
        <section className="pf-list">
          {P.proposals.map((p) =>
          <Reveal as="article" className="pf-card" key={p.no} style={{ "--accent": p.accent }}>
              <div className="pf-media">
                <div className="pf-img" style={{ backgroundImage: `url(${p.cover})` }} />
                <span className="pf-img-tag">{p.mono}</span>
              </div>
              <div className="pf-info">
                <div className="pf-top">
                  <span className="pf-no">{p.no}</span>
                  <span className="pf-type">{p.type}</span>
                </div>
                <h3 className="pf-name">{p.brand}</h3>
                <div className="pf-sub">{p.line2}</div>
                <p className="pf-summary">{p.summary}</p>
                <div className="pf-role">
                  <span className="pf-role-k">MY ROLE</span>
                  <span className="pf-role-v">{p.roleShort}</span>
                </div>
                <div className="pf-actions">
                  {p.pdf &&
                <a className="pf-btn primary" href={p.pdf} target="_blank" rel="noopener noreferrer">
                      View Proposal PDF <span className="ar">→</span>
                    </a>
                }
                  <button className={"pf-btn" + (p.pdf ? " ghost" : " primary")} onClick={() => setOpenCase(p)}>
                    Details <span className="ar">+</span>
                  </button>
                </div>
              </div>
            </Reveal>
          )}
        </section>

        {P.pageProves &&
        <section className="pf-proves">
            <div className="pf-proves-h">WHAT THIS PAGE PROVES <span>这一页证明了什么</span></div>
            <p className="pf-proves-txt">{P.pageProves.text}</p>
            <ul className="pf-proves-tags">
              {P.pageProves.tags.map((t) => <li key={t}>{t}</li>)}
            </ul>
          </section>
        }

        {openCase && <CaseFile p={openCase} onClose={() => setOpenCase(null)} />}
      </div>);

  }

  // ------------------------------------------------------------------- styles
  const GBC_CSS = `
  @import url('https://fonts.googleapis.com/css2?family=Schibsted+Grotesk:wght@400;500;600;700;800&family=Noto+Sans+SC:wght@400;500;700;900&display=swap');

  /* ---- overlay chrome (dark portfolio) ---- */
  .pd-card-portfolio{ background:#0a0a0b !important; box-shadow:0 0 0 1px rgba(255,255,255,.06), 0 40px 120px rgba(0,0,0,.62) !important; }
  .pd-card-portfolio .pd-scroll{ background:#0a0a0b !important; background-image:none !important; }
  .pd-card-portfolio .pd-scroll::-webkit-scrollbar-thumb{ background:#2a2a2c; }
  .pd-card-portfolio .pd-bar{ background:rgba(10,10,11,.78) !important; backdrop-filter:blur(12px); border-bottom:1px solid rgba(255,255,255,.07) !important; }
  .pd-card-portfolio .pd-tag{ color:#86857f !important; letter-spacing:.16em !important; }
  .pd-card-portfolio .pd-x{ color:#f4f3f1 !important; border:1px solid rgba(255,255,255,.22) !important; background:transparent !important; box-shadow:none !important; border-radius:999px !important; }
  .pd-card-portfolio .pd-x:hover{ background:#f4f3f1 !important; color:#0a0a0b !important; }

  .pf{
    --bg:#0a0a0b; --card:#141416; --card-2:#1a1a1d;
    --ink:#f4f3f1; --muted:#9a9a96; --muted-2:#76756f; --line:rgba(255,255,255,.09);
    --sans:"Schibsted Grotesk","Noto Sans SC",-apple-system,BlinkMacSystemFont,sans-serif;
    --mono:"IBM Plex Mono",ui-monospace,monospace;
    color:var(--ink); background:var(--bg);
    padding:0 clamp(20px,5vw,80px) clamp(40px,8vh,96px);
    font-family:var(--sans);
  }
  .pf-rv{ opacity:0; transform:translateY(30px); transition:opacity .9s cubic-bezier(.2,.7,.2,1), transform .9s cubic-bezier(.2,.7,.2,1); }
  .pf-rv.in{ opacity:1; transform:none; }

  /* ---- hero ---- */
  .pf-hero{ padding:clamp(44px,8vh,92px) 0 clamp(36px,6vh,64px); border-bottom:1px solid var(--line); }
  .pf-eyebrow{ font-family:var(--mono); font-size:11px; letter-spacing:.3em; color:var(--muted-2); }
  .pf-title{ font-weight:700; font-size:clamp(40px,7vw,104px); line-height:.98; letter-spacing:-.025em; margin:clamp(16px,2.4vh,26px) 0 0; }
  .pf-title-cn{ font-family:var(--sans); font-weight:500; font-size:clamp(18px,2.2vw,30px); color:var(--muted); margin-top:12px; letter-spacing:.02em; }
  .pf-statement{ font-size:clamp(17px,1.7vw,23px); font-weight:400; line-height:1.55; color:#cfcec9; max-width:60ch; margin:clamp(20px,3vh,32px) 0 0; text-wrap:pretty; }
  .pf-meta{ display:flex; align-items:baseline; gap:14px; margin-top:clamp(26px,4vh,42px); font-family:var(--mono); font-size:11px; letter-spacing:.16em; }
  .pf-meta-k{ color:var(--muted-2); }
  .pf-meta-v{ color:var(--muted); }

  /* ---- case cards ---- */
  .pf-list{ display:flex; flex-direction:column; gap:clamp(28px,5vh,56px); margin-top:clamp(40px,7vh,72px); }
  .pf-card{ display:grid; grid-template-columns:minmax(0,48%) 1fr; gap:clamp(20px,3vw,52px); align-items:stretch;
    background:var(--card); border:1px solid var(--line); border-radius:26px; padding:clamp(14px,1.4vw,18px);
    transition:transform .5s cubic-bezier(.2,.7,.2,1), background .5s, border-color .5s; }
  .pf-card:hover{ transform:translateY(-4px); background:var(--card-2); border-color:rgba(255,255,255,.16); }
  .pf-media{ position:relative; border-radius:18px; overflow:hidden; min-height:clamp(280px,38vh,440px); background:#0e0e10; }
  .pf-img{ position:absolute; inset:0; background-size:cover; background-position:center; transition:transform .8s cubic-bezier(.2,.7,.2,1); }
  .pf-card:hover .pf-img{ transform:scale(1.04); }
  .pf-img-tag{ position:absolute; top:14px; left:14px; font-family:var(--mono); font-size:11px; letter-spacing:.14em; color:#fff; background:rgba(0,0,0,.42); backdrop-filter:blur(4px); padding:5px 11px; border-radius:999px; }

  .pf-info{ display:flex; flex-direction:column; padding:clamp(14px,2vw,34px) clamp(14px,2vw,30px) clamp(18px,2vw,28px) clamp(8px,1vw,14px); }
  .pf-top{ display:flex; align-items:center; gap:14px; font-family:var(--mono); font-size:11px; letter-spacing:.16em; color:var(--muted-2); }
  .pf-no{ color:var(--accent); }
  .pf-type{ text-transform:uppercase; }
  .pf-name{ font-weight:700; font-size:clamp(28px,3.4vw,52px); line-height:1.02; letter-spacing:-.02em; margin:clamp(14px,1.8vh,22px) 0 0; }
  .pf-sub{ font-size:clamp(14px,1.3vw,17px); color:var(--muted); margin-top:8px; line-height:1.4; }
  .pf-summary{ font-size:clamp(15px,1.35vw,18px); line-height:1.6; color:#c4c3be; margin:clamp(16px,2vh,22px) 0 0; max-width:48ch; text-wrap:pretty; }
  .pf-role{ display:flex; flex-direction:column; gap:5px; margin-top:clamp(18px,2.4vh,26px); padding-top:clamp(16px,2vh,20px); border-top:1px solid var(--line); }
  .pf-role-k{ font-family:var(--mono); font-size:10px; letter-spacing:.2em; color:var(--muted-2); }
  .pf-role-v{ font-size:clamp(13.5px,1.2vw,16px); color:#d7d6d1; }
  .pf-actions{ display:flex; flex-wrap:wrap; gap:12px; margin-top:auto; padding-top:clamp(22px,3vh,32px); }

  .pf-btn{ display:inline-flex; align-items:center; gap:10px; font-family:var(--sans); font-weight:500; font-size:14px; letter-spacing:.01em;
    border-radius:999px; padding:13px 22px; cursor:pointer; text-decoration:none; transition:transform .15s, background .3s, color .3s, border-color .3s; border:1px solid transparent; }
  .pf-btn .ar{ transition:transform .3s; }
  .pf-btn.primary{ background:var(--ink); color:#0a0a0b; }
  .pf-btn.primary:hover{ background:#fff; }
  .pf-btn.primary:hover .ar{ transform:translateX(4px); }
  .pf-btn.ghost{ background:transparent; color:var(--ink); border-color:rgba(255,255,255,.22); }
  .pf-btn.ghost:hover{ border-color:#fff; background:rgba(255,255,255,.06); }
  .pf-btn.ghost:hover .ar{ transform:rotate(90deg); }
  .pf-btn:active{ transform:scale(.97); }

  /* ---- Case File (level 2) ---- */
  .cf{ position:fixed; inset:0; z-index:260; background:#0a0a0b; color:var(--ink); display:flex; flex-direction:column;
    font-family:var(--sans); animation:cfIn .42s cubic-bezier(.2,.7,.2,1); }
  @keyframes cfIn{ from{ opacity:0; transform:translateY(24px); } to{ opacity:1; transform:none; } }
  .cf-bar{ display:flex; align-items:center; justify-content:space-between; gap:18px; flex:0 0 auto;
    padding:clamp(16px,2.2vw,26px) clamp(20px,5vw,80px); border-bottom:1px solid var(--line); background:rgba(10,10,11,.86); backdrop-filter:blur(12px); }
  .cf-bar-l{ display:flex; align-items:baseline; gap:16px; flex-wrap:wrap; min-width:0; }
  .cf-no{ font-family:var(--mono); font-size:11px; letter-spacing:.18em; color:var(--accent); }
  .cf-name{ font-weight:700; font-size:clamp(18px,1.8vw,24px); letter-spacing:-.01em; }
  .cf-type{ font-family:var(--mono); font-size:11px; letter-spacing:.1em; color:var(--muted-2); }
  .cf-close{ flex:0 0 auto; font-family:var(--sans); font-weight:500; font-size:13px; color:var(--ink); background:transparent; border:1px solid rgba(255,255,255,.22); border-radius:999px; padding:10px 18px; cursor:pointer; transition:background .25s,color .25s; }
  .cf-close:hover{ background:#f4f3f1; color:#0a0a0b; }

  .cf-scroll{ flex:1; min-height:0; overflow-y:auto; padding:clamp(24px,4vw,56px) clamp(20px,5vw,80px) clamp(48px,8vh,96px); }
  .cf-scroll::-webkit-scrollbar{ width:10px; }
  .cf-scroll::-webkit-scrollbar-thumb{ background:#2a2a2c; border-radius:6px; }
  .cf-img{ width:100%; height:clamp(280px,52vh,560px); border-radius:22px; background-size:cover; background-position:center; border:1px solid var(--line); }
  .cf-head{ max-width:72ch; margin:clamp(34px,6vh,60px) 0 0; }
  .cf-concept-label{ font-family:var(--mono); font-size:11px; letter-spacing:.2em; color:var(--muted-2); }
  .cf-concept{ font-weight:700; font-size:clamp(36px,5.4vw,76px); line-height:1; letter-spacing:-.02em; margin:14px 0 0; }
  .cf-concept-en{ font-size:clamp(17px,1.8vw,24px); color:var(--accent); margin-top:10px; }
  .cf-summary{ font-size:clamp(17px,1.7vw,22px); line-height:1.6; color:#cfcec9; margin:clamp(18px,2.6vh,28px) 0 0; text-wrap:pretty; }

  .cf-meta{ display:flex; flex-direction:column; gap:7px; margin:clamp(34px,5vh,52px) 0 0; padding:clamp(20px,2.6vw,28px); background:var(--card); border:1px solid var(--line); border-radius:18px; }
  .cf-meta-k{ font-family:var(--mono); font-size:11px; letter-spacing:.2em; color:var(--muted-2); }
  .cf-meta-v{ font-size:clamp(16px,1.6vw,21px); color:#e6e5e0; }

  .cf-sections{ display:grid; grid-template-columns:1fr 1fr; gap:clamp(20px,2.6vw,40px); margin-top:clamp(28px,4vh,44px); }
  .cf-sec{ padding:clamp(22px,2.6vw,32px); background:var(--card); border:1px solid var(--line); border-radius:18px; }
  .cf-sec-h{ display:flex; align-items:baseline; gap:12px; flex-wrap:wrap; }
  .cf-sec-n{ font-family:var(--mono); font-size:12px; color:var(--accent); }
  .cf-sec-en{ font-weight:600; font-size:clamp(18px,1.8vw,24px); letter-spacing:-.01em; }
  .cf-sec-cn{ font-family:var(--mono); font-size:11px; letter-spacing:.14em; color:var(--muted-2); }
  .cf-sec-body{ font-size:clamp(15px,1.4vw,18px); line-height:1.65; color:#c4c3be; margin:14px 0 0; text-wrap:pretty; }

  /* ---- multi-airline case file ---- */
  .cf-meta-note{ font-size:clamp(14px,1.3vw,16.5px); line-height:1.6; color:#b6b5b0; margin:12px 0 0; max-width:74ch; text-wrap:pretty; }
  .cf-block{ margin-top:clamp(40px,6vh,68px); }
  .cf-block-h{ display:flex; align-items:baseline; gap:14px; font-family:var(--mono); font-size:13px; letter-spacing:.12em; color:var(--ink);
    padding-bottom:16px; border-bottom:1px solid var(--line); }
  .cf-block-h span{ font-family:var(--sans); letter-spacing:.02em; color:var(--muted-2); font-size:13px; }

  .cf-tabs{ display:grid; grid-template-columns:repeat(3,1fr); gap:clamp(10px,1.2vw,16px); margin-top:clamp(22px,3vh,30px); }
  .cf-tab{ display:flex; flex-direction:column; align-items:flex-start; gap:6px; text-align:left; cursor:pointer;
    padding:clamp(14px,1.6vw,20px); border-radius:16px; background:var(--card); border:1px solid var(--line);
    transition:transform .3s, background .3s, border-color .3s; }
  .cf-tab:hover{ transform:translateY(-3px); border-color:rgba(255,255,255,.2); }
  .cf-tab.on{ background:color-mix(in srgb, var(--ta) 16%, var(--card)); border-color:var(--ta); }
  .cf-tab-code{ font-family:var(--mono); font-size:11px; letter-spacing:.16em; color:var(--ta); }
  .cf-tab-name{ font-weight:600; font-size:clamp(14px,1.4vw,17px); color:var(--ink); line-height:1.2; }
  .cf-tab-cn{ font-size:clamp(13px,1.2vw,15px); color:var(--muted); }
  .cf-tab.on .cf-tab-cn{ color:#e6e5e0; }

  .cf-air{ display:grid; grid-template-columns:minmax(0,46%) 1fr; gap:clamp(20px,2.6vw,40px); align-items:start;
    margin-top:clamp(22px,3vh,32px); animation:cfAir .4s cubic-bezier(.2,.7,.2,1); }
  @keyframes cfAir{ from{ opacity:0; transform:translateY(14px);} to{ opacity:1; transform:none;} }
  .cf-air-kv{ position:relative; border-radius:18px; overflow:hidden; aspect-ratio:16/9; background:#0e0e10 center/cover no-repeat; border:1px solid var(--line); }
  .cf-air-badge{ position:absolute; left:14px; bottom:14px; font-family:var(--mono); font-size:11px; letter-spacing:.12em; color:#fff;
    background:rgba(0,0,0,.5); backdrop-filter:blur(4px); padding:6px 12px; border-radius:999px; }
  .cf-air-body{ min-width:0; }
  .cf-air-label{ font-family:var(--mono); font-size:11px; letter-spacing:.2em; color:var(--muted-2); }
  .cf-air-concept{ font-weight:700; font-size:clamp(30px,3.6vw,52px); line-height:1.02; letter-spacing:-.01em; margin:10px 0 0; color:var(--accent); }
  .cf-air-en{ font-size:clamp(15px,1.5vw,19px); color:#e6e5e0; margin-top:8px; }
  .cf-air-alt{ font-family:var(--mono); font-size:12.5px; color:var(--muted); margin-top:6px; }
  .cf-air-sum{ font-size:clamp(15px,1.4vw,18px); line-height:1.62; color:#c4c3be; margin:clamp(16px,2vh,22px) 0 0; text-wrap:pretty; }
  .cf-air-sub{ font-family:var(--mono); font-size:11px; letter-spacing:.18em; color:var(--muted-2); margin:clamp(20px,2.6vh,28px) 0 0; }
  .cf-chips{ list-style:none; display:flex; flex-wrap:wrap; gap:9px; margin:14px 0 0; padding:0; }
  .cf-chip{ font-size:13.5px; color:#dad9d4; background:color-mix(in srgb, var(--accent) 12%, transparent); border:1px solid color-mix(in srgb, var(--accent) 40%, var(--line));
    padding:8px 14px; border-radius:999px; }
  .cf-air-proof{ display:flex; flex-direction:column; gap:6px; margin-top:clamp(20px,2.6vh,28px); padding-top:clamp(16px,2vh,20px); border-top:1px solid var(--line); }
  .cf-air-proof-k{ font-family:var(--mono); font-size:10.5px; letter-spacing:.2em; color:var(--muted-2); }
  .cf-air-proof-v{ font-size:clamp(14px,1.3vw,16.5px); color:#dad9d4; }

  .cf-proves{ list-style:none; display:grid; grid-template-columns:repeat(auto-fit,minmax(220px,1fr)); gap:12px; margin:clamp(22px,3vh,30px) 0 0; padding:0; }
  .cf-prove{ display:flex; align-items:center; gap:12px; font-size:clamp(15px,1.4vw,18px); font-weight:500; color:#e6e5e0;
    padding:clamp(16px,1.8vw,22px); background:var(--card); border:1px solid var(--line); border-radius:14px; }
  .cf-prove-n{ font-family:var(--mono); font-size:12px; letter-spacing:.1em; color:var(--accent); }
  .cf-proves-cn{ font-size:clamp(15px,1.4vw,18px); line-height:1.6; color:#b6b5b0; margin:clamp(20px,2.6vh,26px) 0 0; max-width:74ch; text-wrap:pretty; }
  @media (max-width:880px){
    .cf-tabs{ grid-template-columns:1fr; }
    .cf-air{ grid-template-columns:1fr; }
  }

  /* ---- selected visual pages ---- */
  .cf-visuals{ list-style:none; display:grid; grid-template-columns:repeat(auto-fit,minmax(260px,1fr)); gap:12px; margin:clamp(22px,3vh,30px) 0 0; padding:0; }
  .cf-visual{ display:flex; align-items:center; gap:14px; padding:clamp(14px,1.6vw,18px); background:var(--card); border:1px solid var(--line); border-radius:14px; }
  .cf-visual-n{ font-family:var(--mono); font-size:12px; color:var(--accent); flex:0 0 auto; }
  .cf-visual-t{ font-size:clamp(14px,1.3vw,16.5px); color:#dad9d4; }
  .cf-visual-note{ font-family:var(--mono); font-size:11px; letter-spacing:.06em; color:var(--muted-2); margin:16px 0 0; }
  .cf-foot-note{ font-family:var(--mono); font-size:12px; letter-spacing:.14em; color:var(--muted-2); padding:14px 0; }

  .cf-shot{ margin-top:clamp(40px,6vh,68px); padding-top:clamp(28px,4vh,40px); border-top:1px solid var(--line); }
  .cf-shot-h{ display:flex; align-items:baseline; gap:14px; font-family:var(--mono); font-size:13px; letter-spacing:.12em; color:var(--ink); padding-bottom:16px; }
  .cf-shot-h span{ font-family:var(--sans); letter-spacing:.02em; color:var(--muted-2); font-size:13px; }
  .cf-shot-img{ display:block; width:100%; height:auto; border:1px solid var(--line); border-radius:8px; background:#0a0a0b; }

  /* ---- page-level proves ---- */
  .pf-proves{ margin-top:clamp(40px,7vh,72px); padding-top:clamp(28px,4vh,44px); border-top:1px solid var(--line); }
  .pf-proves-h{ display:flex; align-items:baseline; gap:14px; font-family:var(--mono); font-size:13px; letter-spacing:.12em; color:var(--ink); }
  .pf-proves-h span{ font-family:var(--sans); letter-spacing:.02em; color:var(--muted-2); font-size:13px; }
  .pf-proves-txt{ font-size:clamp(17px,1.7vw,22px); line-height:1.6; color:#cfcec9; margin:clamp(18px,2.6vh,26px) 0 0; max-width:72ch; text-wrap:pretty; }
  .pf-proves-tags{ list-style:none; display:flex; flex-wrap:wrap; gap:10px; margin:clamp(20px,3vh,28px) 0 0; padding:0; }
  .pf-proves-tags li{ font-family:var(--mono); font-size:12px; letter-spacing:.06em; color:#dad9d4; background:rgba(255,255,255,.04); border:1px solid var(--line); padding:9px 15px; border-radius:999px; }

  .cf-foot{ display:flex; flex-wrap:wrap; gap:14px; margin-top:clamp(36px,6vh,60px); padding-top:clamp(28px,4vh,40px); border-top:1px solid var(--line); }
  .cf-btn{ display:inline-flex; align-items:center; gap:10px; font-family:var(--sans); font-weight:500; font-size:14.5px; border-radius:999px; padding:15px 26px; text-decoration:none; cursor:pointer; transition:transform .15s, background .3s, color .3s, border-color .3s; border:1px solid transparent; }
  .cf-btn .ar{ transition:transform .3s; }
  .cf-btn.primary{ background:var(--ink); color:#0a0a0b; }
  .cf-btn.primary:hover{ background:#fff; }
  .cf-btn.primary:hover .ar{ transform:translate(3px,-3px); }
  .cf-btn.ghost{ background:transparent; color:var(--ink); border-color:rgba(255,255,255,.22); }
  .cf-btn.ghost:hover{ border-color:#fff; background:rgba(255,255,255,.06); }
  .cf-btn:active{ transform:scale(.97); }

  /* ---- responsive ---- */
  @media (max-width:880px){
    .pf-card{ grid-template-columns:1fr; gap:0; }
    .pf-media{ min-height:clamp(220px,42vw,360px); margin-bottom:clamp(16px,3vw,22px); }
    .pf-info{ padding:clamp(6px,2vw,16px) clamp(10px,3vw,20px) clamp(14px,3vw,22px); }
    .cf-sections{ grid-template-columns:1fr; }
    .cf-bar{ flex-wrap:wrap; }
  }
  @media (max-width:520px){
    .pf-actions{ flex-direction:column; align-items:stretch; }
    .pf-btn{ justify-content:center; }
    .cf-foot .cf-btn{ flex:1; justify-content:center; }
  }
  `;

  if (!document.getElementById("gbc-style")) {
    const s = document.createElement("style");
    s.id = "gbc-style";
    s.textContent = GBC_CSS;
    document.head.appendChild(s);
  }

  window.GBC_DATA = GBC_DATA;
  window.GBCSections = GBCSections;
})();