function getFeaturedImage(item, fallback) {
return (item && item._embedded && item._embedded["wp:featuredmedia"] && item._embedded["wp:featuredmedia"][0] && item._embedded["wp:featuredmedia"][0].source_url) || fallback;
}
function getTermName(item, taxonomy) {
const groups = (item && item._embedded && item._embedded["wp:term"]) || [];
for (const group of groups) {
const t = group.find((t) => t.taxonomy === taxonomy);
if (t) return t.name;
}
return "";
}
function stripTags(html) {
// タグ除去に加え、WordPressが変換した文字参照(’ など)も元の文字に戻す
return (new DOMParser().parseFromString(html || "", "text/html").body.textContent || "").trim();
}
function splitTitle(title) {
const idx = title.indexOf("、");
if (idx === -1) return [title];
return [title.slice(0, idx + 1), title.slice(idx + 1)];
}
const STORY_ITEMS = [
{
image: "/wp-content/themes/original/assets/story-photo-highschool.png",
category: "高校生 / INTERVIEW",
title: ["学校の外で、", "はじめて“企画”をやってみた。"],
name: "N.Yさん",
},
{
image: "/wp-content/themes/original/assets/story-photo-university.png",
category: "大学生 / INTERVIEW",
title: ["「好き」が、", "最初のきっかけになった。"],
name: "N.Yさん",
},
{
image: "/wp-content/themes/original/assets/story-photo-worker.png",
category: "若手社会人 / INTERVIEW",
title: ["会社を辞めずに、", "小さく試してみた。"],
name: "N.Yさん",
},
];
const FAQ_ITEMS = [
{
q: "高校生・大学生でも参加できますか?",
a: "はい。高校生・大学生も対象です。学生から社会人まで、何か始めてみたい方を歓迎します。",
},
{
q: "アイデアや起業の経験がなくても大丈夫?",
a: "大丈夫です。専門知識や明確なアイデアがなくても、話を聞いたりワークを通じて考えたりするところから始められます。",
},
{
q: "参加費はかかりますか?",
a: "全4回とも参加無料です。各回20〜30名程度を予定しています。",
},
{
q: "1回だけでも参加できますか?",
a: "第1回「はじめの一歩ラボ」は単発参加が可能です。ほかの回の参加条件は、各回の案内をご確認ください。",
},
{
q: "最後の発表会は、誰でも発表できますか?",
a: "第4回の発表はプログラム受講者が対象です。一般観覧も予定しています。詳細は決まり次第ご案内します。",
},
];
const HERO_LEFT_PERSON_IMGS = [
"/wp-content/themes/original/assets/hero-left-person-154-51.svg", "/wp-content/themes/original/assets/hero-left-person-154-52.svg", "/wp-content/themes/original/assets/hero-left-person-154-53.svg",
"/wp-content/themes/original/assets/hero-left-person-154-54.svg", "/wp-content/themes/original/assets/hero-left-person-154-55.svg", "/wp-content/themes/original/assets/hero-left-person-154-56.svg",
"/wp-content/themes/original/assets/hero-left-person-154-57.svg", "/wp-content/themes/original/assets/hero-left-person-154-58.svg", "/wp-content/themes/original/assets/hero-left-person-154-59.svg",
"/wp-content/themes/original/assets/hero-left-person-154-60.svg", "/wp-content/themes/original/assets/hero-left-person-154-62.svg", "/wp-content/themes/original/assets/hero-left-person-154-64.svg",
"/wp-content/themes/original/assets/hero-left-person-154-68-mask.svg", "/wp-content/themes/original/assets/hero-left-person-154-68.svg", "/wp-content/themes/original/assets/hero-left-person-154-71.svg",
"/wp-content/themes/original/assets/hero-left-person-154-72.svg", "/wp-content/themes/original/assets/hero-left-person-154-73.svg", "/wp-content/themes/original/assets/hero-left-person-154-74.svg",
"/wp-content/themes/original/assets/hero-left-person-154-75.svg", "/wp-content/themes/original/assets/hero-left-person-154-76.svg", "/wp-content/themes/original/assets/hero-left-person-154-79.svg",
"/wp-content/themes/original/assets/hero-left-person-154-80.svg", "/wp-content/themes/original/assets/hero-left-person-154-81.svg", "/wp-content/themes/original/assets/hero-left-person-154-82.svg",
"/wp-content/themes/original/assets/hero-left-person-154-83.svg", "/wp-content/themes/original/assets/hero-left-person-154-84.svg", "/wp-content/themes/original/assets/hero-left-person-154-85.svg",
"/wp-content/themes/original/assets/hero-left-person-154-86.svg", "/wp-content/themes/original/assets/hero-left-person-154-87.svg", "/wp-content/themes/original/assets/hero-left-person-154-88.svg",
"/wp-content/themes/original/assets/hero-left-person-154-89.svg", "/wp-content/themes/original/assets/hero-left-person-154-90.svg", "/wp-content/themes/original/assets/hero-left-person-154-91.svg",
"/wp-content/themes/original/assets/hero-left-person-154-95.svg", "/wp-content/themes/original/assets/hero-left-person-154-96.svg", "/wp-content/themes/original/assets/hero-left-person-154-97.svg",
"/wp-content/themes/original/assets/hero-left-person-154-98.svg", "/wp-content/themes/original/assets/hero-left-person-154-99.svg", "/wp-content/themes/original/assets/hero-left-person-154-100.svg",
];
const HERO_RIGHT_PERSON_IMGS = [
"/wp-content/themes/original/assets/hero-right-person-154-104.svg", "/wp-content/themes/original/assets/hero-right-person-154-105.svg", "/wp-content/themes/original/assets/hero-right-person-154-106.svg",
"/wp-content/themes/original/assets/hero-right-person-154-107.svg", "/wp-content/themes/original/assets/hero-right-person-154-108.svg", "/wp-content/themes/original/assets/hero-right-person-154-109.svg",
"/wp-content/themes/original/assets/hero-right-person-154-111.svg", "/wp-content/themes/original/assets/hero-right-person-154-113.svg", "/wp-content/themes/original/assets/hero-right-person-154-117-mask.svg",
"/wp-content/themes/original/assets/hero-right-person-154-117.svg", "/wp-content/themes/original/assets/hero-right-person-154-120.svg", "/wp-content/themes/original/assets/hero-right-person-154-121.svg",
"/wp-content/themes/original/assets/hero-right-person-154-122.svg", "/wp-content/themes/original/assets/hero-right-person-154-123.svg", "/wp-content/themes/original/assets/hero-right-person-154-124.svg",
"/wp-content/themes/original/assets/hero-right-person-154-125.svg", "/wp-content/themes/original/assets/hero-right-person-154-128.svg", "/wp-content/themes/original/assets/hero-right-person-154-129.svg",
"/wp-content/themes/original/assets/hero-right-person-154-130.svg", "/wp-content/themes/original/assets/hero-right-person-154-131.svg", "/wp-content/themes/original/assets/hero-right-person-154-132.svg",
"/wp-content/themes/original/assets/hero-right-person-154-133.svg", "/wp-content/themes/original/assets/hero-right-person-154-134.svg", "/wp-content/themes/original/assets/hero-right-person-154-135.svg",
"/wp-content/themes/original/assets/hero-right-person-154-136.svg", "/wp-content/themes/original/assets/hero-right-person-154-137.svg", "/wp-content/themes/original/assets/hero-right-person-154-138.svg",
"/wp-content/themes/original/assets/hero-right-person-154-139.svg", "/wp-content/themes/original/assets/hero-right-person-154-140.svg", "/wp-content/themes/original/assets/hero-right-person-154-144.svg",
"/wp-content/themes/original/assets/hero-right-person-154-145.svg", "/wp-content/themes/original/assets/hero-right-person-154-146.svg", "/wp-content/themes/original/assets/hero-right-person-154-147.svg",
"/wp-content/themes/original/assets/hero-right-person-154-148.svg", "/wp-content/themes/original/assets/hero-right-person-154-149.svg", "/wp-content/themes/original/assets/hero-right-person-154-150.svg",
"/wp-content/themes/original/assets/hero-right-person-154-151.svg", "/wp-content/themes/original/assets/hero-right-person-154-152.svg",
];
// イラスト|パソコンを囲む人物(Movieセクション装飾)
function MovieIllust({
className,
mask1Position = "3.748px -41.201px",
mask1Size = "56.485px 62.333px",
mask2Position = "6.021px -41.945px",
mask2Size = "53.818px 63.186px",
}) {
const p = "/wp-content/themes/original/assets/movie-illust-227-";
return (
);
}
// イラスト|ジャンプする人物(Eventセクション装飾)
function EventIllust({ className }) {
const p = "/wp-content/themes/original/assets/event-illust-227-";
return (
);
}
// イラスト|疑問を持つ人物(FAQセクション装飾)
function FaqIllust({ className, maskPosition = "7.182px -35.837px", maskSize = "70.983px 69.098px" }) {
const p = "/wp-content/themes/original/assets/faq-illust-227-";
return (
);
}
// アイコン|線画(Font Awesome Regularウェイト相当。Freeプランに該当スタイルがないため自作)
function IconPlay({ className }) {
return (
);
}
function IconPause({ className }) {
return (
);
}
function IconCaretLeft({ className }) {
return (
);
}
function IconCaretRight({ className }) {
return (
);
}
function IconExternalLink({ className }) {
return (
);
}
function Hero() {
return (
{/* SP: ヒーロー背景ウェーブ(セクション下端に重ねる) */}
{/* PC: Figma(1440px基準)の絶対配置を、画面幅に応じて比率を保ったまま縮小表示する */}
{/* SP: 縦積みレイアウト */}
);
}
function About() {
return (
まだ、何をするか決まっていなくても大丈夫。
学校や仕事の外で、新しい人に会ってみたい。
気になることはあるけれど、何から始めればいいかわからない。
長崎チャレパスは、そんな
「やってみたい」
を持ち寄って、
一緒に試してみるためのプログラム
です。
かつて出島が新しいものの入り口だったように、
長崎には、外の世界と混ざり合いながら
新しいものを生み出してきた歴史があります。
日常のちょっとした違和感や
「こうなったらいいのに」という思いつきも、
ここでは立派な
挑戦のはじまり
です。
「チャレパス」は、Challenge Pass。
自分の道(Path)を描きはじめるための、参加証(Pass)です。
);
}
function Stories() {
const [items, setItems] = useState(STORY_ITEMS.map((i) => ({ ...i, link: STORY_PAGE_URL })));
useEffect(() => {
fetch(`${WP_API}/wp/v2/story?_embed&per_page=3&orderby=date&order=desc`)
.then((r) => (r.ok ? r.json() : null))
.then((data) => {
if (!data || !data.length) return;
setItems(
data.map((post) => ({
image: getFeaturedImage(post, "/wp-content/themes/original/assets/story-photo-worker.png"),
category: `${getTermName(post, "story_category") || "INTERVIEW"} / INTERVIEW`,
title: splitTitle(stripTags(post.title.rendered)),
name: (post.story_fields && post.story_fields.interviewee_name) || "",
link: post.link,
}))
);
})
.catch(() => {});
}, []);
return (
);
}
// TikTok動画URLから数値の動画IDを取り出す(例: .../video/1234567890 → 1234567890)
function getTiktokVideoId(url) {
const m = (url || "").match(/video\/(\d+)/);
return m ? m[1] : "";
}
// TikTok公式の埋め込み(blockquote.tiktok-embed)をモーダルで表示する
// embed.js(front-page.phpで読み込み)がDOMを監視し、挿入されたblockquoteを自動でiframe化する
function TikTokModal({ item, onClose }) {
const blockquoteRef = useRef(null);
useEffect(() => {
if (!item || !blockquoteRef.current) return;
if (window.tiktokEmbed && window.tiktokEmbed.lib && typeof window.tiktokEmbed.lib.render === "function") {
window.tiktokEmbed.lib.render([blockquoteRef.current]);
}
}, [item]);
if (!item) return null;
const videoId = getTiktokVideoId(item.tiktokUrl);
return (
);
}
// TikTokフィード(Feeds for TikTok プラグイン)の見た目をMovieセクション用に上書きするクラス
// プラグインがstyle属性や詳細度の高いCSSで指定しているため、いずれも!(important)付きにしている
const TIKTOK_FEED_CLASS = [
// サムネイル枠:高さ269px固定で縦長動画が切れるため、9:16の縦長にして全体を表示する
"[&_.sb-post-item-image-wrap]:!h-auto [&_.sb-post-item-image-wrap]:aspect-[9/16] [&_.sb-post-item-image]:!h-full",
// 一覧:列数設定どおりに等分すると件数が少ないとき横いっぱいに広がるため、一定幅のカードを左から詰める(SP最小140px・PC最小220px)
"[&_.sb-grid-wrapper]:![grid-template-columns:repeat(auto-fill,minmax(140px,1fr))] md:[&_.sb-grid-wrapper]:![grid-template-columns:repeat(auto-fill,minmax(220px,1fr))]",
// ヘッダー:紹介文が無いとアイコンと名前が中央寄せになるため左寄せにする
"[&_.sb-feed-header-profile]:!justify-start",
// ヘッダー(SP・狭い幅):縦並び・中央寄せになるため左寄せにする。640pxはプラグイン側の切替幅、.sb-narrow-widthは表示幅が狭いときプラグインが付けるクラス
"max-[640px]:[&_.sb-feed-header-content]:!items-start max-[640px]:[&_.sb-feed-header-profile]:!items-start max-[640px]:[&_.sb-feed-header-user-info]:!items-start",
"[&_.sb-narrow-width_.sb-feed-header-content]:!items-start [&_.sb-narrow-width_.sb-feed-header-profile]:!items-start [&_.sb-narrow-width_.sb-feed-header-user-info]:!items-start",
].join(" ");
function Movie() {
// 【旧実装・コメントアウト中】「TikTok動画」投稿を手動登録して自作カルーセルで表示していた仕組み。
// TikTokフィード(Feeds for TikTok プラグイン)に切り替えたため停止。戻す場合はこの関数内の「旧実装」部分のコメントを外す。
/*
const [items, setItems] = useState([]);
const [index, setIndex] = useState(0);
const [playing, setPlaying] = useState(true);
const [activeVideo, setActiveVideo] = useState(null);
const [loaded, setLoaded] = useState(false);
const trackRef = useRef(null);
*/
const feedRef = useRef(null);
// front-page.php で描画済みのTikTokフィードを、このセクション内へ移動する
// (コピーではなく移動なので、プラグインのJSで組み立てた表示や動作はそのまま保たれる)
useEffect(() => {
const source = document.getElementById("tiktok-feed-source");
if (!source || !feedRef.current) return;
while (source.firstChild) feedRef.current.appendChild(source.firstChild);
}, []);
// 【旧実装・コメントアウト中】TikTok動画投稿の取得とカルーセルの自動送り
/*
useEffect(() => {
fetch(`${WP_API}/wp/v2/tiktok_video?_embed&per_page=20&orderby=menu_order&order=asc`)
.then((r) => (r.ok ? r.json() : null))
.then((data) => {
if (!data || !data.length) return;
setItems(
data.map((post) => ({
image: getFeaturedImage(post, ""),
caption: stripTags(post.title.rendered),
tiktokUrl: (post.video_fields && post.video_fields.tiktok_url) || "",
}))
);
})
.catch((err) => console.error("TikTok動画の取得に失敗しました", err))
.finally(() => setLoaded(true));
}, []);
const goTo = useCallback((i) => {
const clamped = Math.max(0, Math.min(items.length - 1, i));
setIndex(clamped);
}, [items.length]);
const isFirstRender = useRef(true);
useEffect(() => {
if (isFirstRender.current) {
isFirstRender.current = false;
return;
}
if (trackRef.current) {
const card = trackRef.current.children[index];
if (card) {
trackRef.current.scrollTo({ left: card.offsetLeft, behavior: "smooth" });
}
}
}, [index]);
useEffect(() => {
if (!playing || items.length === 0) return;
const timer = setInterval(() => {
setIndex((i) => (i + 1) % items.length);
}, 4000);
return () => clearInterval(timer);
}, [playing, index, items.length]);
*/
return (
Short Movie
まずは動画で、
のぞいてみよう
挑戦している人の声や、イベントの雰囲気を短い動画で。
読むより先に、まずは見てみてください。
{/* 【旧実装・コメントアウト中】Coming Soon・自作カルーセル・モーダル・操作ボタン
(ブロックコメントは入れ子にできないため、内側の注記は // に置き換えている。戻すときは {/* *\/} に戻す)
// 動画が1件もなければ Coming Soon を表示する(取得完了前は何も出さない)
{loaded && items.length === 0 && (
Coming Soon
)}
{items.map((item) => (
item.tiktokUrl && setActiveVideo(item)}
className={`flex flex-col gap-[12px] items-start overflow-clip shrink-0 w-[220px] md:w-[282px] ${item.tiktokUrl ? "cursor-pointer" : ""}`}
>
{item.image && (

)}
{item.tiktokUrl && (
)}
{item.caption}
))}
setActiveVideo(null)} />
// 動画が5件以下のときは操作ボタンを表示しない
{items.length > 5 && (
)}
*/}
{/* TikTokフィード(プラグイン)の表示先。フィードが無いときは空のまま非表示。見た目の上書きは TIKTOK_FEED_CLASS を参照 */}
);
}
const EVENT_FALLBACK = [
{
id: "fallback-1", stage: "STAGE 01", theme: "見る", title: "はじめの一歩ラボ",
date: "2026年11月12日(木) 00:00~00:00", location: "CO-DEJIMA",
leadHeading: "「何かやってみたい」を、話すところから。",
leadBody: "身近な挑戦の話を聞き、アイデアを考えるワークや対話を通じて、自分の最初の一歩を見つけます。",
googlemapUrl: "", priceLabel: "参加費無料",
programItems: ["起業や新規事業のリアル", "小さく始める考え方", "アイデア発想ワーク", "挑戦者との対話"],
targetAudience: "若手社会人/学生/社内起業層/挑戦したい方",
applyUrl: "",
speakerPhoto: "", speakerName: "", speakerTitle: "", speakerBio: "", speakerProfileUrl: "",
speaker2Photo: "", speaker2Name: "", speaker2Title: "", speaker2Bio: "", speaker2ProfileUrl: "",
},
{ id: "fallback-2", stage: "STAGE 02", theme: "共感する", title: "NAGASAKI HERO's TALK", date: "2026年12月00日(○) 00:00~00:00", location: "", leadHeading: "", leadBody: "", googlemapUrl: "", priceLabel: "", programItems: [], targetAudience: "", applyUrl: "", speakerPhoto: "", speakerName: "", speakerTitle: "", speakerBio: "", speakerProfileUrl: "", speaker2Photo: "", speaker2Name: "", speaker2Title: "", speaker2Bio: "", speaker2ProfileUrl: "" },
{ id: "fallback-3", stage: "STAGE 013", theme: "体験する", title: "チャレンジワークショップ", date: "2027年01月00日(○) 00:00~00:00", location: "", leadHeading: "", leadBody: "", googlemapUrl: "", priceLabel: "", programItems: [], targetAudience: "", applyUrl: "", speakerPhoto: "", speakerName: "", speakerTitle: "", speakerBio: "", speakerProfileUrl: "", speaker2Photo: "", speaker2Name: "", speaker2Title: "", speaker2Bio: "", speaker2ProfileUrl: "" },
{ id: "fallback-4", stage: "STAGE 04", theme: "一歩踏み出す", title: "NEXT ACTION Pitch", date: "2027年02月00日(○) 00:00~00:00", location: "", leadHeading: "", leadBody: "", googlemapUrl: "", priceLabel: "", programItems: [], targetAudience: "", applyUrl: "", speakerPhoto: "", speakerName: "", speakerTitle: "", speakerBio: "", speakerProfileUrl: "", speaker2Photo: "", speaker2Name: "", speaker2Title: "", speaker2Bio: "", speaker2ProfileUrl: "" },
];
function Event() {
const [events, setEvents] = useState(EVENT_FALLBACK);
const [openId, setOpenId] = useState(EVENT_FALLBACK[0].id);
// 開閉でクリックした見出しが画面上でずれないよう、クリック時の位置を覚えておく
const anchorRef = useRef(null);
const toggle = (id, e) => {
const button = e.currentTarget;
anchorRef.current = { button, top: button.getBoundingClientRect().top };
setOpenId(openId === id ? null : id);
};
// 描画後・画面表示前に、見出しがずれた分だけスクロールを戻す
React.useLayoutEffect(() => {
const anchor = anchorRef.current;
if (!anchor) return;
anchorRef.current = null;
const diff = anchor.button.getBoundingClientRect().top - anchor.top;
if (diff !== 0) window.scrollBy(0, diff);
}, [openId]);
useEffect(() => {
fetch(`${WP_API}/wp/v2/event?per_page=20&orderby=id&order=asc`)
.then((r) => (r.ok ? r.json() : null))
.then((data) => {
if (!data || !data.length) return;
const mapped = data.map((post) => {
const acf = post.event_fields || {};
return {
id: post.id,
stage: acf.event_stage || "",
theme: acf.event_theme || "",
title: stripTags(post.title.rendered),
date: acf.event_date || "",
location: acf.event_location || "",
leadHeading: acf.lead_heading || "",
leadBody: acf.lead_body || "",
googlemapUrl: acf.googlemap_url || "",
priceLabel: acf.price_label || "",
programItems: acf.program_items || [],
targetAudience: acf.target_audience || "",
applyUrl: acf.apply_url || "",
speakerPhoto: acf.speaker_photo || "",
speakerName: acf.speaker_name || "",
speakerTitle: acf.speaker_title || "",
speakerBio: acf.speaker_bio || "",
speakerProfileUrl: acf.speaker_profile_url || "",
speaker2Photo: acf.speaker2_photo || "",
speaker2Name: acf.speaker2_name || "",
speaker2Title: acf.speaker2_title || "",
speaker2Bio: acf.speaker2_bio || "",
speaker2ProfileUrl: acf.speaker2_profile_url || "",
};
});
setEvents(mapped);
setOpenId(mapped[0].id);
})
.catch(() => {});
}, []);
return (
見る → 共感する → 体験する → 一歩踏み出す
全4回を通して、自分の「やってみたい」を見つけ、試していくプログラムです。
各回20〜30名程度・参加無料
第1回は単発参加も可能です。第4回の発表は受講者が対象です。
{events.map((ev) => {
const isOpen = openId === ev.id;
return (
{isOpen && (
<>
{ev.leadHeading && (
{ev.leadHeading}
)}
{ev.leadBody && (
{ev.leadBody}
)}
{ev.date}
{ev.location && (
{ev.location}
{ev.googlemapUrl && (
Googlemap
)}
)}
{ev.priceLabel && (
)}
{ev.programItems.length > 0 && (
<>
プログラム
{ev.programItems.map((item, i) => (
))}
>
)}
{ev.targetAudience && (
)}
{(() => {
const speakers = [
{ photo: ev.speakerPhoto, name: ev.speakerName, title: ev.speakerTitle, bio: ev.speakerBio, profileUrl: ev.speakerProfileUrl },
{ photo: ev.speaker2Photo, name: ev.speaker2Name, title: ev.speaker2Title, bio: ev.speaker2Bio, profileUrl: ev.speaker2ProfileUrl },
].filter((s) => s.name);
if (!speakers.length) return null;
return (
<>
{speakers.map((speaker, i) => (
{speaker.photo && (

)}
Guest Speaker
{speaker.name}
{speaker.title && (
{speaker.title}
)}
{speaker.bio && (
{speaker.bio}
)}
{speaker.profileUrl && (
プロフィールを見る
)}
))}
>
);
})()}
{ev.applyUrl && (
このイベントに申し込む
)}
>
)}
);
})}
);
}
function Faq() {
const [items, setItems] = useState(FAQ_ITEMS);
useEffect(() => {
fetch(`${WP_API}/wp/v2/faq?per_page=20&orderby=id&order=asc`)
.then((r) => (r.ok ? r.json() : null))
.then((data) => {
if (!data || !data.length) return;
setItems(data.map((post) => ({ q: stripTags(post.title.rendered), a: stripTags(post.content.rendered) })));
})
.catch(() => {});
}, []);
return (
{items.map((item) => (
))}
);
}
function App() {
const [mobileOpen, setMobileOpen] = useState(false);
// 他ページから /#event などで来たとき、描画後にセクションへスクロールする。
// 各セクションのデータ取得で高さが変わるため、しばらくは位置を合わせ直す(ユーザーが操作したら止める)
useEffect(() => {
const id = decodeURIComponent(window.location.hash.slice(1));
if (!id) return;
const scrollToTarget = () => {
const el = document.getElementById(id);
if (el) el.scrollIntoView();
};
scrollToTarget();
const observer = new ResizeObserver(scrollToTarget);
observer.observe(document.body);
const stop = () => {
observer.disconnect();
clearTimeout(timer);
["wheel", "touchstart", "keydown"].forEach((ev) => window.removeEventListener(ev, stop));
};
const timer = setTimeout(stop, 3000);
["wheel", "touchstart", "keydown"].forEach((ev) => window.addEventListener(ev, stop, { passive: true }));
return stop;
}, []);
return (
<>
setMobileOpen(true)} />
setMobileOpen(false)} />
>
);
}
ReactDOM.createRoot(document.getElementById("app")).render();