Add Neon Mirai conference example

This commit is contained in:
Paul Bakaus
2026-04-24 17:22:59 -07:00
parent 25353448e2
commit 7de610c620
30 changed files with 2586 additions and 0 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 199 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 947 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

+22
View File
@@ -0,0 +1,22 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
<defs>
<filter id="rough" x="-20%" y="-20%" width="140%" height="140%">
<feTurbulence type="fractalNoise" baseFrequency="0.9" numOctaves="3" seed="42"/>
<feDisplacementMap in="SourceGraphic" scale="1.6"/>
</filter>
<mask id="ink">
<rect width="64" height="64" fill="white"/>
<g fill="black" opacity="0.22">
<circle cx="11" cy="18" r="1.4"/>
<circle cx="49" cy="13" r="1"/>
<circle cx="19" cy="48" r="1.2"/>
<circle cx="43" cy="44" r="1.5"/>
<path d="M8 55h18v2H8zM37 8h15v2H37z"/>
</g>
</mask>
</defs>
<g filter="url(#rough)" mask="url(#ink)" fill="none" stroke="#d95a35" stroke-width="3.2" stroke-linecap="square" stroke-linejoin="miter">
<path d="M10 10h44v44H10z"/>
<path d="M23 18v28M41 18v28M23 31h18M17 24h12M35 40h12"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 902 B

+344
View File
@@ -0,0 +1,344 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<meta name="description" content="NEO MIRAI AI Design Conference, Tokyo 2042. A retro-futurist conference experience for illustration, interfaces, machines, and optimism.">
<title>NEO MIRAI AI Design Conference</title>
<link rel="icon" href="../favicon.svg" type="image/svg+xml">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Azeret+Mono:wght@400;500;600;700&family=Chakra+Petch:wght@300;400;500;600&family=Zen+Old+Mincho:wght@400;500;600&display=swap" rel="stylesheet">
<link rel="stylesheet" href="./styles.css?v=20260424-speaker-dots-left">
</head>
<body>
<a class="skip-link" href="#main">Skip to content</a>
<header class="site-header" data-reveal>
<a class="brand-lockup" href="#" aria-label="NEO MIRAI home">
<span class="brand-mark" aria-hidden="true">
<span></span>
</span>
<span class="brand-word">
<span>NEO</span>
<span>MIRAI</span>
</span>
</a>
<button class="nav-toggle" type="button" aria-expanded="false" aria-controls="site-nav">
<span>Menu</span>
<i aria-hidden="true"></i>
</button>
<nav class="site-nav" id="site-nav" aria-label="Primary navigation">
<a href="#agenda" aria-current="page">Home</a>
<a href="#agenda">Agenda</a>
<a href="#speakers">Speakers</a>
<a href="#installations">Installations</a>
<a href="#experience">Experience</a>
<a href="#tickets">Practicals</a>
</nav>
<a class="ticket-pill" href="#tickets">
<span>Get tickets</span>
<svg viewBox="0 0 24 24" aria-hidden="true">
<path d="M5 12h12m-5-5 5 5-5 5"/>
</svg>
</a>
</header>
<main id="main">
<section class="hero" aria-labelledby="hero-title">
<div class="vertical-poem" aria-hidden="true">
<span>未来を描き、共に創る。</span>
<i></i>
<img src="./assets/stamp-seal.svg" alt="">
</div>
<div class="hero-copy" data-reveal>
<p class="kicker">新しい未来デザインカンファレンス</p>
<h1 id="hero-title">
<span>NEO MIRAI</span>
<span>AI DESIGN</span>
<span>CONFERENCE</span>
</h1>
<p class="hero-place">Tokyo 2042</p>
<p class="hero-summary">Illustration, interfaces, machines, optimism</p>
<div class="hero-meta" aria-label="Conference date and venue">
<span>May 2022, 2042</span>
<span>Tokyo International Forum</span>
</div>
</div>
<figure class="hero-art" data-reveal>
<img src="./assets/hero-city.webp" alt="An illustrated golden future Tokyo skyline with towers, terraces, and visitors walking toward the conference venue.">
<figcaption>Systems with warmth. Machines with a human horizon.</figcaption>
</figure>
</section>
<section class="agenda-block" id="agenda" aria-labelledby="agenda-title">
<div class="agenda-panel" data-reveal>
<p class="section-label">Agenda</p>
<h2 id="agenda-title">Three days of ideas and inspiration</h2>
<ol class="agenda-days" aria-label="Conference agenda highlights">
<li>
<time datetime="2042-05-20">Day 01 <span>05.20</span></time>
<div>
<h3>New Frontiers</h3>
<p>Keynotes, visions, and emerging paradigms.</p>
</div>
</li>
<li>
<time datetime="2042-05-21">Day 02 <span>05.21</span></time>
<div>
<h3>Design x Intelligence</h3>
<p>Crafting experiences with AI.</p>
</div>
</li>
<li>
<time datetime="2042-05-22">Day 03 <span>05.22</span></time>
<div>
<h3>Society &amp; Imagination</h3>
<p>Systems, ethics, and collective futures.</p>
</div>
</li>
</ol>
<a class="text-action" href="#tickets">View full agenda <span aria-hidden="true"></span></a>
</div>
<figure class="agenda-art" data-reveal>
<img src="./assets/agenda-architecture.webp" alt="A quiet illustrated architectural platform with amber circles, slim towers, and a lone visitor.">
<figcaption>創造は、未来をつくる最初の一歩。</figcaption>
</figure>
</section>
<section class="speakers" id="speakers" aria-labelledby="speakers-title">
<div class="section-intro" data-reveal>
<p class="section-label">Speakers</p>
<h2 id="speakers-title">Pioneers shaping tomorrow</h2>
<a class="text-action" href="#tickets">View full speakers <span aria-hidden="true"></span></a>
</div>
<div class="speaker-carousel" data-reveal aria-roledescription="carousel" aria-label="Featured speaker carousel">
<div class="speaker-track" id="speaker-track">
<article class="speaker-slide is-active" aria-label="Featured speakers set 1">
<ul class="speaker-grid" aria-label="Featured speakers, set 1">
<li class="speaker-person" style="--speaker-focus-x: 68%; --speaker-focus-y: 48%;" data-kanji="中村由美">
<img src="./assets/speaker-yumi-nakamura.webp" alt="Yumi Nakamura illustrated in profile before a golden sun and distant future city.">
<div class="speaker-meta">
<span>Yumi Nakamura</span>
<small>AI Ethicist &amp; Researcher</small>
</div>
</li>
<li class="speaker-person" style="--speaker-focus-x: 52%; --speaker-focus-y: 47%;" data-kanji="田中啓介">
<img src="./assets/speaker-keisuke-tanaka.webp" alt="Keisuke Tanaka illustrated before an amber sun and speculative city towers.">
<div class="speaker-meta">
<span>Keisuke Tanaka</span>
<small>Interaction Designer &amp; Creative Director</small>
</div>
</li>
<li class="speaker-person" style="--speaker-focus-x: 42%; --speaker-focus-y: 48%;" data-kanji="李ソフィア">
<img src="./assets/speaker-sophia-lee.webp" alt="Sophia Lee illustrated in profile near circular geometry and a temple skyline.">
<div class="speaker-meta">
<span>Sophia Lee</span>
<small>Machine Learning Artist</small>
</div>
</li>
</ul>
</article>
<article class="speaker-slide" aria-label="Featured speakers set 2" aria-hidden="true">
<ul class="speaker-grid" aria-label="Featured speakers, set 2">
<li class="speaker-person" style="--speaker-focus-x: 44%; --speaker-focus-y: 48%;" data-kanji="渡辺藍子">
<img src="./assets/speaker-aiko-watanabe.webp" alt="Aiko Watanabe illustrated in profile against a burnt-orange sun and pine silhouette.">
<div class="speaker-meta">
<span>Aiko Watanabe</span>
<small>Synthetic Media Director</small>
</div>
</li>
<li class="speaker-person" style="--speaker-focus-x: 52%; --speaker-focus-y: 48%;" data-kanji="佐藤蓮">
<img src="./assets/speaker-ren-sato.webp" alt="Ren Sato illustrated before Mount Fuji and flowing translucent forms.">
<div class="speaker-meta">
<span>Ren Sato</span>
<small>Robotics Experience Lead</small>
</div>
</li>
<li class="speaker-person" style="--speaker-focus-x: 46%; --speaker-focus-y: 48%;" data-kanji="黒田美奈">
<img src="./assets/speaker-mina-kuroda.webp" alt="Mina Kuroda illustrated before a red sun and vertical future towers.">
<div class="speaker-meta">
<span>Mina Kuroda</span>
<small>Computational Typographer</small>
</div>
</li>
</ul>
</article>
<article class="speaker-slide" aria-label="Featured speakers set 3" aria-hidden="true">
<ul class="speaker-grid" aria-label="Featured speakers, set 3">
<li class="speaker-person" style="--speaker-focus-x: 43%; --speaker-focus-y: 48%;" data-kanji="森花">
<img src="./assets/speaker-hana-mori.webp" alt="Hana Mori illustrated against a black eclipse circle and delicate future skyline.">
<div class="speaker-meta">
<span>Hana Mori</span>
<small>Speculative Systems Artist</small>
</div>
</li>
<li class="speaker-person" style="--speaker-focus-x: 52%; --speaker-focus-y: 47%;" data-kanji="伊藤大地">
<img src="./assets/speaker-daichi-ito.webp" alt="Daichi Ito illustrated before a red sun and dense machine city.">
<div class="speaker-meta">
<span>Daichi Ito</span>
<small>Neural Interface Researcher</small>
</div>
</li>
<li class="speaker-person" style="--speaker-focus-x: 42%; --speaker-focus-y: 48%;" data-kanji="小林恵美">
<img src="./assets/speaker-emi-kobayashi.webp" alt="Emi Kobayashi illustrated near a gold disk and Tokyo tower forms.">
<div class="speaker-meta">
<span>Emi Kobayashi</span>
<small>Civic AI Designer</small>
</div>
</li>
</ul>
</article>
<article class="speaker-slide" aria-label="Featured speakers set 4" aria-hidden="true">
<ul class="speaker-grid" aria-label="Featured speakers, set 4">
<li class="speaker-person" style="--speaker-focus-x: 70%; --speaker-focus-y: 48%;" data-kanji="荒田健司">
<img src="./assets/speaker-kenji-arata.webp" alt="Kenji Arata illustrated before a red sun and distant speculative towers.">
<div class="speaker-meta">
<span>Kenji Arata</span>
<small>Machine Imagination Lab</small>
</div>
</li>
<li class="speaker-person" style="--speaker-focus-x: 52%; --speaker-focus-y: 48%;" data-kanji="古賀直美">
<img src="./assets/speaker-naomi-koga.webp" alt="Naomi Koga illustrated below layered amber circles and a small temple skyline.">
<div class="speaker-meta">
<span>Naomi Koga</span>
<small>Data Rituals Curator</small>
</div>
</li>
<li class="speaker-person" style="--speaker-focus-x: 58%; --speaker-focus-y: 48%;" data-kanji="藤本亮">
<img src="./assets/speaker-ryo-fujimoto.webp" alt="Ryo Fujimoto illustrated near dark circular geometry and warm technical markings.">
<div class="speaker-meta">
<span>Ryo Fujimoto</span>
<small>Embodied Intelligence Architect</small>
</div>
</li>
</ul>
</article>
</div>
<div class="speaker-controls" aria-label="Speaker carousel controls">
<button class="speaker-dot is-active" type="button" data-slide="0" aria-label="Show speaker set 1" aria-current="true"></button>
<button class="speaker-dot" type="button" data-slide="1" aria-label="Show speaker set 2"></button>
<button class="speaker-dot" type="button" data-slide="2" aria-label="Show speaker set 3"></button>
<button class="speaker-dot" type="button" data-slide="3" aria-label="Show speaker set 4"></button>
</div>
</div>
</section>
<section class="installations" id="installations" aria-labelledby="installations-title">
<div class="section-intro" data-reveal>
<p class="section-label">Installations</p>
<h2 id="installations-title">Experiences beyond the screen</h2>
<a class="text-action" href="#tickets">Explore installations <span aria-hidden="true"></span></a>
</div>
<div class="installation-rhythm" data-reveal>
<article class="installation-item item-flux">
<img src="./assets/install-flux.webp" alt="A tiny visitor standing before a glowing orange spherical installation.">
<h3>Harmonic Flux</h3>
<p>Immersive environment</p>
</article>
<article class="installation-item item-dream">
<img src="./assets/install-dream.webp" alt="An illustrated generative ribbon floating through an amber exhibition space.">
<h3>Dream Compiler</h3>
<p>Generative sculpture</p>
</article>
<article class="installation-item item-echoes">
<img src="./assets/install-echoes.webp" alt="A lone visitor in a circular sound installation with a dark center.">
<h3>Echoes of Tomorrow</h3>
<p>AI soundscape</p>
</article>
</div>
</section>
<section class="manifesto" id="experience" aria-labelledby="manifesto-title">
<div class="manifesto-copy" data-reveal>
<p class="section-label">Manifesto</p>
<h2 id="manifesto-title">We believe the future is something we design together.</h2>
<a class="text-action text-action-light" href="#tickets">The NEO MIRAI manifesto <span aria-hidden="true"></span></a>
</div>
<figure class="manifesto-art" data-reveal>
<img src="./assets/manifesto-fuji-clean.webp" alt="Mount Fuji and a golden future city beneath a red sun.">
</figure>
</section>
<section class="tickets" id="tickets" aria-labelledby="tickets-title">
<img class="ticket-pine" src="./assets/pine-ticket.png" alt="" aria-hidden="true">
<div class="tickets-heading" data-reveal>
<p class="section-label">Tickets</p>
<h2 id="tickets-title">Choose your experience</h2>
</div>
<div class="ticket-options" data-reveal>
<article>
<h3>Attendee</h3>
<p>Full access to all talks and installations.</p>
<strong>¥ 49,000</strong>
<a href="mailto:tickets@neomirai.example">Select</a>
</article>
<article>
<h3>Student</h3>
<p>Access for students and educators.</p>
<strong>¥ 19,000</strong>
<a href="mailto:tickets@neomirai.example">Select</a>
</article>
<article>
<h3>Supporter</h3>
<p>Support the community and get benefits.</p>
<strong>¥ 99,000</strong>
<a href="mailto:tickets@neomirai.example">Select</a>
</article>
<article>
<h3>Group</h3>
<p>For teams of five or more.</p>
<strong>Contact us</strong>
<a href="mailto:tickets@neomirai.example">Inquire</a>
</article>
</div>
<aside class="ticket-seal" data-reveal>
<span class="ticket-seal-label">
<span>Get</span>
<span>Your</span>
<span>Ticket</span>
</span>
<a href="mailto:tickets@neomirai.example" aria-label="Email ticket office"></a>
</aside>
</section>
</main>
<footer class="site-footer">
<a class="brand-lockup brand-lockup-small" href="#" aria-label="NEO MIRAI home">
<span class="brand-mark" aria-hidden="true"><span></span></span>
<span class="brand-word"><span>NEO</span><span>MIRAI</span></span>
</a>
<p>未来を描き、共に創る。</p>
<nav aria-label="Footer navigation">
<a href="#agenda">About</a>
<a href="#speakers">Partners</a>
<a href="#installations">News</a>
<a href="#tickets">FAQ</a>
<a href="mailto:hello@neomirai.example">Contact</a>
</nav>
<div class="language-switch" aria-label="Language options">
<a href="#" aria-current="true">EN</a>
<span>/</span>
<a href="#">日本語</a>
</div>
</footer>
<script src="./script.js?v=20260424-speaker-dots-left"></script>
</body>
</html>
+155
View File
@@ -0,0 +1,155 @@
const header = document.querySelector(".site-header");
const nav = document.querySelector("#site-nav");
const navToggle = document.querySelector(".nav-toggle");
const revealTargets = document.querySelectorAll("[data-reveal]");
const navLinks = document.querySelectorAll(".site-nav a");
const reducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)");
const setHeaderState = () => {
header.classList.toggle("is-scrolled", window.scrollY > 12);
};
setHeaderState();
window.addEventListener("scroll", setHeaderState, { passive: true });
if (navToggle && nav) {
navToggle.addEventListener("click", () => {
const isOpen = navToggle.getAttribute("aria-expanded") === "true";
navToggle.setAttribute("aria-expanded", String(!isOpen));
nav.classList.toggle("is-open", !isOpen);
});
nav.addEventListener("click", (event) => {
if (event.target instanceof HTMLAnchorElement) {
navToggle.setAttribute("aria-expanded", "false");
nav.classList.remove("is-open");
}
});
}
const revealObserver = new IntersectionObserver(
(entries, observer) => {
entries.forEach((entry) => {
if (!entry.isIntersecting) return;
entry.target.classList.add("is-visible");
observer.unobserve(entry.target);
});
},
{ threshold: 0.16, rootMargin: "0px 0px -8% 0px" }
);
revealTargets.forEach((target) => {
const section = target.closest("section");
const localTargets = section
? Array.from(section.querySelectorAll("[data-reveal]"))
: Array.from(revealTargets);
const localIndex = Math.max(localTargets.indexOf(target), 0);
const delay = Math.min(localIndex, 4) * 110;
target.style.setProperty("--reveal-delay", `${delay}ms`);
revealObserver.observe(target);
});
window.setTimeout(() => {
revealTargets.forEach((target) => target.classList.add("is-visible"));
}, 1600);
const sections = Array.from(document.querySelectorAll("main section[id]"));
const activeObserver = new IntersectionObserver(
(entries) => {
const visible = entries
.filter((entry) => entry.isIntersecting)
.sort((a, b) => b.intersectionRatio - a.intersectionRatio)[0];
if (!visible) return;
navLinks.forEach((link) => {
const isActive = link.getAttribute("href") === `#${visible.target.id}`;
if (isActive) {
link.setAttribute("aria-current", "page");
} else {
link.removeAttribute("aria-current");
}
});
},
{ threshold: [0.24, 0.42, 0.64], rootMargin: "-18% 0px -52% 0px" }
);
sections.forEach((section) => activeObserver.observe(section));
const speakerCarousel = document.querySelector(".speaker-carousel");
if (speakerCarousel) {
const speakerTrack = speakerCarousel.querySelector(".speaker-track");
const speakerSlides = Array.from(speakerCarousel.querySelectorAll(".speaker-slide"));
const speakerDots = Array.from(speakerCarousel.querySelectorAll(".speaker-dot"));
let activeSpeakerIndex = 0;
let speakerTimer = null;
const setSpeakerSlide = (index) => {
activeSpeakerIndex = (index + speakerSlides.length) % speakerSlides.length;
speakerCarousel.style.setProperty("--speaker-index", activeSpeakerIndex);
speakerCarousel.style.setProperty("--speaker-offset", `${activeSpeakerIndex * -100}%`);
speakerSlides.forEach((slide, slideIndex) => {
const isActive = slideIndex === activeSpeakerIndex;
slide.classList.toggle("is-active", isActive);
slide.toggleAttribute("aria-hidden", !isActive);
});
speakerDots.forEach((dot, dotIndex) => {
const isActive = dotIndex === activeSpeakerIndex;
dot.classList.toggle("is-active", isActive);
if (isActive) {
dot.setAttribute("aria-current", "true");
} else {
dot.removeAttribute("aria-current");
}
});
};
const stopSpeakerTimer = () => {
if (!speakerTimer) return;
window.clearInterval(speakerTimer);
speakerTimer = null;
};
const startSpeakerTimer = () => {
if (reducedMotion.matches || speakerSlides.length < 2 || speakerTimer) return;
speakerTimer = window.setInterval(() => {
setSpeakerSlide(activeSpeakerIndex + 1);
}, 5600);
};
speakerDots.forEach((dot) => {
dot.addEventListener("click", () => {
const slideIndex = Number(dot.dataset.slide);
if (Number.isNaN(slideIndex)) return;
setSpeakerSlide(slideIndex);
stopSpeakerTimer();
startSpeakerTimer();
});
});
speakerCarousel.addEventListener("pointerenter", stopSpeakerTimer);
speakerCarousel.addEventListener("pointerleave", startSpeakerTimer);
speakerCarousel.addEventListener("focusin", stopSpeakerTimer);
speakerCarousel.addEventListener("focusout", startSpeakerTimer);
speakerCarousel.addEventListener("keydown", (event) => {
if (event.key === "ArrowDown" || event.key === "ArrowRight") {
event.preventDefault();
setSpeakerSlide(activeSpeakerIndex + 1);
}
if (event.key === "ArrowUp" || event.key === "ArrowLeft") {
event.preventDefault();
setSpeakerSlide(activeSpeakerIndex - 1);
}
});
if (speakerTrack) {
setSpeakerSlide(0);
startSpeakerTimer();
}
}
File diff suppressed because it is too large Load Diff