add components refinements, accessibility quick wins
This commit is contained in:
parent
28803b266a
commit
92cdd44af3
@ -1,5 +1,5 @@
|
|||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="de">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||||
|
|||||||
@ -5,9 +5,12 @@ import ProgrammDetail from "./pages/ProgrammDetail";
|
|||||||
import Speaker from "./pages/Speaker";
|
import Speaker from "./pages/Speaker";
|
||||||
import SpeakerDetail from "./pages/SpeakerDetail";
|
import SpeakerDetail from "./pages/SpeakerDetail";
|
||||||
import Tickets from "./pages/Tickets";
|
import Tickets from "./pages/Tickets";
|
||||||
|
import { ScrollToTop } from "./components/ScrollToTop";
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
|
<ScrollToTop />
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route path="/" element={<Home />} />
|
<Route path="/" element={<Home />} />
|
||||||
<Route path="/programm" element={<Programm />} />
|
<Route path="/programm" element={<Programm />} />
|
||||||
@ -16,6 +19,7 @@ function App() {
|
|||||||
<Route path="/speaker/:slug" element={<SpeakerDetail />} />
|
<Route path="/speaker/:slug" element={<SpeakerDetail />} />
|
||||||
<Route path="/tickets" element={<Tickets />} />
|
<Route path="/tickets" element={<Tickets />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -39,8 +39,9 @@ export const Cta30 = (props: Cta30Props) => {
|
|||||||
className="rb-4 mb-4 grid max-w-sm grid-cols-1 gap-y-3 sm:grid-cols-[1fr_max-content] sm:gap-4"
|
className="rb-4 mb-4 grid max-w-sm grid-cols-1 gap-y-3 sm:grid-cols-[1fr_max-content] sm:gap-4"
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
>
|
>
|
||||||
|
<label htmlFor="cta-email" className="sr-only">E-Mail-Adresse</label>
|
||||||
<Input
|
<Input
|
||||||
id="email"
|
id="cta-email"
|
||||||
type="email"
|
type="email"
|
||||||
placeholder={inputPlaceholder}
|
placeholder={inputPlaceholder}
|
||||||
value={emailInput}
|
value={emailInput}
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import speaker3 from "../assets/speaker3.png";
|
|||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import type { ButtonProps } from "@relume_io/relume-ui";
|
import type { ButtonProps } from "@relume_io/relume-ui";
|
||||||
import { Button } from "@relume_io/relume-ui";
|
import { Button } from "@relume_io/relume-ui";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
//import { RxChevronRight } from "react-icons/rx";
|
//import { RxChevronRight } from "react-icons/rx";
|
||||||
//import { BiMap, BiCalendarAlt } from "react-icons/bi";
|
//import { BiMap, BiCalendarAlt } from "react-icons/bi";
|
||||||
|
|
||||||
@ -34,7 +35,7 @@ type Props = {
|
|||||||
tagline: string;
|
tagline: string;
|
||||||
heading: string;
|
heading: string;
|
||||||
description: string;
|
description: string;
|
||||||
button: ButtonProps;
|
button: ButtonProps & { url?: string };
|
||||||
featuredEvents: FeaturedEvent[];
|
featuredEvents: FeaturedEvent[];
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -49,8 +50,8 @@ export const Event17 = (props: Event17Props) => {
|
|||||||
<section id="relume" className="px-[5%] py-16 md:py-24 lg:py-28 bg-tech-navy font-barlow">
|
<section id="relume" className="px-[5%] py-16 md:py-24 lg:py-28 bg-tech-navy font-barlow">
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<div className="mx-auto mb-12 max-w-lg text-center md:mb-18 lg:mb-20">
|
<div className="mx-auto mb-12 max-w-lg text-center md:mb-18 lg:mb-20">
|
||||||
<h4 className="font-semibold">{tagline}</h4>
|
{tagline && <p className="font-semibold">{tagline}</p>}
|
||||||
<h1 className="mt-3 text-5xl font-bold md:mt-4 md:text-7xl lg:text-8xl text-acid-lime">{heading}</h1>
|
<h2 className="mt-3 text-5xl font-bold md:mt-4 md:text-7xl lg:text-8xl text-acid-lime">{heading}</h2>
|
||||||
<p className="mt-5 text-base md:mt-6 md:text-md text-cloud-white whitespace-pre-wrap">{description}</p>
|
<p className="mt-5 text-base md:mt-6 md:text-md text-cloud-white whitespace-pre-wrap">{description}</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid auto-cols-fr grid-cols-1 gap-x-8 gap-y-12 md:grid-cols-2 md:gap-y-16 lg:grid-cols-3">
|
<div className="grid auto-cols-fr grid-cols-1 gap-x-8 gap-y-12 md:grid-cols-2 md:gap-y-16 lg:grid-cols-3">
|
||||||
@ -59,7 +60,13 @@ export const Event17 = (props: Event17Props) => {
|
|||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-12 flex justify-center md:mt-18 lg:mt-20">
|
<div className="mt-12 flex justify-center md:mt-18 lg:mt-20">
|
||||||
|
{button.url ? (
|
||||||
|
<Link to={button.url}>
|
||||||
<Button {...button} className="bg-acid-lime text-tech-navy font-semibold px-6 py-3 rounded-2xl border-acid-lime">{button.title}</Button>
|
<Button {...button} className="bg-acid-lime text-tech-navy font-semibold px-6 py-3 rounded-2xl border-acid-lime">{button.title}</Button>
|
||||||
|
</Link>
|
||||||
|
) : (
|
||||||
|
<Button {...button} className="bg-acid-lime text-tech-navy font-semibold px-6 py-3 rounded-2xl border-acid-lime">{button.title}</Button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
@ -83,7 +90,7 @@ export const Event17Defaults: Props = {
|
|||||||
tagline: "",
|
tagline: "",
|
||||||
heading: "Speaker:innen",
|
heading: "Speaker:innen",
|
||||||
description: "Überwältigt von unserem Programm?\nLerne unsere diesjährigen Speakerinnen und Speaker kennen.",
|
description: "Überwältigt von unserem Programm?\nLerne unsere diesjährigen Speakerinnen und Speaker kennen.",
|
||||||
button: { variant: "primary", size: "primary", title: "Zu den Speakern" },
|
button: { variant: "primary", size: "primary", title: "Zu den Speakern", url: "/speaker" },
|
||||||
featuredEvents: [
|
featuredEvents: [
|
||||||
{
|
{
|
||||||
url: "/speaker", image: { src: speaker1, alt: "Dr. Elena Rossi" },
|
url: "/speaker", image: { src: speaker1, alt: "Dr. Elena Rossi" },
|
||||||
|
|||||||
@ -51,7 +51,7 @@ export const Event20 = (props: Event20Props) => {
|
|||||||
<div className="mb-12 grid auto-cols-fr grid-cols-1 items-end gap-12 md:mb-18 md:grid-cols-[1fr_max-content] lg:mb-20 lg:gap-20">
|
<div className="mb-12 grid auto-cols-fr grid-cols-1 items-end gap-12 md:mb-18 md:grid-cols-[1fr_max-content] lg:mb-20 lg:gap-20">
|
||||||
<div className="max-w-lg">
|
<div className="max-w-lg">
|
||||||
<p className="mb-3 font-semibold md:mb-4">{tagline}</p>
|
<p className="mb-3 font-semibold md:mb-4">{tagline}</p>
|
||||||
<h1 className="mb-3 text-5xl font-bold md:mb-4 md:text-7xl lg:text-8xl text-cloud-white">{heading}</h1>
|
<h2 className="mb-3 text-5xl font-bold md:mb-4 md:text-7xl lg:text-8xl text-cloud-white">{heading}</h2>
|
||||||
<p className="md:text-md text-cloud-white">{description}</p>
|
<p className="md:text-md text-cloud-white">{description}</p>
|
||||||
</div>
|
</div>
|
||||||
<Button {...button} className="hidden md:flex bg-acid-lime text-tech-navy font-semibold px-6 py-3 rounded-2xl border-acid-lime">
|
<Button {...button} className="hidden md:flex bg-acid-lime text-tech-navy font-semibold px-6 py-3 rounded-2xl border-acid-lime">
|
||||||
|
|||||||
@ -21,6 +21,7 @@ type Links = {
|
|||||||
type SocialMediaLinks = {
|
type SocialMediaLinks = {
|
||||||
url: string;
|
url: string;
|
||||||
icon: React.ReactNode;
|
icon: React.ReactNode;
|
||||||
|
label: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type ColumnLinks = {
|
type ColumnLinks = {
|
||||||
@ -80,7 +81,7 @@ export const Footer3 = (props: Footer3Props) => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="grid grid-flow-col grid-cols-[max-content] items-start justify-start gap-x-3">
|
<div className="grid grid-flow-col grid-cols-[max-content] items-start justify-start gap-x-3">
|
||||||
{socialMediaLinks.map((link, index) => (
|
{socialMediaLinks.map((link, index) => (
|
||||||
<a key={index} href={link.url}>
|
<a key={index} href={link.url} aria-label={link.label}>
|
||||||
{link.icon}
|
{link.icon}
|
||||||
</a>
|
</a>
|
||||||
))}
|
))}
|
||||||
@ -134,24 +135,24 @@ export const Footer3Defaults: Props = {
|
|||||||
links: [
|
links: [
|
||||||
{ title: "Programm", url: "/programm" },
|
{ title: "Programm", url: "/programm" },
|
||||||
{ title: "Speaker", url: "/speaker" },
|
{ title: "Speaker", url: "/speaker" },
|
||||||
{ title: "Location", url: "#" },
|
{ title: "Location", url: "/location" },
|
||||||
{ title: "Tickets", url: "#tickets" },
|
{ title: "Tickets", url: "/tickets" },
|
||||||
{ title: "FAQ", url: "#faq" },
|
{ title: "FAQ", url: "/programm#faq" },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{ links: [] },
|
{ links: [] },
|
||||||
],
|
],
|
||||||
socialMediaLinks: [
|
socialMediaLinks: [
|
||||||
{ url: "#", icon: <BiLogoFacebookCircle className="size-6 text-neutral-dark" /> },
|
{ url: "#", label: "UXplore auf Facebook", icon: <BiLogoFacebookCircle className="size-6 text-neutral-dark" /> },
|
||||||
{ url: "#", icon: <BiLogoInstagram className="size-6 text-neutral-dark" /> },
|
{ url: "#", label: "UXplore auf Instagram", icon: <BiLogoInstagram className="size-6 text-neutral-dark" /> },
|
||||||
{ url: "#", icon: <FaXTwitter className="size-6 p-0.5 text-neutral-dark" /> },
|
{ url: "#", label: "UXplore auf X (Twitter)", icon: <FaXTwitter className="size-6 p-0.5 text-neutral-dark" /> },
|
||||||
{ url: "#", icon: <BiLogoLinkedinSquare className="size-6 text-neutral-dark" /> },
|
{ url: "#", label: "UXplore auf LinkedIn", icon: <BiLogoLinkedinSquare className="size-6 text-neutral-dark" /> },
|
||||||
{ url: "#", icon: <BiLogoYoutube className="size-6 text-neutral-dark" /> },
|
{ url: "#", label: "UXplore auf YouTube", icon: <BiLogoYoutube className="size-6 text-neutral-dark" /> },
|
||||||
],
|
],
|
||||||
footerText: "© 2026 UXplore",
|
footerText: "© 2026 UXplore",
|
||||||
footerLinks: [
|
footerLinks: [
|
||||||
{ title: "AGB", url: "#" },
|
{ title: "AGB", url: "/agb" },
|
||||||
{ title: "Datenschutz", url: "#" },
|
{ title: "Datenschutz", url: "/datenschutz" },
|
||||||
{ title: "Cookie Einstellungen", url: "#" },
|
{ title: "Cookie Einstellungen", url: "/cookie-einstellungen" },
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
@ -37,12 +37,15 @@ export const Navbar3 = (props: Navbar3Props) => {
|
|||||||
const isMobile = useMediaQuery("(max-width: 991px)");
|
const isMobile = useMediaQuery("(max-width: 991px)");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section
|
<nav
|
||||||
id="relume"
|
id="relume"
|
||||||
className="z-[999] grid w-full grid-cols-[1fr_max-content_1fr] items-center justify-between border-b border-neutral-dark bg-tech-navy px-[5%] md:min-h-18 font-barlow"
|
aria-label="Hauptnavigation"
|
||||||
|
className="sticky top-0 z-[999] grid w-full grid-cols-[1fr_max-content_1fr] items-center justify-between border-b border-neutral-dark bg-tech-navy px-[5%] md:min-h-18 font-barlow"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
className="flex size-12 flex-col justify-center lg:hidden"
|
className="flex size-12 flex-col justify-center lg:hidden"
|
||||||
|
aria-label={isMobileMenuOpen ? "Menü schließen" : "Menü öffnen"}
|
||||||
|
aria-expanded={isMobileMenuOpen}
|
||||||
onClick={() => setIsMobileMenuOpen((prev) => !prev)}
|
onClick={() => setIsMobileMenuOpen((prev) => !prev)}
|
||||||
>
|
>
|
||||||
{Array(3)
|
{Array(3)
|
||||||
@ -134,7 +137,7 @@ export const Navbar3 = (props: Navbar3Props) => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</nav>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -209,7 +212,7 @@ export const Navbar3Defaults: Props = {
|
|||||||
navLinks: [
|
navLinks: [
|
||||||
{ title: "Programm", url: "/programm" },
|
{ title: "Programm", url: "/programm" },
|
||||||
{ title: "Speaker", url: "/speaker" },
|
{ title: "Speaker", url: "/speaker" },
|
||||||
{ title: "Location", url: "#" },
|
{ title: "Location", url: "/location" },
|
||||||
],
|
],
|
||||||
buttons: [
|
buttons: [
|
||||||
{
|
{
|
||||||
|
|||||||
10
relume-test/src/components/ScrollToTop.tsx
Normal file
10
relume-test/src/components/ScrollToTop.tsx
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import { useEffect } from "react";
|
||||||
|
import { useLocation } from "react-router-dom";
|
||||||
|
|
||||||
|
export const ScrollToTop = () => {
|
||||||
|
const { pathname } = useLocation();
|
||||||
|
useEffect(() => {
|
||||||
|
window.scrollTo(0, 0);
|
||||||
|
}, [pathname]);
|
||||||
|
return null;
|
||||||
|
};
|
||||||
@ -16,6 +16,7 @@ type ImageProps = {
|
|||||||
type SocialLink = {
|
type SocialLink = {
|
||||||
href: string;
|
href: string;
|
||||||
icon: React.ReactNode;
|
icon: React.ReactNode;
|
||||||
|
label: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type Talk = {
|
type Talk = {
|
||||||
@ -67,7 +68,7 @@ const MemberCard = ({ member }: { member: TeamMember }) => (
|
|||||||
{member.socialLinks.length > 0 && (
|
{member.socialLinks.length > 0 && (
|
||||||
<div className="flex gap-2 shrink-0">
|
<div className="flex gap-2 shrink-0">
|
||||||
{member.socialLinks.map((link, i) => (
|
{member.socialLinks.map((link, i) => (
|
||||||
<a key={i} href={link.href}>{link.icon}</a>
|
<a key={i} href={link.href} aria-label={link.label}>{link.icon}</a>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@ -95,8 +96,8 @@ export const Team4 = (props: Team4Props) => {
|
|||||||
<p className="py-16 text-center text-gray-400">Keine Speaker gefunden.</p>
|
<p className="py-16 text-center text-gray-400">Keine Speaker gefunden.</p>
|
||||||
) : (
|
) : (
|
||||||
<div className="grid grid-cols-1 gap-x-8 gap-y-12 sm:grid-cols-2 lg:grid-cols-4">
|
<div className="grid grid-cols-1 gap-x-8 gap-y-12 sm:grid-cols-2 lg:grid-cols-4">
|
||||||
{teamMembers.map((member, i) => (
|
{teamMembers.map((member) => (
|
||||||
<MemberCard key={i} member={member} />
|
<MemberCard key={member.slug} member={member} />
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@ -124,7 +125,7 @@ export const Team4Defaults: Props = {
|
|||||||
{ title: "Talk: Scaling Research", type: "Talk" },
|
{ title: "Talk: Scaling Research", type: "Talk" },
|
||||||
{ title: "Workshop: Skalierbare Research-Infrastruktur", type: "Workshop" },
|
{ title: "Workshop: Skalierbare Research-Infrastruktur", type: "Workshop" },
|
||||||
],
|
],
|
||||||
socialLinks: [{ href: "#", icon: <BiLogoLinkedinSquare className="size-6" /> }],
|
socialLinks: [{ href: "#", label: "LinkedIn-Profil", icon: <BiLogoLinkedinSquare className="size-6" /> }],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
image: { src: speaker2, alt: "Marcus J. Low" },
|
image: { src: speaker2, alt: "Marcus J. Low" },
|
||||||
@ -139,7 +140,7 @@ export const Team4Defaults: Props = {
|
|||||||
"Marcus J. Low ist Principal Designer bei Airbnb und war massgeblich an der Entwicklung des ersten Airbnb Design Systems beteiligt. Er spricht über die Balance zwischen Markenästhetik und funktionaler Logik und teilt seine Erfahrungen aus über 10 Jahren in der Produktgestaltung für globale Plattformen.",
|
"Marcus J. Low ist Principal Designer bei Airbnb und war massgeblich an der Entwicklung des ersten Airbnb Design Systems beteiligt. Er spricht über die Balance zwischen Markenästhetik und funktionaler Logik und teilt seine Erfahrungen aus über 10 Jahren in der Produktgestaltung für globale Plattformen.",
|
||||||
category: "Design / UX",
|
category: "Design / UX",
|
||||||
talks: [{ title: "Workshop: The Future of Tokens", type: "Workshop" }],
|
talks: [{ title: "Workshop: The Future of Tokens", type: "Workshop" }],
|
||||||
socialLinks: [{ href: "#", icon: <BiLogoLinkedinSquare className="size-6" /> }],
|
socialLinks: [{ href: "#", label: "LinkedIn-Profil", icon: <BiLogoLinkedinSquare className="size-6" /> }],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
image: { src: speaker3, alt: "Reto Gwerder" },
|
image: { src: speaker3, alt: "Reto Gwerder" },
|
||||||
@ -154,7 +155,7 @@ export const Team4Defaults: Props = {
|
|||||||
"Reto Gwerder ist Head of Product bei Ginetta und steht für konsequente Schweizer Design-Qualität. Er analysiert, warum Simplizität oft die größte technische Herausforderung ist und wie man in einem schnellen Produktumfeld trotzdem Qualität bewahrt.",
|
"Reto Gwerder ist Head of Product bei Ginetta und steht für konsequente Schweizer Design-Qualität. Er analysiert, warum Simplizität oft die größte technische Herausforderung ist und wie man in einem schnellen Produktumfeld trotzdem Qualität bewahrt.",
|
||||||
category: "Strategie",
|
category: "Strategie",
|
||||||
talks: [{ title: "Talk: Simplify or Die", type: "Talk" }],
|
talks: [{ title: "Talk: Simplify or Die", type: "Talk" }],
|
||||||
socialLinks: [{ href: "#", icon: <BiLogoLinkedinSquare className="size-6" /> }],
|
socialLinks: [{ href: "#", label: "LinkedIn-Profil", icon: <BiLogoLinkedinSquare className="size-6" /> }],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
image: { src: speaker4, alt: "Dr. Elena Rossi" },
|
image: { src: speaker4, alt: "Dr. Elena Rossi" },
|
||||||
@ -169,7 +170,7 @@ export const Team4Defaults: Props = {
|
|||||||
"Dr. Elena Rossi ist Kognitionspsychologin an der Universität Mailand und verbindet Wissenschaft mit Design. Sie erklärt, wie unser Gehirn auf Micro-Interactions reagiert und wann wir uns manipuliert fühlen. Elena forscht seit über einem Jahrzehnt zur Schnittstelle von Psychologie und digitaler Produktgestaltung.",
|
"Dr. Elena Rossi ist Kognitionspsychologin an der Universität Mailand und verbindet Wissenschaft mit Design. Sie erklärt, wie unser Gehirn auf Micro-Interactions reagiert und wann wir uns manipuliert fühlen. Elena forscht seit über einem Jahrzehnt zur Schnittstelle von Psychologie und digitaler Produktgestaltung.",
|
||||||
category: "Psychologie",
|
category: "Psychologie",
|
||||||
talks: [{ title: "Deep Dive: Psychological UX", type: "Talk" }],
|
talks: [{ title: "Deep Dive: Psychological UX", type: "Talk" }],
|
||||||
socialLinks: [{ href: "#", icon: <BiLogoLinkedinSquare className="size-6" /> }],
|
socialLinks: [{ href: "#", label: "LinkedIn-Profil", icon: <BiLogoLinkedinSquare className="size-6" /> }],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
image: { src: speaker5, alt: "Liam O'Connor" },
|
image: { src: speaker5, alt: "Liam O'Connor" },
|
||||||
@ -184,7 +185,7 @@ export const Team4Defaults: Props = {
|
|||||||
"Liam O'Connor ist Lead Product Designer bei Spotify und gibt Einblicke, wie das Unternehmen Personalisierung nutzt, ohne die Privatsphäre der Nutzer zu verletzen. Er arbeitet an der Schnittstelle von Daten, Design und Ethik.",
|
"Liam O'Connor ist Lead Product Designer bei Spotify und gibt Einblicke, wie das Unternehmen Personalisierung nutzt, ohne die Privatsphäre der Nutzer zu verletzen. Er arbeitet an der Schnittstelle von Daten, Design und Ethik.",
|
||||||
category: "AI & Future",
|
category: "AI & Future",
|
||||||
talks: [{ title: "Talk: Trust in AI UX", type: "Talk" }],
|
talks: [{ title: "Talk: Trust in AI UX", type: "Talk" }],
|
||||||
socialLinks: [{ href: "#", icon: <BiLogoLinkedinSquare className="size-6" /> }],
|
socialLinks: [{ href: "#", label: "LinkedIn-Profil", icon: <BiLogoLinkedinSquare className="size-6" /> }],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
image: { src: speaker6, alt: "Fabienne Keller" },
|
image: { src: speaker6, alt: "Fabienne Keller" },
|
||||||
@ -199,7 +200,7 @@ export const Team4Defaults: Props = {
|
|||||||
"Fabienne Keller ist Gründerin der User-First Agency und Expertin für User Research in komplexen B2B-Umfeldern. Sie zeigt, wie man Stakeholder von Test-Ergebnissen überzeugt und eine nachhaltige Research-Kultur in Unternehmen aufbaut.",
|
"Fabienne Keller ist Gründerin der User-First Agency und Expertin für User Research in komplexen B2B-Umfeldern. Sie zeigt, wie man Stakeholder von Test-Ergebnissen überzeugt und eine nachhaltige Research-Kultur in Unternehmen aufbaut.",
|
||||||
category: "Research",
|
category: "Research",
|
||||||
talks: [{ title: "Workshop: Research Repositories", type: "Workshop" }],
|
talks: [{ title: "Workshop: Research Repositories", type: "Workshop" }],
|
||||||
socialLinks: [{ href: "#", icon: <BiLogoLinkedinSquare className="size-6" /> }],
|
socialLinks: [{ href: "#", label: "LinkedIn-Profil", icon: <BiLogoLinkedinSquare className="size-6" /> }],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|||||||
@ -10,11 +10,13 @@ export const Home = () => {
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Navbar3 />
|
<Navbar3 />
|
||||||
|
<main>
|
||||||
<Header1 />
|
<Header1 />
|
||||||
<Content11 />
|
<Content11 />
|
||||||
<Event17 />
|
<Event17 />
|
||||||
<Event20 />
|
<Event20 />
|
||||||
<Cta30 />
|
<Cta30 />
|
||||||
|
</main>
|
||||||
<Footer3 />
|
<Footer3 />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -66,6 +66,7 @@ const Programm = () => {
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Navbar3 />
|
<Navbar3 />
|
||||||
|
<main>
|
||||||
<Header23 />
|
<Header23 />
|
||||||
<Filters5
|
<Filters5
|
||||||
activeTabs={activeTabs}
|
activeTabs={activeTabs}
|
||||||
@ -79,6 +80,7 @@ const Programm = () => {
|
|||||||
/>
|
/>
|
||||||
<Event33 events={filteredEvents} />
|
<Event33 events={filteredEvents} />
|
||||||
<Banner15 />
|
<Banner15 />
|
||||||
|
</main>
|
||||||
<Footer3 />
|
<Footer3 />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -50,7 +50,7 @@ const ProgrammDetail = () => {
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Navbar3 />
|
<Navbar3 />
|
||||||
|
<main>
|
||||||
{/* Hero section */}
|
{/* Hero section */}
|
||||||
<section className="bg-tech-navy px-[5%] py-16 md:py-24 font-barlow">
|
<section className="bg-tech-navy px-[5%] py-16 md:py-24 font-barlow">
|
||||||
<div className="container">
|
<div className="container">
|
||||||
@ -71,7 +71,7 @@ const ProgrammDetail = () => {
|
|||||||
<BiCalendarAlt className="size-5 shrink-0 text-acid-lime" />
|
<BiCalendarAlt className="size-5 shrink-0 text-acid-lime" />
|
||||||
<span className="text-sm">{dateLabel}, {event.time}</span>
|
<span className="text-sm">{dateLabel}, {event.time}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-3 text-cloud-white/80">
|
<div className="flex items-center gap-3 text-cloud-white/80">
|
||||||
<BiUser className="size-5 shrink-0 text-acid-lime" />
|
<BiUser className="size-5 shrink-0 text-acid-lime" />
|
||||||
<span className="text-sm">{event.speaker}</span>
|
<span className="text-sm">{event.speaker}</span>
|
||||||
</div>
|
</div>
|
||||||
@ -112,13 +112,13 @@ const ProgrammDetail = () => {
|
|||||||
<p className="mb-1 text-sm text-cloud-white/60">{speaker.role}</p>
|
<p className="mb-1 text-sm text-cloud-white/60">{speaker.role}</p>
|
||||||
<p className="mb-4 text-sm text-cloud-white/60">{speaker.company}</p>
|
<p className="mb-4 text-sm text-cloud-white/60">{speaker.company}</p>
|
||||||
<div className="flex gap-3 mb-6">
|
<div className="flex gap-3 mb-6">
|
||||||
<a href="#" className="text-cloud-white/60 hover:text-acid-lime transition-colors">
|
<a href="#" aria-label={`${speaker.name} auf LinkedIn`} className="text-cloud-white/60 hover:text-acid-lime transition-colors">
|
||||||
<BiLogoLinkedinSquare className="size-6" />
|
<BiLogoLinkedinSquare className="size-6" />
|
||||||
</a>
|
</a>
|
||||||
<a href="#" className="text-cloud-white/60 hover:text-acid-lime transition-colors">
|
<a href="#" aria-label={`${speaker.name} auf Xing`} className="text-cloud-white/60 hover:text-acid-lime transition-colors">
|
||||||
<SiXing className="size-5" />
|
<SiXing className="size-5" />
|
||||||
</a>
|
</a>
|
||||||
<a href="#" className="text-cloud-white/60 hover:text-acid-lime transition-colors">
|
<a href="#" aria-label={`${speaker.name} auf Dribbble`} className="text-cloud-white/60 hover:text-acid-lime transition-colors">
|
||||||
<BiLogoDribbble className="size-6" />
|
<BiLogoDribbble className="size-6" />
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
@ -134,7 +134,7 @@ const ProgrammDetail = () => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Right: das erwartete dich */}
|
{/* Right: das erwartet dich */}
|
||||||
<div>
|
<div>
|
||||||
<RxCube className="mb-4 size-8 text-electric-violet" />
|
<RxCube className="mb-4 size-8 text-electric-violet" />
|
||||||
<h2 className="mb-6 text-2xl font-bold text-cloud-white md:text-3xl">
|
<h2 className="mb-6 text-2xl font-bold text-cloud-white md:text-3xl">
|
||||||
@ -148,12 +148,9 @@ const ProgrammDetail = () => {
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* Stay tuned */}
|
|
||||||
<Cta30 />
|
<Cta30 />
|
||||||
|
|
||||||
{/* Sponsors */}
|
|
||||||
<SponsorsSection />
|
<SponsorsSection />
|
||||||
|
</main>
|
||||||
<Footer3 />
|
<Footer3 />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -47,6 +47,7 @@ const Speaker = () => {
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Navbar3 />
|
<Navbar3 />
|
||||||
|
<main>
|
||||||
<Header23
|
<Header23
|
||||||
heading="Unsere Speaker"
|
heading="Unsere Speaker"
|
||||||
description="Erfahre von den klügsten Köpfen der Branche, wie sie komplexe Design-Herausforderungen meistern. Von Schweizer Präzision im Interface bis hin zu globalen Strategien führender Tech-Giganten – unsere Speaker bringen handfeste Insights statt nur Buzzwords."
|
description="Erfahre von den klügsten Köpfen der Branche, wie sie komplexe Design-Herausforderungen meistern. Von Schweizer Präzision im Interface bis hin zu globalen Strategien führender Tech-Giganten – unsere Speaker bringen handfeste Insights statt nur Buzzwords."
|
||||||
@ -69,6 +70,7 @@ const Speaker = () => {
|
|||||||
showSortButton={false}
|
showSortButton={false}
|
||||||
/>
|
/>
|
||||||
<Team4 teamMembers={filteredSpeakers} />
|
<Team4 teamMembers={filteredSpeakers} />
|
||||||
|
</main>
|
||||||
<Footer3 />
|
<Footer3 />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -46,20 +46,12 @@ const SpeakerDetail = () => {
|
|||||||
<div>
|
<div>
|
||||||
<Navbar3 />
|
<Navbar3 />
|
||||||
|
|
||||||
{/* Hero image */}
|
<main>
|
||||||
<div className="w-full aspect-[16/7] overflow-hidden">
|
|
||||||
<img
|
|
||||||
src={(speaker.detailImage ?? speaker.image).src}
|
|
||||||
alt={(speaker.detailImage ?? speaker.image).alt}
|
|
||||||
className="size-full object-cover object-top"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Speaker info */}
|
{/* Speaker info */}
|
||||||
<section className="bg-tech-navy px-[5%] py-16 md:py-24 font-barlow">
|
<section className="bg-tech-navy px-[5%] py-16 md:py-24 font-barlow">
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<div className="grid grid-cols-1 gap-12 lg:grid-cols-2 lg:gap-20">
|
<div className="grid grid-cols-1 items-center gap-12 lg:grid-cols-2 lg:gap-20">
|
||||||
{/* Left: badge, name, location */}
|
{/* Left: badge, name, bio, social */}
|
||||||
<div>
|
<div>
|
||||||
<span className="mb-6 inline-block rounded-full bg-acid-lime px-4 py-1.5 text-sm font-bold text-tech-navy">
|
<span className="mb-6 inline-block rounded-full bg-acid-lime px-4 py-1.5 text-sm font-bold text-tech-navy">
|
||||||
{speaker.category}
|
{speaker.category}
|
||||||
@ -70,21 +62,18 @@ const SpeakerDetail = () => {
|
|||||||
<p className="text-base font-semibold text-cloud-white/80">{speaker.role}</p>
|
<p className="text-base font-semibold text-cloud-white/80">{speaker.role}</p>
|
||||||
<p className="mb-2 text-base text-cloud-white/60">{speaker.company}</p>
|
<p className="mb-2 text-base text-cloud-white/60">{speaker.company}</p>
|
||||||
{speaker.location && (
|
{speaker.location && (
|
||||||
<p className="text-base text-cloud-white/60">{speaker.location}</p>
|
<p className="mb-6 text-base text-cloud-white/60">{speaker.location}</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Right: bio + social */}
|
|
||||||
<div className="flex flex-col justify-center gap-6">
|
|
||||||
<p className="text-base leading-relaxed text-cloud-white/80 md:text-lg">
|
<p className="text-base leading-relaxed text-cloud-white/80 md:text-lg">
|
||||||
{speaker.fullBio ?? speaker.description}
|
{speaker.fullBio ?? speaker.description}
|
||||||
</p>
|
</p>
|
||||||
{speaker.socialLinks.length > 0 && (
|
{speaker.socialLinks.length > 0 && (
|
||||||
<div className="flex gap-4">
|
<div className="mt-6 flex gap-4">
|
||||||
{speaker.socialLinks.map((link, i) => (
|
{speaker.socialLinks.map((link, i) => (
|
||||||
<a
|
<a
|
||||||
key={i}
|
key={i}
|
||||||
href={link.href}
|
href={link.href}
|
||||||
|
aria-label={link.label}
|
||||||
className="text-cloud-white/60 hover:text-acid-lime transition-colors"
|
className="text-cloud-white/60 hover:text-acid-lime transition-colors"
|
||||||
>
|
>
|
||||||
{link.icon}
|
{link.icon}
|
||||||
@ -93,6 +82,15 @@ const SpeakerDetail = () => {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Right: speaker image */}
|
||||||
|
<div className="aspect-square w-full max-w-md overflow-hidden lg:ml-auto">
|
||||||
|
<img
|
||||||
|
src={(speaker.detailImage ?? speaker.image).src}
|
||||||
|
alt={(speaker.detailImage ?? speaker.image).alt}
|
||||||
|
className="size-full object-cover object-top"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
@ -143,6 +141,7 @@ const SpeakerDetail = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<SponsorsSection />
|
<SponsorsSection />
|
||||||
|
</main>
|
||||||
<Footer3 />
|
<Footer3 />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -77,6 +77,7 @@ const Tickets = () => {
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Navbar3 />
|
<Navbar3 />
|
||||||
|
<main>
|
||||||
<Header23
|
<Header23
|
||||||
heading="Ticketshop"
|
heading="Ticketshop"
|
||||||
description="Erfahre von den klügsten Köpfen der Branche, wie sie komplexe Design-Herausforderungen meistern. Von Schweizer Präzision im Interface bis hin zu globalen Strategien führender Tech-Giganten – unsere Speaker bringen handfeste Insights statt nur Buzzwords."
|
description="Erfahre von den klügsten Köpfen der Branche, wie sie komplexe Design-Herausforderungen meistern. Von Schweizer Präzision im Interface bis hin zu globalen Strategien führender Tech-Giganten – unsere Speaker bringen handfeste Insights statt nur Buzzwords."
|
||||||
@ -99,8 +100,9 @@ const Tickets = () => {
|
|||||||
className="mb-4 grid max-w-sm grid-cols-1 gap-y-3 sm:grid-cols-[1fr_max-content] sm:gap-4"
|
className="mb-4 grid max-w-sm grid-cols-1 gap-y-3 sm:grid-cols-[1fr_max-content] sm:gap-4"
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
>
|
>
|
||||||
|
<label htmlFor="tickets-email" className="sr-only">E-Mail-Adresse</label>
|
||||||
<Input
|
<Input
|
||||||
id="email"
|
id="tickets-email"
|
||||||
type="email"
|
type="email"
|
||||||
placeholder="Enter your email"
|
placeholder="Enter your email"
|
||||||
value={emailInput}
|
value={emailInput}
|
||||||
@ -116,11 +118,11 @@ const Tickets = () => {
|
|||||||
</form>
|
</form>
|
||||||
<p className="text-xs text-cloud-white">
|
<p className="text-xs text-cloud-white">
|
||||||
By clicking Get Updates you're confirming that you agree with our{" "}
|
By clicking Get Updates you're confirming that you agree with our{" "}
|
||||||
<a href="#" className="underline">Terms and Conditions</a>.
|
<a href="/agb" className="underline">Terms and Conditions</a>.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</Header23>
|
</Header23>
|
||||||
<Pricing39Ticket
|
<Pricing39Ticket
|
||||||
heading="1-Tagespässe"
|
heading="1-Tagespässe"
|
||||||
plans={[
|
plans={[
|
||||||
{ day: "Donnerstag", date: "25. Juni 2026", earlyBirdPrice: 99, regularPrice: 131, earlyBirdDeadline: "31. Mai 2026" },
|
{ day: "Donnerstag", date: "25. Juni 2026", earlyBirdPrice: 99, regularPrice: 131, earlyBirdDeadline: "31. Mai 2026" },
|
||||||
@ -131,6 +133,7 @@ const Tickets = () => {
|
|||||||
heading="2-Tagespass"
|
heading="2-Tagespass"
|
||||||
plans={[{ day: "Donnerstag – Freitag", date: "25. – 26. Juni 2026", earlyBirdPrice: 179, regularPrice: 236, earlyBirdDeadline: "31. Mai 2026" }]}
|
plans={[{ day: "Donnerstag – Freitag", date: "25. – 26. Juni 2026", earlyBirdPrice: 179, regularPrice: 236, earlyBirdDeadline: "31. Mai 2026" }]}
|
||||||
/>
|
/>
|
||||||
|
</main>
|
||||||
<Footer3 />
|
<Footer3 />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user