This commit is contained in:
2024-08-27 04:11:46 +02:00
parent ad337c76e2
commit ee4840da3a
658 changed files with 17330 additions and 323 deletions

View File

@@ -11,6 +11,7 @@ import {
ShieldCheckIcon,
FilmIcon,
GlobeAltIcon,
RocketLaunchIcon,
} from '@heroicons/react/20/solid'
const features = [
@@ -50,10 +51,10 @@ import {
return (
<div className="bg-white lg:py-20 py-24">
<div className="mx-auto max-w-7xl px-6 lg:px-8">
<div className="mx-auto max-w-2xl sm:text-center">
<div className="mx-auto max-w-4xl sm:text-center">
<h2 className="text-base font-medium font-mono leading-7 text-blue-600">Get Started</h2>
<p className="mt-2 lg:text-5xl font-semibold tracking-tight text-blue-700 text-3xl">Build Your Own Verse</p>
<p className="mt-6 text-lg leading-8 text-blue-900">
<p className="mt-2 font-display text-4xl font-medium tracking-tighter text-blue-600 sm:text-5xl">Build Your Own Verse</p>
<p className="mt-6 font-display text-2xl tracking-tight text-blue-900">
Create and customize your virtual world with powerful tools and resources that make building and managing your digital space easy and intuitive.
</p>
</div>
@@ -88,6 +89,14 @@ import {
</div>
))}
</dl>
<div className="mt-16 flex items-center justify-center gap-x-6">
<a
href="#"
className="rounded-xl bg-blue-700 px-3.5 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-blue-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600"
>
Build Your Own Verse Now <RocketLaunchIcon className="h-4 w-4 inline-block -mt-0.5" />
</a>
</div>
</div>
</div>
)

View File

@@ -26,7 +26,7 @@ export function Header() {
<div className="hidden lg:flex lg:items-center lg:gap-8 lg:grow lg:basis-0">
<div className="flex gap-8 mx-auto">
{navigationItems.map((item) => (
<a key={item.name} href={item.href} className="text-blue-600 hover:text-blue-800">
<a key={item.name} href={item.href} className="text-blue-700 font-semibold hover:text-blue-900">
{item.name}
</a>
))}

View File

@@ -27,11 +27,19 @@ export function Homepage() {
where you can express yourself freely, build meaningful relationships,
and explore endless possibilities in an environment that celebrates diversity and authenticity.</p>
</div>
<Button href="#" className="mt-2 mb-10 w-30">
Join OurVerse
</Button>
<div className="mt-10 pb-8 flex items-center gap-x-6">
<a
href="#"
className="rounded-xl bg-blue-700 px-3.5 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-blue-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600"
>
Join OurVerse
</a>
<a href="#" className="text-sm font-semibold leading-6 text-blue-900 hover:text-blue-700">
Learn more <span aria-hidden="true"></span>
</a>
</div>
</div>
</Container>
</Container>
</Gradient>
);
}

View File

@@ -0,0 +1,233 @@
'use client'
import { useEffect, useState } from 'react'
import { Tab, TabGroup, TabList, TabPanel, TabPanels } from '@headlessui/react'
import clsx from 'clsx'
import { BackgroundImage } from '@/components/BackgroundImage'
import { Container } from '@/components/Container'
const schedule = [
{
date: 'Enhancing Education',
summary:
'Transform traditional education with distant learning opportunities.',
timeSlots: [
{
name: 'Virtual Classrooms',
description: 'Create engaging and interactive learning environments where students can collaborate and participate in real-time.',
},
{
name: 'Distance Learning',
description: 'Provide accessible education to students around the world with flexible and remote learning solutions.',
},
{
name: 'Professional Training',
description: 'Equip professionals with advanced skills through immersive, hands-on training experiences.',
},
],
},
{
date: 'Supporting Healthcare',
summary:
' Innovate healthcare by integrating virtual tools for a holistic approach to well-being.',
timeSlots: [
{
name: 'Virtual Health Consultations',
description: 'Offer remote medical consultations in secure and accessible virtual environments.',
},
{
name: 'Mental Health Support',
description: 'Provide confidential and supportive virtual spaces for mental health counseling and therapy.',
},
{
name: 'Promoting Social Good',
description: 'Utilize virtual platforms for fundraising events and community engagement, driving positive change globally.',
},
],
},
{
date: 'Empowering Africa',
summary:
'Foster cultural preservation, economic growth, and educational access across Africa.',
timeSlots: [
{
name: 'Cultural Preservation',
description: 'Protect and celebrate Africas rich cultural heritage through virtual exhibits and experiences.',
},
{
name: 'Economic Development',
description: 'Drive economic growth by creating virtual marketplaces and entrepreneurial opportunities.',
},
{
name: 'Educational Access',
description: ' Expand educational opportunities by delivering learning resources to underserved communities.',
},
],
},
{
date: 'Advocate for environmental conservation through virtual eco-tours, green initiatives',
summary:
'Foster cultural preservation, economic growth, and educational access across Africa.',
timeSlots: [
{
name: 'Cultural Preservation',
description: 'Protect and celebrate Africas rich cultural heritage through virtual exhibits and experiences.',
},
{
name: 'Economic Development',
description: 'Drive economic growth by creating virtual marketplaces and entrepreneurial opportunities.',
},
{
name: 'Educational Access',
description: ' Expand educational opportunities by delivering learning resources to underserved communities.',
},
],
},
]
function ScheduleTabbed() {
let [tabOrientation, setTabOrientation] = useState('horizontal')
useEffect(() => {
let smMediaQuery = window.matchMedia('(min-width: 640px)')
function onMediaQueryChange({ matches }) {
setTabOrientation(matches ? 'vertical' : 'horizontal')
}
onMediaQueryChange(smMediaQuery)
smMediaQuery.addEventListener('change', onMediaQueryChange)
return () => {
smMediaQuery.removeEventListener('change', onMediaQueryChange)
}
}, [])
return (
<TabGroup
className="mx-auto grid max-w-2xl grid-cols-1 gap-y-6 sm:grid-cols-2 lg:hidden"
vertical={tabOrientation === 'vertical'}
>
<TabList className="-mx-4 flex gap-x-4 gap-y-10 overflow-x-auto pb-4 pl-4 sm:mx-0 sm:flex-col sm:pb-0 sm:pl-0 sm:pr-8">
{({ selectedIndex }) => (
<>
{schedule.map((day, dayIndex) => (
<div
key={day.dateTime}
className={clsx(
'relative w-3/4 flex-none pr-4 sm:w-auto sm:pr-0',
dayIndex !== selectedIndex && 'opacity-70',
)}
>
<DaySummary
day={{
...day,
date: (
<Tab className="ui-not-focus-visible:outline-none">
<span className="absolute inset-0" />
{day.date}
</Tab>
),
}}
/>
</div>
))}
</>
)}
</TabList>
<TabPanels>
{schedule.map((day) => (
<TabPanel
key={day.dateTime}
className="ui-not-focus-visible:outline-none"
>
<TimeSlots day={day} />
</TabPanel>
))}
</TabPanels>
</TabGroup>
)
}
function DaySummary({ day }) {
return (
<>
<h3 className="text-2xl font-semibold tracking-tight text-blue-900 mt-16">
<time dateTime={day.dateTime}>{day.date}</time>
</h3>
<p className="mt-1.5 text-base tracking-tight text-blue-900">
{day.summary}
</p>
</>
)
}
function TimeSlots({ day, className }) {
return (
<ol
role="list"
className={clsx(
className,
'space-y-8 bg-white/60 px-10 py-14 text-center shadow-xl shadow-blue-900/5 backdrop-blur',
)}
>
{day.timeSlots.map((timeSlot, timeSlotIndex) => (
<li
key={timeSlot.start}
aria-label={`${timeSlot.name} talking about ${timeSlot.description} at ${timeSlot.start} - ${timeSlot.end} PST`}
>
{timeSlotIndex > 0 && (
<div className="mx-auto mb-8 h-px w-48 bg-indigo-500/10" />
)}
<h4 className="text-lg font-semibold tracking-tight text-blue-900">
{timeSlot.name}
</h4>
{timeSlot.description && (
<p className="mt-1 tracking-tight text-blue-900">
{timeSlot.description}
</p>
)}
</li>
))}
</ol>
)
}
function ScheduleStatic() {
return (
<div className="hidden lg:grid lg:grid-cols-3 lg:gap-x-8">
{schedule.map((day) => (
<section key={day.dateTime}>
<DaySummary day={day} />
<TimeSlots day={day} className="mt-10" />
</section>
))}
</div>
)
}
export function Schedule() {
return (
<section id="schedule" aria-label="Schedule" className="py-20 sm:py-32">
<Container className="relative z-10">
<div className="mx-auto max-w-2xl lg:mx-0 lg:max-w-4xl lg:pr-24">
<h2 className="font-display text-4xl font-medium tracking-tighter text-blue-600 sm:text-5xl">
Transforming Possibilities Across Industries Digitally
</h2>
<p className="mt-4 font-display text-2xl tracking-tight text-blue-900">
Explore diverse scenarios where our platform empowers users to create, collaborate,
and innovate in immersive virtual environments, unlocking new potentials across industries and communities.
</p>
</div>
</Container>
<div className="relative mt-14 sm:mt-24">
<BackgroundImage position="right" className="-bottom-32 -top-40" />
<Container className="relative">
<ScheduleTabbed />
<ScheduleStatic />
</Container>
</div>
</section>
)
}

View File

@@ -7,311 +7,81 @@ import clsx from 'clsx'
import { BackgroundImage } from '@/components/BackgroundImage'
import { Container } from '@/components/Container'
const schedule = [
const products = [
{
date: 'April 4',
dateTime: '2022-04-04',
summary:
'The first day of the conference is focused on dark patterns for ecommerce.',
timeSlots: [
{
name: 'Steven McHail',
description: 'Not so one-time payments',
start: '9:00AM',
end: '10:00AM',
},
{
name: 'Jaquelin Isch',
description: 'The finer print',
start: '10:00AM',
end: '11:00AM',
},
{
name: 'Dianne Guilianelli',
description: 'Post-purchase blackmail',
start: '11:00AM',
end: '12:00PM',
},
{
name: 'Lunch',
description: null,
start: '12:00PM',
end: '1:00PM',
},
{
name: 'Ronni Cantadore',
description: 'Buy or die',
start: '1:00PM',
end: '2:00PM',
},
{
name: 'Erhart Cockrin',
description: 'In-person cancellation',
start: '2:00PM',
end: '3:00PM',
},
{
name: 'Parker Johnson',
description: 'The pay/cancel switcheroo',
start: '3:00PM',
end: '4:00PM',
},
],
id: 1,
name: 'Enhancing Education',
color: 'Transform traditional education with immersive distance learning opportunities',
href: '#',
imageSrc: '/images/education.jpg',
imageAlt: 'classroom',
},
{
date: 'April 5',
dateTime: '2022-04-05',
summary:
'Next we spend the day talking about deceiving people with technology.',
timeSlots: [
{
name: 'Damaris Kimura',
description: 'The invisible card reader',
start: '9:00AM',
end: '10:00AM',
},
{
name: 'Ibrahim Frasch',
description: 'Stealing fingerprints',
start: '10:00AM',
end: '11:00AM',
},
{
name: 'Cathlene Burrage',
description: 'Voting machines',
start: '11:00AM',
end: '12:00PM',
},
{
name: 'Lunch',
description: null,
start: '12:00PM',
end: '1:00PM',
},
{
name: 'Rinaldo Beynon',
description: 'Blackhat SEO that works',
start: '1:00PM',
end: '2:00PM',
},
{
name: 'Waylon Hyden',
description: 'Turning your audience into a botnet',
start: '2:00PM',
end: '3:00PM',
},
{
name: 'Giordano Sagucio',
description: 'Fly phishing',
start: '3:00PM',
end: '4:00PM',
},
],
id: 2,
name: 'Environmental Awareness',
color: 'Advocate for environmental conservation through virtual eco-tours & initiatives.',
href: '#',
imageSrc: '/images/education.jpg',
imageAlt: 'classroom',
},
{
date: 'April 6',
dateTime: '2022-04-06',
summary:
'We close out the event previewing new techniques that are still in development.',
timeSlots: [
{
name: 'Andrew Greene',
description: 'Neuralink dark patterns',
start: '9:00AM',
end: '10:00AM',
},
{
name: 'Heather Terry',
description: 'DALL-E for passports',
start: '10:00AM',
end: '11:00AM',
},
{
name: 'Piers Wilkins',
description: 'Quantum password cracking',
start: '11:00AM',
end: '12:00PM',
},
{
name: 'Lunch',
description: null,
start: '12:00PM',
end: '1:00PM',
},
{
name: 'Gordon Sanderson',
description: 'SkyNet is coming',
start: '1:00PM',
end: '2:00PM',
},
{
name: 'Kimberly Parsons',
description: 'Dark patterns for the metaverse',
start: '2:00PM',
end: '3:00PM',
},
{
name: 'Richard Astley',
description: 'Knowing the game and playing it',
start: '3:00PM',
end: '4:00PM',
},
],
id: 3,
name: 'Supporting Healthcare',
color: 'Innovate healthcare delivery by integrating virtual consultations & tools.',
href: '#',
imageSrc: '/images/education.jpg',
imageAlt: 'classroom',
},
{
id: 4,
name: 'Empowering Africa',
color: 'Foster cultural and economic growth across Africa through virtual solutions.',
href: '#',
imageSrc: '/images/education.jpg',
imageAlt: 'classroom',
},
]
function ScheduleTabbed() {
let [tabOrientation, setTabOrientation] = useState('horizontal')
useEffect(() => {
let smMediaQuery = window.matchMedia('(min-width: 640px)')
function onMediaQueryChange({ matches }) {
setTabOrientation(matches ? 'vertical' : 'horizontal')
}
onMediaQueryChange(smMediaQuery)
smMediaQuery.addEventListener('change', onMediaQueryChange)
return () => {
smMediaQuery.removeEventListener('change', onMediaQueryChange)
}
}, [])
return (
<TabGroup
className="mx-auto grid max-w-2xl grid-cols-1 gap-y-6 sm:grid-cols-2 lg:hidden"
vertical={tabOrientation === 'vertical'}
>
<TabList className="-mx-4 flex gap-x-4 gap-y-10 overflow-x-auto pb-4 pl-4 sm:mx-0 sm:flex-col sm:pb-0 sm:pl-0 sm:pr-8">
{({ selectedIndex }) => (
<>
{schedule.map((day, dayIndex) => (
<div
key={day.dateTime}
className={clsx(
'relative w-3/4 flex-none pr-4 sm:w-auto sm:pr-0',
dayIndex !== selectedIndex && 'opacity-70',
)}
>
<DaySummary
day={{
...day,
date: (
<Tab className="ui-not-focus-visible:outline-none">
<span className="absolute inset-0" />
{day.date}
</Tab>
),
}}
/>
</div>
))}
</>
)}
</TabList>
<TabPanels>
{schedule.map((day) => (
<TabPanel
key={day.dateTime}
className="ui-not-focus-visible:outline-none"
>
<TimeSlots day={day} />
</TabPanel>
))}
</TabPanels>
</TabGroup>
)
}
function DaySummary({ day }) {
return (
<>
<h3 className="text-2xl font-semibold tracking-tight text-blue-900">
<time dateTime={day.dateTime}>{day.date}</time>
</h3>
<p className="mt-1.5 text-base tracking-tight text-blue-900">
{day.summary}
</p>
</>
)
}
function TimeSlots({ day, className }) {
return (
<ol
role="list"
className={clsx(
className,
'space-y-8 bg-white/60 px-10 py-14 text-center shadow-xl shadow-blue-900/5 backdrop-blur',
)}
>
{day.timeSlots.map((timeSlot, timeSlotIndex) => (
<li
key={timeSlot.start}
aria-label={`${timeSlot.name} talking about ${timeSlot.description} at ${timeSlot.start} - ${timeSlot.end} PST`}
>
{timeSlotIndex > 0 && (
<div className="mx-auto mb-8 h-px w-48 bg-indigo-500/10" />
)}
<h4 className="text-lg font-semibold tracking-tight text-blue-900">
{timeSlot.name}
</h4>
{timeSlot.description && (
<p className="mt-1 tracking-tight text-blue-900">
{timeSlot.description}
</p>
)}
<p className="mt-1 font-mono text-sm text-slate-500">
<time dateTime={`${day.dateTime}T${timeSlot.start}-08:00`}>
{timeSlot.start}
</time>{' '}
-{' '}
<time dateTime={`${day.dateTime}T${timeSlot.end}-08:00`}>
{timeSlot.end}
</time>{' '}
PST
</p>
</li>
))}
</ol>
)
}
function ScheduleStatic() {
return (
<div className="hidden lg:grid lg:grid-cols-3 lg:gap-x-8">
{schedule.map((day) => (
<section key={day.dateTime}>
<DaySummary day={day} />
<TimeSlots day={day} className="mt-10" />
</section>
))}
</div>
)
}
export function Schedule() {
return (
<section id="schedule" aria-label="Schedule" className="py-20 sm:py-32">
<section id="schedule" aria-label="Schedule" className="py-8 lg:py-24 mb-12">
<Container className="relative z-10">
<div className="mx-auto max-w-2xl lg:mx-0 lg:max-w-4xl lg:pr-24">
<h2 className="font-display text-4xl font-medium tracking-tighter text-blue-600 sm:text-5xl">
Our three day schedule is jam-packed with brilliant, creative, evil
geniuses.
<h2 className="text-base font-medium font-mono leading-7 text-blue-600">Usecases</h2>
<h2 className="mt-2 font-display text-4xl font-medium tracking-tighter text-blue-600 sm:text-5xl">
Transforming Possibilities Across Industries Digitally
</h2>
<p className="mt-4 font-display text-2xl tracking-tight text-blue-900">
The worst people in our industry giving the best talks youve ever
seen. Nothing will be recorded and every attendee has to sign an NDA
to watch the talks.
Explore diverse scenarios where our platform empowers users to create, collaborate,
and innovate in immersive virtual environments, unlocking new potentials across industries and communities.
</p>
</div>
</Container>
<div className="relative mt-14 sm:mt-24">
<div className="relative lg:mt-14 mt-16">
<BackgroundImage position="right" className="-bottom-32 -top-40" />
<Container className="relative">
<ScheduleTabbed />
<ScheduleStatic />
<div className="mt-4 grid grid-cols-1 gap-y-12 sm:grid-cols-2 sm:gap-x-6 lg:grid-cols-4 xl:gap-x-8">
{products.map((product) => (
<div key={product.id}>
<div className="relative">
<div className="relative h-full w-full overflow-hidden rounded-sm">
<img
alt={product.imageAlt}
src={product.imageSrc}
className="h-full w-full object-cover object-center"
/>
</div>
<div className="relative mt-4">
<h3 className="lg:text-base text-lg font-medium text-blue-700">{product.name}</h3>
<p className="mt-1 mb-2 lg:text-sm text-base text-blue-900">{product.color}</p>
<a href={product.href} className="lg:text-xs text-sm font-mono text-blue-700 hover:text-blue-900">
Read Usecase <span aria-hidden="true"></span>
</a>
</div>
</div>
</div>
))}
</div>
</Container>
</div>
</section>

View File

@@ -0,0 +1,319 @@
'use client'
import { useEffect, useState } from 'react'
import { Tab, TabGroup, TabList, TabPanel, TabPanels } from '@headlessui/react'
import clsx from 'clsx'
import { BackgroundImage } from '@/components/BackgroundImage'
import { Container } from '@/components/Container'
const schedule = [
{
date: 'April 4',
dateTime: '2022-04-04',
summary:
'The first day of the conference is focused on dark patterns for ecommerce.',
timeSlots: [
{
name: 'Steven McHail',
description: 'Not so one-time payments',
start: '9:00AM',
end: '10:00AM',
},
{
name: 'Jaquelin Isch',
description: 'The finer print',
start: '10:00AM',
end: '11:00AM',
},
{
name: 'Dianne Guilianelli',
description: 'Post-purchase blackmail',
start: '11:00AM',
end: '12:00PM',
},
{
name: 'Lunch',
description: null,
start: '12:00PM',
end: '1:00PM',
},
{
name: 'Ronni Cantadore',
description: 'Buy or die',
start: '1:00PM',
end: '2:00PM',
},
{
name: 'Erhart Cockrin',
description: 'In-person cancellation',
start: '2:00PM',
end: '3:00PM',
},
{
name: 'Parker Johnson',
description: 'The pay/cancel switcheroo',
start: '3:00PM',
end: '4:00PM',
},
],
},
{
date: 'April 5',
dateTime: '2022-04-05',
summary:
'Next we spend the day talking about deceiving people with technology.',
timeSlots: [
{
name: 'Damaris Kimura',
description: 'The invisible card reader',
start: '9:00AM',
end: '10:00AM',
},
{
name: 'Ibrahim Frasch',
description: 'Stealing fingerprints',
start: '10:00AM',
end: '11:00AM',
},
{
name: 'Cathlene Burrage',
description: 'Voting machines',
start: '11:00AM',
end: '12:00PM',
},
{
name: 'Lunch',
description: null,
start: '12:00PM',
end: '1:00PM',
},
{
name: 'Rinaldo Beynon',
description: 'Blackhat SEO that works',
start: '1:00PM',
end: '2:00PM',
},
{
name: 'Waylon Hyden',
description: 'Turning your audience into a botnet',
start: '2:00PM',
end: '3:00PM',
},
{
name: 'Giordano Sagucio',
description: 'Fly phishing',
start: '3:00PM',
end: '4:00PM',
},
],
},
{
date: 'April 6',
dateTime: '2022-04-06',
summary:
'We close out the event previewing new techniques that are still in development.',
timeSlots: [
{
name: 'Andrew Greene',
description: 'Neuralink dark patterns',
start: '9:00AM',
end: '10:00AM',
},
{
name: 'Heather Terry',
description: 'DALL-E for passports',
start: '10:00AM',
end: '11:00AM',
},
{
name: 'Piers Wilkins',
description: 'Quantum password cracking',
start: '11:00AM',
end: '12:00PM',
},
{
name: 'Lunch',
description: null,
start: '12:00PM',
end: '1:00PM',
},
{
name: 'Gordon Sanderson',
description: 'SkyNet is coming',
start: '1:00PM',
end: '2:00PM',
},
{
name: 'Kimberly Parsons',
description: 'Dark patterns for the metaverse',
start: '2:00PM',
end: '3:00PM',
},
{
name: 'Richard Astley',
description: 'Knowing the game and playing it',
start: '3:00PM',
end: '4:00PM',
},
],
},
]
function ScheduleTabbed() {
let [tabOrientation, setTabOrientation] = useState('horizontal')
useEffect(() => {
let smMediaQuery = window.matchMedia('(min-width: 640px)')
function onMediaQueryChange({ matches }) {
setTabOrientation(matches ? 'vertical' : 'horizontal')
}
onMediaQueryChange(smMediaQuery)
smMediaQuery.addEventListener('change', onMediaQueryChange)
return () => {
smMediaQuery.removeEventListener('change', onMediaQueryChange)
}
}, [])
return (
<TabGroup
className="mx-auto grid max-w-2xl grid-cols-1 gap-y-6 sm:grid-cols-2 lg:hidden"
vertical={tabOrientation === 'vertical'}
>
<TabList className="-mx-4 flex gap-x-4 gap-y-10 overflow-x-auto pb-4 pl-4 sm:mx-0 sm:flex-col sm:pb-0 sm:pl-0 sm:pr-8">
{({ selectedIndex }) => (
<>
{schedule.map((day, dayIndex) => (
<div
key={day.dateTime}
className={clsx(
'relative w-3/4 flex-none pr-4 sm:w-auto sm:pr-0',
dayIndex !== selectedIndex && 'opacity-70',
)}
>
<DaySummary
day={{
...day,
date: (
<Tab className="ui-not-focus-visible:outline-none">
<span className="absolute inset-0" />
{day.date}
</Tab>
),
}}
/>
</div>
))}
</>
)}
</TabList>
<TabPanels>
{schedule.map((day) => (
<TabPanel
key={day.dateTime}
className="ui-not-focus-visible:outline-none"
>
<TimeSlots day={day} />
</TabPanel>
))}
</TabPanels>
</TabGroup>
)
}
function DaySummary({ day }) {
return (
<>
<h3 className="text-2xl font-semibold tracking-tight text-blue-900">
<time dateTime={day.dateTime}>{day.date}</time>
</h3>
<p className="mt-1.5 text-base tracking-tight text-blue-900">
{day.summary}
</p>
</>
)
}
function TimeSlots({ day, className }) {
return (
<ol
role="list"
className={clsx(
className,
'space-y-8 bg-white/60 px-10 py-14 text-center shadow-xl shadow-blue-900/5 backdrop-blur',
)}
>
{day.timeSlots.map((timeSlot, timeSlotIndex) => (
<li
key={timeSlot.start}
aria-label={`${timeSlot.name} talking about ${timeSlot.description} at ${timeSlot.start} - ${timeSlot.end} PST`}
>
{timeSlotIndex > 0 && (
<div className="mx-auto mb-8 h-px w-48 bg-indigo-500/10" />
)}
<h4 className="text-lg font-semibold tracking-tight text-blue-900">
{timeSlot.name}
</h4>
{timeSlot.description && (
<p className="mt-1 tracking-tight text-blue-900">
{timeSlot.description}
</p>
)}
<p className="mt-1 font-mono text-sm text-slate-500">
<time dateTime={`${day.dateTime}T${timeSlot.start}-08:00`}>
{timeSlot.start}
</time>{' '}
-{' '}
<time dateTime={`${day.dateTime}T${timeSlot.end}-08:00`}>
{timeSlot.end}
</time>{' '}
PST
</p>
</li>
))}
</ol>
)
}
function ScheduleStatic() {
return (
<div className="hidden lg:grid lg:grid-cols-3 lg:gap-x-8">
{schedule.map((day) => (
<section key={day.dateTime}>
<DaySummary day={day} />
<TimeSlots day={day} className="mt-10" />
</section>
))}
</div>
)
}
export function Schedule() {
return (
<section id="schedule" aria-label="Schedule" className="py-20 sm:py-32">
<Container className="relative z-10">
<div className="mx-auto max-w-2xl lg:mx-0 lg:max-w-4xl lg:pr-24">
<h2 className="font-display text-4xl font-medium tracking-tighter text-blue-600 sm:text-5xl">
Our three day schedule is jam-packed with brilliant, creative, evil
geniuses.
</h2>
<p className="mt-4 font-display text-2xl tracking-tight text-blue-900">
The worst people in our industry giving the best talks youve ever
seen. Nothing will be recorded and every attendee has to sign an NDA
to watch the talks.
</p>
</div>
</Container>
<div className="relative mt-14 sm:mt-24">
<BackgroundImage position="right" className="-bottom-32 -top-40" />
<Container className="relative">
<ScheduleTabbed />
<ScheduleStatic />
</Container>
</div>
</section>
)
}