/* 下島 海 — Personal Portfolio
 * Design: dark lapis-lazuli navy, gold + blue accent (Claude Design, 2026-08-07刷新)
 * Content: 職務経歴書 + 本セッション合意内容より実情報に差し替え済み
 * 注意: 理念・代表メッセージは一次ドラフト。本人の言葉での最終確認が必要
 */

const { useState, useEffect } = React;

const GAS_WEB_APP_URL =
  'https://script.google.com/macros/s/AKfycbz90ee-u5gTX96j_l1hfE2zom3UMYVHV8a_MZNIclMdifTMVZkXaEYi4tgd4q7GKw9KBA/exec';
const CONTACT_TYPES = ['構想', '戦略', '戦術', '実装', '運用', 'その他'];
const MOBILE_BREAKPOINT = 900;

function useIsMobile() {
  const [isMobile, setIsMobile] = useState(
    typeof window !== 'undefined' && window.innerWidth < MOBILE_BREAKPOINT
  );
  useEffect(() => {
    const onResize = () => setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
    window.addEventListener('resize', onResize);
    return () => window.removeEventListener('resize', onResize);
  }, []);
  return isMobile;
}

/* ---------- data: 概要 ---------- */

const PROFILE = [
  { label: '氏名', value: '下島 海（したしま かい）' },
  { label: '屋号', value: 'LaZri（ラズリ）' },
  { label: '拠点', value: '東京都（フルリモート対応）' },
  {
    label: '専門領域',
    value:
      'プロダクトマネジメント／プロジェクトマネジメント／DXコンサルティング／AI駆動開発・マーケティング',
  },
  {
    label: '主な技術',
    value:
      'Claude Code（MCP活用）、Google Cloud Platform、Python、Playwright ほか',
  },
  {
    label: '対応業種',
    value:
      'ゲーム・自動車・スポーツエンタメ・自治体・ヘルスケア・保険・航空 ほか',
  },
];

/* ---------- data: 実績（本業） ---------- */

const JISSEKI_BIZCO_SUMMARY =
  '新規事業の0→1立ち上げから、10年選手の長寿タイトル運用まで。ゲーム・自動車・スポーツ、3つの事業ドメインで一貫して推進。';

const JISSEKI_BIZCO = [
  {
    title: '複数タイトル横断の地方コラボ企画統括',
    body: '自社プラットフォーム上で運営する複数タイトルを横断し、地方コラボ企画を統括。現地訪問がゲームユーザーの喜びになるUXを設計し、企画骨子を各タイトルへ展開・実装。1ヶ月にわたる地方創生型コラボを実現。',
    stages: ['構想', '戦術', '実装', '運用'],
  },
  {
    title: '某長期運営タイトルのV字回復',
    body: '10年選手の長寿ゲームタイトルの運営責任者として、施策の仕組化と組織の自走化を推進し売上・利益をV字回復。社内表彰（個人・チーム）を受賞。',
    stages: ['戦略', '戦術', '運用'],
  },
  {
    title: '某配車アプリの新機能PRD作成',
    body: '予約配車機能・空車待ち機能のPRD作成、開発チームへの要件伝達を主導。',
    stages: ['戦術', '実装'],
  },
  {
    title: '某NFT新規事業の0→1立ち上げ',
    body: 'プロ野球モチーフのNFTカード事業を起案から半年でリリース。事業構想〜経営会議承認〜開発〜ローンチを一気通貫で完遂。',
    stages: ['構想', '戦略', '戦術', '実装'],
  },
];

const JISSEKI_CONSULTING_SUMMARY =
  '自治体・ヘルスケア・保険・自動車・興行・航空など、9業界10件のコンサルティングプロジェクトをPM/PMOとして推進。';

const JISSEKI_CONSULTING = [
  {
    title: '自治体向けBPOシステム開発PMO',
    body: 'As-Is/To-Be業務フローをもとにRFPを作成し、約20社ベンダースクリーニングを経て3社選定までをPMOとして推進。',
    stages: ['構想', '戦術'],
  },
  {
    title: 'ヘルスケアB2B新規事業共創',
    body: 'エキスパートインタビューから事業コンセプトの具体化、事業企画書作成までをPMOとして推進。',
    stages: ['構想', '戦略'],
  },
  {
    title: '大手保険代理店 基幹システム刷新',
    body: '複数部署へのヒアリングから導出したAs-Is業務をもとにTo-Be業務を整理し、そのギャップを埋めるための大方針を策定。大方針を実現するためのシステム構想・グランドデザインまでをPMOとして推進。',
    stages: ['構想', '戦略'],
  },
  {
    title: '航空会社 業務効率化・営業DX支援',
    body: '現状ヒアリングから課題を洗い出し、AI推進に向けた吸い上げから実装までの交通整理を実施。ダッシュボード構築・運用ルールの策定までをPMOとして推進。',
    stages: ['構想', '実装', '運用'],
  },
  {
    title: '新設アリーナのDX戦略〜実装支援',
    body: '新設アリーナのDX戦略を、ステークホルダーの要求分析から要求仕様書作成、ベンダー選定・RFP作成までをPMOとして推進。',
    stages: ['構想', '戦略', '戦術'],
  },
  {
    title: '既存ホールのリニューアル支援・ブランド戦略策定',
    body: '現状分析から導出したあるべき定量・定性目標を策定。目標を実現するための施策群を洗い出し、優先順位付けからロードマップ策定までをPMOとして推進。',
    stages: ['構想', '戦略', '戦術'],
  },
  {
    title: '大規模イベントの集客・売上最大化支援',
    body: '感覚的な運営からの脱却を目指し、複数の観点から仮説を設定。デスクトップリサーチやインタビュー等の定量・定性調査で検証し、施策の洗い出しから優先度付け、ロードマップ策定までをPMOとして推進。',
    stages: ['戦略', '戦術'],
  },
  {
    title: '格闘技プラットフォーム構想策定・PMO',
    body: '壁打ちを重ねながら構想を策定し、経営会議向け資料作成から会議通過までを推進。要件定義から開発を管理し、ベータ版リリース後はデジタルマーケティング・運用までを担当。',
    stages: ['戦略', '戦術', '実装'],
  },
  {
    title: 'スポーツチーム向けデータダッシュボード構築',
    body: 'ヒアリングからユースケースを洗い出して優先順位を決定し、PoC設計・推進からリリースまでをPMOとして推進。',
    stages: ['戦術', '実装'],
  },
  {
    title: '防災設備メーカー Salesforce刷新・営業DX支援',
    body: '基幹システムとSalesforceのデータ連携強化を軸に、要件定義から全体計画書の策定までをPMOとして推進。',
    stages: ['戦略', '戦術'],
  },
  {
    title: 'セールス活動',
    body: 'アタックリストを作成し、SWOT分析ベースのディスカッション型商談を展開。商談資料マスターを構築し、アポ〜初回商談〜デリバリーまでをPMOとして推進。',
    stages: ['運用'],
  },
];

const JISSEKI_OUTSOURCE_SUMMARY =
  '構想から運用まで、業務委託でAIを活用しながら幅広く支援。';

const JISSEKI_OUTSOURCE = [
  {
    category: 'AIエージェント基盤構築',
    body: 'Cloud Run・Windows VM・MCPサーバーを組み合わせたAIエージェント基盤を個人で設計・構築・運用。以下すべての実装を支える基盤。',
    stages: ['構想', '実装', '運用'],
  },
  {
    category: '投資運用自動化',
    body: '投資分析・情報収集・レポーティングの自動化基盤を個人で構築し、運用。',
    stages: ['戦術', '実装', '運用'],
  },
  {
    category: 'SEO・広告運用',
    body: '個人事業主・中小企業向けに、検索広告の設計・運用とSEOの現状分析・改善提案・実装までを一気通貫で支援。',
    stages: ['戦術', '実装', '運用'],
  },
  {
    category: '越境EC最適化',
    body: 'eBay等の既存ECチャネルでの受注処理自動化・送料設計・SEO最適化・計測基盤の構築を実装。',
    stages: ['実装', '運用'],
  },
  {
    category: '業務効率化・自動化',
    body: 'Google Workspace Marketplace向けの業務自動化SaaS（帳票自動作成・カレンダー同期・メール差込）を開発。',
    stages: ['実装'],
  },
  {
    category: 'デジタルプロダクト開発',
    body: '開発ハーネス（CLAUDE.md設計・Hook集・PRD/SPECテンプレ）や記事など、自身の知見を活かしたデジタルプロダクトを作成。',
    stages: ['実装'],
  },
];

/* ---------- data: 強み ---------- */

const SUPPORT_STAGES = [
  {
    stage: '構想',
    en: 'CONCEPT',
    items: [
      '課題と目的の言語化',
      '市場調査',
      'ステークホルダーインタビュー',
      '壁打ち',
    ],
  },
  {
    stage: '戦略',
    en: 'STRATEGY',
    items: ['論点整理', '仮説策定', '検証による方向性の確定'],
  },
  {
    stage: '戦術',
    en: 'TACTICS',
    items: ['施策の洗い出し', '優先順位付け', 'RFP作成／ベンダー選定'],
  },
  {
    stage: '実装',
    en: 'EXECUTION',
    items: ['開発', 'システム構築'],
  },
  {
    stage: '運用',
    en: 'OPERATIONS',
    items: ['デジタルマーケティング', '運用保守', '営業'],
  },
];

/* ---------- shared ---------- */

const Container = ({ children, style }) => (
  <div
    style={{ maxWidth: 1180, margin: '0 auto', padding: '0 48px', ...style }}
  >
    {children}
  </div>
);

const SectionLabel = ({ no, ja, en }) => {
  const isMobile = useIsMobile();
  if (isMobile) {
    return (
      <div
        style={{
          borderBottom: '1px solid var(--rule)',
          paddingBottom: 14,
          marginBottom: 48,
        }}
      >
        <div
          style={{
            display: 'flex',
            alignItems: 'baseline',
            gap: 10,
            marginBottom: 6,
          }}
        >
          {no && (
            <span
              className="mono"
              style={{
                fontSize: 12,
                letterSpacing: '0.12em',
                color: 'var(--accent-gold)',
              }}
            >
              {no}
            </span>
          )}
          <span
            className="mono"
            style={{ fontSize: 12, color: 'var(--muted)' }}
          >
            {en}
          </span>
        </div>
        <h2
          style={{
            margin: 0,
            fontSize: 25,
            fontWeight: 500,
            letterSpacing: '0.04em',
            color: 'var(--ink)',
            whiteSpace: 'nowrap',
          }}
        >
          {ja}
        </h2>
      </div>
    );
  }
  return (
    <div
      style={{
        display: 'flex',
        alignItems: 'baseline',
        gap: 18,
        borderBottom: '1px solid var(--rule)',
        paddingBottom: 14,
        marginBottom: 48,
      }}
    >
      <span
        className="mono"
        style={{
          fontSize: 12,
          letterSpacing: '0.12em',
          color: 'var(--accent-gold)',
        }}
      >
        {no}
      </span>
      <h2
        style={{
          margin: 0,
          fontSize: 28,
          fontWeight: 500,
          letterSpacing: '0.04em',
          color: 'var(--ink)',
        }}
      >
        {ja}
      </h2>
      <span
        className="mono"
        style={{ fontSize: 13, color: 'var(--muted)', marginLeft: 4 }}
      >
        {en}
      </span>
      <span style={{ flex: 1 }} />
    </div>
  );
};

/* ---------- Nav ---------- */

const NAV_ITEMS = [
  { id: 'tsuyomi', ja: '支援内容', en: 'Support' },
  { id: 'jisseki', ja: '実績', en: 'Works' },
  { id: 'message', ja: '代表メッセージ', en: 'Message' },
  { id: 'profile', ja: '概要', en: 'Profile' },
  { id: 'renraku', ja: '連絡先', en: 'Contact' },
];

function Nav() {
  const [scrolled, setScrolled] = useState(false);
  const [open, setOpen] = useState(false);
  const isMobile = useIsMobile();

  useEffect(() => {
    const onScroll = () => setScrolled(window.scrollY > 24);
    window.addEventListener('scroll', onScroll);
    return () => window.removeEventListener('scroll', onScroll);
  }, []);

  useEffect(() => {
    if (!isMobile) setOpen(false);
  }, [isMobile]);

  const navBg = scrolled || open ? 'rgba(16,27,48,0.95)' : 'transparent';

  return (
    <nav
      style={{
        position: 'fixed',
        top: 0,
        left: 0,
        right: 0,
        zIndex: 50,
        background: navBg,
        backdropFilter: scrolled || open ? 'blur(12px)' : 'none',
        borderBottom:
          scrolled || open ? '1px solid var(--rule)' : '1px solid transparent',
        transition: 'all 240ms ease',
      }}
    >
      <Container style={{ display: 'flex', alignItems: 'center', height: 64 }}>
        <div style={{ flex: 1 }} />
        {isMobile ? (
          <button
            onClick={() => setOpen((v) => !v)}
            aria-label="メニューを開閉"
            style={{
              background: 'none',
              border: 'none',
              cursor: 'pointer',
              padding: 8,
              display: 'flex',
              flexDirection: 'column',
              gap: 5,
            }}
          >
            {[0, 1, 2].map((i) => (
              <span
                key={i}
                style={{
                  width: 22,
                  height: 2,
                  background: 'var(--ink)',
                  display: 'block',
                  transition: 'transform 200ms, opacity 200ms',
                  transform:
                    open && i === 0
                      ? 'translateY(7px) rotate(45deg)'
                      : open && i === 2
                        ? 'translateY(-7px) rotate(-45deg)'
                        : 'none',
                  opacity: open && i === 1 ? 0 : 1,
                }}
              />
            ))}
          </button>
        ) : (
          <div style={{ display: 'flex', gap: 22 }}>
            {NAV_ITEMS.map((it) => (
              <a
                key={it.id}
                href={'#' + it.id}
                style={{
                  textDecoration: 'none',
                  fontSize: 12.5,
                  color: 'var(--ink-2)',
                  display: 'flex',
                  alignItems: 'baseline',
                  gap: 5,
                  whiteSpace: 'nowrap',
                }}
              >
                <span>{it.ja}</span>
                <span
                  className="mono"
                  style={{ fontSize: 9, color: 'var(--muted)' }}
                >
                  {it.en}
                </span>
              </a>
            ))}
          </div>
        )}
      </Container>

      {isMobile && open && (
        <div
          style={{
            borderTop: '1px solid var(--rule)',
            background: 'rgba(16,27,48,0.98)',
          }}
        >
          <Container
            style={{
              padding: '8px 48px 24px',
              display: 'flex',
              flexDirection: 'column',
            }}
          >
            {NAV_ITEMS.map((it) => (
              <a
                key={it.id}
                href={'#' + it.id}
                onClick={() => setOpen(false)}
                style={{
                  textDecoration: 'none',
                  color: 'var(--ink)',
                  fontSize: 15,
                  padding: '14px 0',
                  borderBottom: '1px solid var(--rule)',
                  display: 'flex',
                  alignItems: 'baseline',
                  gap: 10,
                }}
              >
                <span>{it.ja}</span>
                <span
                  className="mono"
                  style={{ fontSize: 10, color: 'var(--muted)' }}
                >
                  {it.en}
                </span>
              </a>
            ))}
          </Container>
        </div>
      )}
    </nav>
  );
}

/* ---------- Hero ---------- */

function Hero() {
  const isMobile = useIsMobile();
  return (
    <header
      id="top"
      style={{
        paddingTop: 88,
        paddingBottom: 56,
        borderBottom: '1px solid var(--rule)',
      }}
    >
      {(() => {
        const keyVisual = (
          <div
            style={{
              position: 'relative',
              width: '100%',
              aspectRatio: isMobile ? '4 / 3.6' : '21 / 8',
              border: isMobile ? 'none' : '1px solid var(--rule)',
              backgroundImage: isMobile
                ? "url('public/images/hero-keyvisual-mobile.webp')"
                : "url('public/images/hero-keyvisual.webp')",
              backgroundSize: isMobile ? 'cover' : '130% auto',
              backgroundPosition: 'center',
              backgroundColor: 'var(--bg-2)',
            }}
          >
            <div
              style={{
                position: 'absolute',
                inset: 0,
                display: 'flex',
                flexDirection: 'column',
                alignItems: 'center',
                justifyContent: 'center',
                gap: 6,
                textAlign: 'center',
                padding: isMobile ? '24px 14px' : 24,
              }}
            >
              <span
                style={{
                  fontSize: isMobile
                    ? 'clamp(18px, 5.9vw, 23px)'
                    : 'clamp(28px, 3.2vw, 42px)',
                  fontWeight: 500,
                  letterSpacing: '0.02em',
                  color: 'var(--ink)',
                }}
              >
                構想から運用まで、一気通貫。
              </span>
              <p
                style={{
                  margin: '18px 0 0',
                  maxWidth: 560,
                  fontSize: isMobile ? 13.5 : 15,
                  lineHeight: 1.9,
                  color: 'var(--ink-2)',
                }}
              >
                構想〜戦略〜戦術〜実装〜運用まで、
                <br />
                AIを活用して必要な分だけ伴走します。
              </p>
            </div>
          </div>
        );
        return isMobile ? (
          <div style={{ padding: '0 14px' }}>{keyVisual}</div>
        ) : (
          <Container>{keyVisual}</Container>
        );
      })()}
    </header>
  );
}

/* ---------- 代表メッセージ ---------- */

function Message() {
  const isMobile = useIsMobile();
  return (
    <section
      id="message"
      style={{
        padding: '120px 0',
        borderBottom: '1px solid var(--rule)',
        background: 'var(--bg-2)',
      }}
    >
      <Container>
        <SectionLabel no="§03" ja="代表メッセージ" en="MESSAGE" />
        <div
          style={{
            display: 'grid',
            gridTemplateColumns: isMobile ? '1fr' : '280px 1fr',
            gap: isMobile ? 24 : 64,
          }}
        >
          <div>
            <div style={{ fontSize: 20, fontWeight: 500, color: 'var(--ink)' }}>
              下島 海
            </div>
            <div
              className="mono"
              style={{ fontSize: 12, color: 'var(--muted)', marginTop: 4 }}
            >
              KAI SHITASHIMA
            </div>
            <img
              src="public/images/kai-portrait.webp"
              alt="下島海"
              style={{
                width: '100%',
                maxWidth: 220,
                aspectRatio: '1 / 1',
                objectFit: 'cover',
                borderRadius: 12,
                marginTop: 20,
                display: 'block',
              }}
            />
          </div>
          <div style={{ maxWidth: 640 }}>
            <p
              style={{
                margin: '0 0 24px',
                fontSize: 15,
                lineHeight: 1.95,
                color: 'var(--ink-2)',
              }}
            >
              <strong style={{ color: 'var(--ink)' }}>
                大企業で磨いた「一気通貫」の力を、中小企業の現場へ。
              </strong>
              <br />
              <br />
              そう考えて、私は業務委託という形で個人での支援を始めました。
            </p>
            <p
              style={{
                margin: '0 0 24px',
                fontSize: 15,
                lineHeight: 1.95,
                color: 'var(--ink-2)',
              }}
            >
              事業会社やコンサルティングファームでは、要件定義から実装、そして運用まで、
              上流から現場まで自分で手を動かしながら一貫して進めるスタイルで仕事をしてきました。
              個人事業主や中小企業の方から相談を受けるようになって気づいたのは、
              このスタイルこそ、リソースが限られた事業者にとって一番効くということです。
              まず今あるリソースでできることを見極めてやり切り、本当に足りない部分だけを
              補っていく。そのやり方の方が、結果的に多くの事業者にとって前に進みやすい
              はずだと思っています。
            </p>
            <p
              style={{
                margin: '0 0 24px',
                fontSize: 15,
                lineHeight: 1.95,
                color: 'var(--ink-2)',
              }}
            >
              だからこそ、業務委託・スポットという小さな単位でも、構想から実装・運用までを
              一気通貫でお引き受けしています。
            </p>
            <p
              style={{
                margin: 0,
                fontSize: 15,
                lineHeight: 1.95,
                color: 'var(--ink-2)',
              }}
            >
              その根っこにあるのは、学生時代から続けている格闘技で培った、ことに向き合って
              最後までやり切る感覚かもしれません。今も週1で稽古を続けながら、フットサルや
              ゴルフ、ジムでも体を動かしています。
            </p>
          </div>
        </div>
      </Container>
    </section>
  );
}

/* ---------- 概要 ---------- */

function Profile() {
  const isMobile = useIsMobile();
  return (
    <section
      id="profile"
      style={{ padding: '120px 0', borderBottom: '1px solid var(--rule)' }}
    >
      <Container>
        <SectionLabel no="§04" ja="概要" en="PROFILE" />
        <div>
          {PROFILE.map((row, i) => (
            <div
              key={row.label}
              style={{
                display: 'grid',
                gridTemplateColumns: isMobile ? '84px 1fr' : '160px 1fr',
                gap: isMobile ? 16 : 32,
                padding: '20px 0',
                borderTop: i === 0 ? 'none' : '1px solid var(--rule)',
              }}
            >
              <div
                className="mono"
                style={{
                  fontSize: 12,
                  color: 'var(--accent-gold)',
                  letterSpacing: '0.05em',
                }}
              >
                {row.label}
              </div>
              <div
                style={{
                  fontSize: 14.5,
                  color: 'var(--ink-2)',
                  lineHeight: 1.8,
                }}
              >
                {row.value}
              </div>
            </div>
          ))}
        </div>
      </Container>
    </section>
  );
}

/* ---------- 実績 ---------- */

function JissekiCard({ item }) {
  const isMobile = useIsMobile();
  const [open, setOpen] = useState(false);
  const expanded = !isMobile || open;
  return (
    <div
      onClick={isMobile ? () => setOpen((v) => !v) : undefined}
      style={{
        background: 'var(--card)',
        border: '1px solid var(--rule)',
        padding: '24px 24px 22px',
        display: 'flex',
        flexDirection: 'column',
        gap: 10,
        ...(isMobile
          ? { minHeight: 118, justifyContent: 'flex-start', cursor: 'pointer' }
          : {}),
      }}
    >
      {item.stages && (
        <div
          style={{
            display: 'flex',
            flexWrap: 'wrap',
            gap: 6,
          }}
        >
          {item.stages.map((st) => (
            <span
              key={st}
              className="mono"
              style={{
                fontSize: 9,
                letterSpacing: '0.08em',
                color: 'var(--accent-gold)',
                border: '1px solid rgba(201,162,39,0.4)',
                borderRadius: 999,
                padding: '2px 9px',
              }}
            >
              {st}
            </span>
          ))}
        </div>
      )}
      {item.org && (
        <div
          className="mono"
          style={{
            fontSize: 10,
            letterSpacing: '0.14em',
            color: 'var(--accent-gold)',
          }}
        >
          {item.org}
        </div>
      )}
      <div
        style={{
          display: 'flex',
          alignItems: 'baseline',
          gap: 10,
          flexWrap: 'wrap',
        }}
      >
        <h4
          style={{
            margin: 0,
            fontSize: 16,
            fontWeight: 500,
            lineHeight: 1.4,
            color: 'var(--ink)',
            flex: 1,
          }}
        >
          {item.title || item.category}
        </h4>
        {item.needsConfirm && (
          <span
            className="mono"
            style={{
              fontSize: 9,
              letterSpacing: '0.1em',
              color: 'var(--bg)',
              background: 'var(--accent-gold)',
              padding: '2px 7px',
              borderRadius: 999,
            }}
          >
            要確認
          </span>
        )}
        {isMobile && (
          <span
            style={{
              color: 'var(--accent-gold)',
              fontSize: 12,
              transform: open ? 'rotate(180deg)' : 'none',
              transition: 'transform 0.2s',
            }}
          >
            ▼
          </span>
        )}
      </div>
      {expanded && (
        <p
          style={{
            margin: 0,
            fontSize: 13,
            lineHeight: 1.75,
            color: 'var(--ink-2)',
          }}
        >
          {item.body}
        </p>
      )}
    </div>
  );
}

function JissekiGroup({ ja, en, summary, items }) {
  const isMobile = useIsMobile();
  return (
    <div style={{ marginBottom: 64 }}>
      <div
        style={{
          marginBottom: 12,
          display: 'flex',
          alignItems: 'center',
          gap: 12,
        }}
      >
        <span
          className="mono"
          style={{
            fontSize: 11,
            letterSpacing: '0.14em',
            color: 'var(--muted)',
          }}
        >
          {ja}
        </span>
        <span className="mono" style={{ fontSize: 12, color: 'var(--muted)' }}>
          {en}
        </span>
      </div>
      <p
        style={{
          margin: '0 0 20px',
          fontSize: 13.5,
          lineHeight: 1.85,
          color: 'var(--ink-2)',
          whiteSpace: isMobile ? 'normal' : 'nowrap',
        }}
      >
        {summary}
      </p>
      <div
        style={{
          display: 'grid',
          gridTemplateColumns: isMobile ? '1fr' : 'repeat(3, 1fr)',
          gap: 14,
        }}
      >
        {items.map((item, i) => (
          <JissekiCard key={i} item={item} />
        ))}
      </div>
    </div>
  );
}

function Jisseki() {
  return (
    <section
      id="jisseki"
      style={{ padding: '120px 0', borderBottom: '1px solid var(--rule)' }}
    >
      <Container>
        <SectionLabel no="§02" ja="実績" en="CASE STUDIES" />

        <JissekiGroup
          ja="事業会社実績"
          en="Business Ventures"
          summary={JISSEKI_BIZCO_SUMMARY}
          items={JISSEKI_BIZCO}
        />
        <JissekiGroup
          ja="コンサル実績"
          en="Consulting"
          summary={JISSEKI_CONSULTING_SUMMARY}
          items={JISSEKI_CONSULTING}
        />
        <JissekiGroup
          ja="業務委託実績"
          en="Independent"
          summary={JISSEKI_OUTSOURCE_SUMMARY}
          items={JISSEKI_OUTSOURCE}
        />
      </Container>
    </section>
  );
}

/* ---------- 強み ---------- */

function SupportCallout({ n, items, bg, top }) {
  return (
    <div
      style={{
        position: 'absolute',
        left: '50%',
        top,
        transform: 'translateX(-50%)',
        width: 270,
        boxSizing: 'border-box',
        padding: '18px 20px 20px',
        background: bg,
        border: '1px solid rgba(82,113,179,0.5)',
        borderTop: '2px solid var(--accent-gold)',
        borderRadius: 2,
        boxShadow: '0 14px 34px rgba(11,20,38,0.38)',
      }}
    >
      <div
        style={{
          display: 'flex',
          alignItems: 'center',
          gap: 10,
          marginBottom: 12,
        }}
      >
        <span
          className="mono"
          style={{
            fontSize: 11,
            letterSpacing: '0.1em',
            color: 'var(--accent-gold)',
          }}
        >
          {n}
        </span>
        <span
          className="mono"
          style={{
            fontSize: 10,
            letterSpacing: '0.22em',
            color: 'var(--muted)',
            whiteSpace: 'nowrap',
          }}
        >
          WHAT WE DO
        </span>
      </div>
      <ul
        style={{
          margin: 0,
          paddingLeft: 18,
          fontSize: 14,
          lineHeight: 1.85,
          color: 'var(--ink-2)',
        }}
      >
        {items.map((it) => (
          <li key={it} style={{ marginTop: 2 }}>
            {it}
          </li>
        ))}
      </ul>
    </div>
  );
}

function SupportFoundation({ mobile }) {
  return (
    <div style={{ position: 'relative', marginTop: mobile ? 48 : 56 }}>
      <div
        style={{
          position: 'absolute',
          inset: 0,
          clipPath: mobile
            ? undefined
            : 'polygon(5% 0, 95% 0, 100% 100%, 0 100%)',
          border: mobile ? '1px solid rgba(82,113,179,0.5)' : undefined,
          background:
            'linear-gradient(180deg, rgba(201,162,39,0.26), rgba(38,66,139,0.16) 60%, rgba(38,66,139,0.06))',
        }}
      />
      <div
        style={{
          position: 'absolute',
          left: mobile ? 0 : '5%',
          right: mobile ? 0 : '5%',
          top: 0,
          height: mobile ? 2 : 3,
          background: 'var(--accent-gold)',
        }}
      />
      <div
        style={{
          position: 'relative',
          padding: mobile ? '24px 20px 26px' : '34px 10% 40px',
          display: 'flex',
          flexDirection: 'column',
          alignItems: 'center',
          gap: 12,
          textAlign: 'center',
        }}
      >
        <div
          className="mono"
          style={{
            fontSize: mobile ? 10 : 11,
            letterSpacing: mobile ? '0.24em' : '0.26em',
            color: 'var(--accent-gold)',
          }}
        >
          GENERATIVE AI / FOUNDATION
        </div>
        <div
          style={{
            fontSize: mobile ? 15 : 19,
            lineHeight: mobile ? 1.85 : 1.8,
            color: 'var(--ink)',
            letterSpacing: mobile ? 0 : '0.04em',
          }}
        >
          {mobile ? (
            <>
              構想〜運用のどの工程にも、
              <br />
              AIを組み込んで推進します。
            </>
          ) : (
            '構想〜運用のどの工程にも、AIを組み込んで推進します。'
          )}
        </div>
      </div>
    </div>
  );
}

function Tsuyomi() {
  const isMobile = useIsMobile();
  return (
    <section
      id="tsuyomi"
      style={{
        padding: '120px 0',
        borderBottom: '1px solid var(--rule)',
        background: 'var(--bg-2)',
      }}
    >
      <Container>
        <SectionLabel no="§01" ja="支援内容" en="SUPPORT" />
        <p
          style={{
            margin: '-24px 0 48px',
            fontSize: isMobile ? 13.5 : 15,
            lineHeight: 1.9,
            color: 'var(--ink-2)',
            maxWidth: 640,
          }}
        >
          構想から運用まで、一本の流れとして伴走します。
        </p>

        {isMobile ? (
          <div style={{ width: '100%' }}>
            <div style={{ position: 'relative' }}>
              <div
                style={{
                  position: 'absolute',
                  left: 8,
                  top: 8,
                  bottom: 8,
                  width: 2,
                  background:
                    'linear-gradient(180deg, rgba(82,113,179,0.25), var(--accent-blue) 10%, var(--accent-blue) 90%, rgba(82,113,179,0.25))',
                }}
              />
              <div
                style={{ display: 'flex', flexDirection: 'column', gap: 34 }}
              >
                {SUPPORT_STAGES.map((s, i) => (
                  <div
                    key={s.stage}
                    style={{ paddingLeft: 40, position: 'relative' }}
                  >
                    <div
                      style={{
                        position: 'absolute',
                        left: 1,
                        top: 6,
                        width: 16,
                        height: 16,
                        borderRadius: '50%',
                        background: 'var(--accent-gold)',
                        boxShadow: '0 0 0 5px rgba(201,162,39,0.16)',
                      }}
                    />
                    <div
                      style={{
                        position: 'absolute',
                        left: 17,
                        top: 13,
                        width: 23,
                        height: 2,
                        background: 'var(--accent-gold)',
                      }}
                    />
                    <div
                      style={{
                        display: 'flex',
                        alignItems: 'baseline',
                        gap: 10,
                      }}
                    >
                      <span
                        className="mono"
                        style={{ fontSize: 12, color: 'var(--accent-gold)' }}
                      >
                        {String(i + 1).padStart(2, '0')}
                      </span>
                      <span
                        style={{
                          fontSize: 21,
                          fontWeight: 700,
                          letterSpacing: '0.1em',
                          color: 'var(--ink)',
                        }}
                      >
                        {s.stage}
                      </span>
                      <span
                        className="mono"
                        style={{
                          fontSize: 10,
                          letterSpacing: '0.22em',
                          color: 'var(--muted)',
                        }}
                      >
                        {s.en}
                      </span>
                    </div>
                    <div
                      style={{
                        marginTop: 14,
                        padding: '18px 20px',
                        background:
                          i % 2 === 0 ? 'var(--card)' : 'var(--card-2)',
                        border: '1px solid rgba(82,113,179,0.5)',
                        borderTop: '2px solid var(--accent-gold)',
                        borderRadius: 2,
                      }}
                    >
                      <ul
                        style={{
                          margin: 0,
                          paddingLeft: 18,
                          fontSize: 14,
                          lineHeight: 1.85,
                          color: 'var(--ink-2)',
                        }}
                      >
                        {s.items.map((it) => (
                          <li key={it} style={{ marginTop: 2 }}>
                            {it}
                          </li>
                        ))}
                      </ul>
                    </div>
                  </div>
                ))}
              </div>
            </div>
            <SupportFoundation mobile />
          </div>
        ) : (
          <div style={{ width: '100%' }}>
            {/* 上向きの枝（構想・戦術） */}
            <div
              style={{ display: 'grid', gridTemplateColumns: 'repeat(5, 1fr)' }}
            >
              {SUPPORT_STAGES.map((s, i) =>
                i % 2 === 0 ? (
                  <div
                    key={s.stage}
                    style={{ position: 'relative', height: 214 }}
                  >
                    <SupportCallout
                      n={String(i + 1).padStart(2, '0')}
                      items={s.items}
                      bg="var(--card)"
                      top={0}
                    />
                    <div
                      style={{
                        position: 'absolute',
                        left: '50%',
                        top: 150,
                        bottom: 0,
                        width: 2,
                        marginLeft: -1,
                        background:
                          'linear-gradient(180deg, rgba(201,162,39,0.55), var(--accent-gold))',
                      }}
                    />
                    <div
                      style={{
                        position: 'absolute',
                        left: '50%',
                        top: 146,
                        width: 7,
                        height: 7,
                        marginLeft: -3.5,
                        borderRadius: '50%',
                        background: 'var(--accent-gold)',
                      }}
                    />
                  </div>
                ) : (
                  <div key={s.stage} style={{ height: 214 }} />
                )
              )}
            </div>

            {/* ベースライン */}
            <div style={{ position: 'relative', height: 132 }}>
              <div
                style={{
                  position: 'absolute',
                  left: 0,
                  right: 0,
                  top: 0,
                  height: 2,
                  background:
                    'linear-gradient(90deg, rgba(82,113,179,0.25), var(--accent-blue) 12%, var(--accent-blue) 88%, rgba(82,113,179,0.25))',
                }}
              />
              <div
                style={{
                  position: 'absolute',
                  left: 0,
                  right: 0,
                  top: 0,
                  display: 'grid',
                  gridTemplateColumns: 'repeat(5, 1fr)',
                }}
              >
                {SUPPORT_STAGES.map((s, i) => (
                  <div
                    key={s.stage}
                    style={{
                      position: 'relative',
                      height: 132,
                      display: 'flex',
                      flexDirection: 'column',
                      alignItems: 'center',
                    }}
                  >
                    <div
                      style={{
                        width: 17,
                        height: 17,
                        borderRadius: '50%',
                        background: 'var(--accent-gold)',
                        boxShadow: '0 0 0 6px rgba(201,162,39,0.16)',
                        marginTop: -8,
                      }}
                    />
                    <div
                      style={{
                        marginTop: 18,
                        display: 'flex',
                        alignItems: 'baseline',
                        gap: 9,
                      }}
                    >
                      <span
                        className="mono"
                        style={{ fontSize: 12, color: 'var(--accent-gold)' }}
                      >
                        {String(i + 1).padStart(2, '0')}
                      </span>
                      <span
                        style={{
                          fontSize: 23,
                          fontWeight: 700,
                          letterSpacing: '0.1em',
                          color: 'var(--ink)',
                        }}
                      >
                        {s.stage}
                      </span>
                    </div>
                    <div
                      className="mono"
                      style={{
                        marginTop: 8,
                        fontSize: 10,
                        letterSpacing: '0.24em',
                        color: 'var(--muted)',
                      }}
                    >
                      {s.en}
                    </div>
                  </div>
                ))}
              </div>
            </div>

            {/* 下向きの枝（戦略・実装） */}
            <div
              style={{ display: 'grid', gridTemplateColumns: 'repeat(5, 1fr)' }}
            >
              {SUPPORT_STAGES.map((s, i) =>
                i % 2 === 1 ? (
                  <div
                    key={s.stage}
                    style={{ position: 'relative', height: 206 }}
                  >
                    <div
                      style={{
                        position: 'absolute',
                        left: '50%',
                        top: 0,
                        height: 44,
                        width: 2,
                        marginLeft: -1,
                        background:
                          'linear-gradient(180deg, var(--accent-gold), rgba(201,162,39,0.55))',
                      }}
                    />
                    <div
                      style={{
                        position: 'absolute',
                        left: '50%',
                        top: 41,
                        width: 7,
                        height: 7,
                        marginLeft: -3.5,
                        borderRadius: '50%',
                        background: 'var(--accent-gold)',
                      }}
                    />
                    <SupportCallout
                      n={String(i + 1).padStart(2, '0')}
                      items={s.items}
                      bg="var(--card-2)"
                      top={44}
                    />
                  </div>
                ) : (
                  <div key={s.stage} style={{ height: 206 }} />
                )
              )}
            </div>

            <SupportFoundation />
          </div>
        )}
      </Container>
    </section>
  );
}

/* ---------- 連絡先 ---------- */

const CONTACT_FIELD_STYLE = {
  width: '100%',
  boxSizing: 'border-box',
  background: 'var(--card)',
  border: '1px solid var(--rule)',
  borderRadius: 6,
  color: 'var(--ink)',
  padding: '10px 12px',
  fontSize: 14,
  fontFamily: 'inherit',
};

function FormField({ label, required, children }) {
  return (
    <label style={{ display: 'block', marginBottom: 18 }}>
      <span
        className="mono"
        style={{
          display: 'block',
          fontSize: 11,
          letterSpacing: '0.1em',
          textTransform: 'uppercase',
          color: 'var(--muted)',
          marginBottom: 6,
        }}
      >
        {label}
        {required && <span style={{ color: 'var(--accent-gold)' }}> *</span>}
      </span>
      {children}
    </label>
  );
}

function Renraku() {
  const [form, setForm] = useState({
    type: '',
    company: '',
    department: '',
    email: '',
    message: '',
    website: '', // ハニーポット（実ユーザー・スクリーンリーダーからは不可視）
  });
  const [status, setStatus] = useState('idle'); // idle | submitting | success | error
  const [errors, setErrors] = useState([]);

  function update(key) {
    return (e) => setForm((f) => ({ ...f, [key]: e.target.value }));
  }

  function validate() {
    const errs = [];
    if (!CONTACT_TYPES.includes(form.type)) {
      errs.push('お問い合わせの種類を選択してください。');
    }
    if (!form.company.trim()) {
      errs.push('貴社名は必須です。');
    }
    if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(form.email.trim())) {
      errs.push('メールアドレスの形式が不正です。');
    }
    if (!form.message.trim()) {
      errs.push('お問い合わせ内容は必須です。');
    }
    return errs;
  }

  async function handleSubmit(e) {
    e.preventDefault();
    if (!GAS_WEB_APP_URL) {
      setStatus('error');
      setErrors(['フォーム準備中です。しばらくしてから再度お試しください。']);
      return;
    }
    const clientErrors = validate();
    if (clientErrors.length) {
      setStatus('error');
      setErrors(clientErrors);
      return;
    }
    setStatus('submitting');
    setErrors([]);
    try {
      const res = await fetch(GAS_WEB_APP_URL, {
        method: 'POST',
        headers: { 'Content-Type': 'text/plain;charset=utf-8' },
        body: JSON.stringify({ action: 'submitContact', params: form }),
        redirect: 'follow',
      });
      if (!res.ok) throw new Error('HTTP ' + res.status);
      const data = JSON.parse(await res.text());
      if (data.success) {
        setStatus('success');
      } else {
        setStatus('error');
        setErrors(
          data.errors || [
            data.error ||
              '送信に失敗しました。時間をおいて再度お試しください。',
          ]
        );
      }
    } catch (err) {
      setStatus('error');
      setErrors(['送信に失敗しました。時間をおいて再度お試しください。']);
    }
  }

  return (
    <section
      id="renraku"
      style={{ padding: '120px 0 100px', background: 'var(--bg-2)' }}
    >
      <Container>
        <SectionLabel no="" ja="連絡先" en="CONTACT" />
        <div
          className="mono"
          style={{
            fontSize: 11,
            letterSpacing: '0.16em',
            color: 'var(--muted)',
            marginBottom: 18,
          }}
        >
          GET IN TOUCH ↓
        </div>
        {status === 'success' ? (
          <div
            aria-live="polite"
            style={{
              maxWidth: 560,
              border: '1px solid var(--accent-gold)',
              borderRadius: 12,
              padding: '28px 32px',
              color: 'var(--ink)',
              fontSize: 15,
              lineHeight: 1.9,
            }}
          >
            お問い合わせいただきありがとうございます。内容を確認の上、折り返しご連絡いたします。
          </div>
        ) : (
          <React.Fragment>
            <p
              style={{
                margin: '0 0 28px',
                fontSize: 15,
                lineHeight: 1.9,
                color: 'var(--ink-2)',
                maxWidth: 560,
              }}
            >
              現状・課題・ご相談内容をお送りください。
              <br />
              内容を確認の上、折り返しご連絡いたします。
            </p>
            <form
              onSubmit={handleSubmit}
              style={{
                maxWidth: 560,
                background: 'var(--bg)',
                border: '1px solid var(--rule)',
                borderRadius: 12,
                padding: 32,
              }}
            >
              <FormField label="お問い合わせの種類" required>
                <select
                  className="contact-field"
                  style={CONTACT_FIELD_STYLE}
                  value={form.type}
                  onChange={update('type')}
                >
                  <option value="">選択してください</option>
                  {CONTACT_TYPES.map((t) => (
                    <option key={t} value={t}>
                      {t}
                    </option>
                  ))}
                </select>
              </FormField>
              <FormField label="貴社名" required>
                <input
                  className="contact-field"
                  style={CONTACT_FIELD_STYLE}
                  type="text"
                  value={form.company}
                  onChange={update('company')}
                />
              </FormField>
              <FormField label="部署名">
                <input
                  className="contact-field"
                  style={CONTACT_FIELD_STYLE}
                  type="text"
                  value={form.department}
                  onChange={update('department')}
                />
              </FormField>
              <FormField label="メールアドレス" required>
                <input
                  className="contact-field"
                  style={CONTACT_FIELD_STYLE}
                  type="email"
                  value={form.email}
                  onChange={update('email')}
                />
              </FormField>
              <FormField label="お問い合わせ内容" required>
                <textarea
                  className="contact-field"
                  style={{
                    ...CONTACT_FIELD_STYLE,
                    minHeight: 120,
                    resize: 'vertical',
                  }}
                  value={form.message}
                  onChange={update('message')}
                />
              </FormField>

              {/* ハニーポット: 実ユーザー・スクリーンリーダーからは不可視、
                  Botのフォーム自動入力には引っかかるようにする */}
              <input
                type="text"
                name="website"
                value={form.website}
                onChange={update('website')}
                tabIndex={-1}
                autoComplete="off"
                aria-hidden="true"
                style={{
                  position: 'absolute',
                  left: -9999,
                  width: 1,
                  height: 1,
                  opacity: 0,
                  pointerEvents: 'none',
                }}
              />

              {status === 'error' && errors.length > 0 && (
                <div
                  role="alert"
                  style={{
                    marginBottom: 18,
                    padding: '12px 16px',
                    border: '1px solid var(--accent-gold)',
                    borderRadius: 6,
                    fontSize: 13,
                    color: 'var(--ink)',
                    lineHeight: 1.7,
                  }}
                >
                  {errors.map((err, i) => (
                    <div key={i}>⚠ {err}</div>
                  ))}
                </div>
              )}

              <button
                type="submit"
                disabled={status === 'submitting' || !GAS_WEB_APP_URL}
                style={{
                  background: 'var(--accent-blue)',
                  color: '#fff',
                  border: 'none',
                  borderRadius: 2,
                  padding: '14px 32px',
                  fontSize: 15,
                  cursor:
                    status === 'submitting' || !GAS_WEB_APP_URL
                      ? 'not-allowed'
                      : 'pointer',
                  opacity:
                    status === 'submitting' || !GAS_WEB_APP_URL ? 0.5 : 1,
                }}
              >
                {status === 'submitting'
                  ? '送信中…'
                  : !GAS_WEB_APP_URL
                    ? 'フォーム準備中です'
                    : '送信する'}
              </button>
            </form>
          </React.Fragment>
        )}
      </Container>
    </section>
  );
}

/* ---------- App ---------- */

function App() {
  return (
    <>
      <Nav />
      <Hero />
      <Tsuyomi />
      <Jisseki />
      <Message />
      <Profile />
      <Renraku />
    </>
  );
}

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