Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added public/media/bingo/ep2002-announcement.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/media/bingo/ep2002-website.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
165 changes: 165 additions & 0 deletions src/components/sections/TriviaCarousel.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
---
interface TriviaItem {
text: string;
year?: string;
}

interface Props {
trivia: TriviaItem[];
}

const { trivia } = Astro.props;
---

<div class="ep25-carousel not-prose" id="ep25-carousel">
<div class="ep25-carousel-inner">
{trivia.map((item, i) => (
<div class={`ep25-slide ${i === 0 ? 'active' : ''}`} aria-hidden={i !== 0 ? "true" : "false"}>
{item.year && <div class="ep25-slide-year">{item.year}</div>}
<p class="ep25-slide-text">{item.text}</p>
</div>
))}
</div>

<div class="ep25-controls">
<button class="ep25-btn" id="ep25-prev" aria-label="Previous">←</button>
<div class="ep25-dots">
{trivia.map((_, i) => (
<button
class={`ep25-dot ${i === 0 ? 'active' : ''}`}
data-index={i}
aria-label={`Go to item ${i + 1}`}
></button>
))}
</div>
<button class="ep25-btn" id="ep25-next" aria-label="Next">→</button>
</div>
</div>

<script>
const carousel = document.getElementById("ep25-carousel");
if (carousel) {
const slides = Array.from(carousel.querySelectorAll<HTMLElement>(".ep25-slide"));
const dots = Array.from(carousel.querySelectorAll<HTMLElement>(".ep25-dot"));
let current = 0;
let timer: ReturnType<typeof setInterval>;

function goTo(index: number) {
slides[current].classList.remove("active");
slides[current].setAttribute("aria-hidden", "true");
dots[current].classList.remove("active");
current = ((index % slides.length) + slides.length) % slides.length;
slides[current].classList.add("active");
slides[current].setAttribute("aria-hidden", "false");
dots[current].classList.add("active");
}

function startAutoplay() {
timer = setInterval(() => goTo(current + 1), 9000);
}

function resetAutoplay() {
clearInterval(timer);
startAutoplay();
}

carousel.querySelector("#ep25-prev")?.addEventListener("click", () => { goTo(current - 1); resetAutoplay(); });
carousel.querySelector("#ep25-next")?.addEventListener("click", () => { goTo(current + 1); resetAutoplay(); });
dots.forEach((dot, i) => dot.addEventListener("click", () => { goTo(i); resetAutoplay(); }));

startAutoplay();
}
</script>

<style>
.ep25-carousel {
border: 1px dashed var(--color-border);
border-left: 3px solid rgb(255, 181, 0);
border-radius: 2px;
padding: 2rem 2rem 1.5rem;
margin: 2rem 0;
background: var(--color-surface-subtle, transparent);
}

.ep25-carousel-inner {
min-height: 6rem;
}

.ep25-slide {
display: none;
animation: ep25FadeIn 0.35s ease;
}

.ep25-slide.active {
display: block;
}

@keyframes ep25FadeIn {
from { opacity: 0; transform: translateY(5px); }
to { opacity: 1; transform: translateY(0); }
}

.ep25-slide-year {
font-size: 0.8rem;
font-weight: 700;
letter-spacing: 0.12em;
text-transform: uppercase;
color: var(--color-accent-themed, var(--color-primary));
margin-bottom: 0.5rem;
}

.ep25-slide-text {
font-size: 1.05rem;
line-height: 1.75;
color: var(--color-text-primary);
font-style: italic;
margin: 0;
}

.ep25-controls {
display: flex;
align-items: center;
justify-content: center;
gap: 0.75rem;
margin-top: 1.5rem;
}

.ep25-btn {
background: none;
border: 1px solid var(--color-border);
border-radius: 2px;
padding: 0.3rem 0.7rem;
cursor: pointer;
color: var(--color-text-primary);
font-size: 1rem;
line-height: 1;
transition: border-color 0.2s, background 0.2s;
}

.ep25-btn:hover {
border-color: var(--color-accent-themed);
background: var(--color-surface-subtle);
}

.ep25-dots {
display: flex;
gap: 0.5rem;
align-items: center;
}

.ep25-dot {
width: 8px;
height: 8px;
border-radius: 50%;
border: 1px solid var(--color-border);
background: transparent;
cursor: pointer;
padding: 0;
transition: background 0.2s, border-color 0.2s;
}

.ep25-dot.active {
background: var(--color-accent-themed, var(--color-primary));
border-color: var(--color-accent-themed, var(--color-primary));
}
</style>
10 changes: 10 additions & 0 deletions src/content/deadlines/03_anniversary.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
title: Celebrating 25 Years of EuroPython
subtitle: Celebrate With Us
url: /25yearsofep
image: volunteers-2024.jpg
---

EuroPython turns 25! Join us in Kraków to celebrate a quarter-century of the
community. Dig out your oldest EuroPython t-shirt and badge: there are contests
and awards waiting at the Social Event.
86 changes: 86 additions & 0 deletions src/content/pages/25yearsofep.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
---
title: 25 Years of EuroPython
subtitle: A quarter-century of the European Python community — and two contests to celebrate it.
toc: false
---

import TriviaCarousel from "../../components/sections/TriviaCarousel.astro";

# 25 Years of EuroPython

Since its very first edition back in 2002, EuroPython has grown into the longest-running community Python conference in Europe. Over the years it has travelled
across the continent, hosted by volunteers in city after city, bringing together
thousands of Pythonistas to learn, share, and build the community we know today.

In 2026 we reach a special milestone: **our 25th edition**, here in Kraków. To mark
it, we want to celebrate not just the talks and the code, but the people and the
memories: the conversations in hallways, the friendships, and yes, the swag.

<div class="not-prose flex flex-col gap-6 my-8">
<figure class="m-0">
<img src="/media/bingo/ep2002-announcement.png" alt="EuroPython 2002 announcement" class="w-full rounded-sm border border-[var(--color-border)]" />
<figcaption class="mt-2 text-center text-sm text-[var(--color-text-muted)]">EuroPython 2002 announcement</figcaption>
</figure>
<figure class="m-0">
<img src="/media/bingo/ep2002-website.png" alt="Screenshot of the EuroPython 2002 website" class="w-full rounded-sm border border-[var(--color-border)]" />
<figcaption class="mt-2 text-center text-sm text-[var(--color-text-muted)]">EuroPython 2002 website</figcaption>
</figure>
</div>

## Two contests on the Social Event night

Bring a piece of EuroPython history with you to the **Social Event** and take part
in our anniversary contests. Winners will be crowned and awarded on the night!

<div class="not-prose grid grid-cols-1 md:grid-cols-2 gap-4 my-6">
<div class="flex flex-col gap-3 p-7 border border-dashed border-[var(--color-border)] rounded-sm">
<div class="text-4xl">👕</div>
<h3 class="text-xl font-semibold text-[var(--color-text)]">Oldest T-shirt</h3>
<p class="text-base leading-relaxed text-[var(--color-text-secondary)]">Still got a EuroPython T-shirt from years gone by? Wear it or bring it along. The oldest EuroPython T-shirt wins.</p>
</div>
<div class="flex flex-col gap-3 p-7 border border-dashed border-[var(--color-border)] rounded-sm">
<div class="text-4xl">🪪</div>
<h3 class="text-xl font-semibold text-[var(--color-text)]">Oldest Badge</h3>
<p class="text-base leading-relaxed text-[var(--color-text-secondary)]">Kept your conference badge as a souvenir? Dust it off and bring it: the oldest EuroPython badge wins.</p>
</div>
</div>

Awards for both contests will be handed out during the Social Event on Thursday. See you there!

{/*
TRIVIA FORMAT
Each item in the array below is an object with:
- year (optional) — short label shown above the text, e.g. "EP 2002" or "2010"
- text (required) — 2–3 plain-text sentences about that edition or milestone

Example:
{ year: "EP 2002", text: "The very first EuroPython was held in Charleroi, Belgium in June 2002. Around 200 Pythonistas from across Europe gathered for three days of talks and sprints." }
*/}
<TriviaCarousel trivia={[
{ year: "EP 2002", text: "The first EuroPython was held in Charleroi, Belgium, from 26–28 June 2002, drawing 240 attendees. It was a double first: the first major Python conference run entirely by community volunteers, and the first major Python conference held in Europe. It grew out of the European Python Meeting that Marc Poinot kick-started at LSM 2001 in Bordeaux the year before, and Guido van Rossum's keynote is among the preserved 2002 materials." },
{ year: "EP 2003", text: "EuroPython returned to Charleroi, Belgium, from 25–27 June 2003. The edition recorded 300 attendees and 70 speakers." },
{ year: "EP 2004", text: "The 2004 conference took place in Göteborg, Sweden, from 7–9 June. The EuroPython Society (EPS) was founded at this conference and registered later that year as the non-profit backing the event." },
{ year: "EP 2006", text: "EuroPython 2006 was hosted at CERN in Geneva, Switzerland, from 30 June to 9 July. CERN is famous as the birthplace of the World Wide Web." },
{ year: "EP 2011–2013", text: "Florence, Italy, hosted EuroPython three years running, in 2011, 2012, and 2013. Attendance grew across the streak, from 681 in 2011 to 845 by 2013." },
{ year: "EP 2014", text: "The 2014 edition was held in Berlin, Germany, from 21–27 July, with 1,226 attendees. It featured a Django Girls workshop attended by 42 women." },
{ year: "EP 2015 & 2017", text: "Starting in 2015 the EPS began co-organising the event, and from 2017 it took over running it entirely, after the conference outgrew what local-only teams could manage. This marked the shift from purely local organising to a Society-run model." },
{ year: "EP 2020", text: "EuroPython 2020 was the first-ever fully online edition, held 23–26 July 2020. It drew 992 attendees from more than 60 countries after the planned in-person event in Dublin was cancelled due to COVID-19." },
{ year: "EP 2021", text: "Held online from 26 July to 1 August 2021, this edition recorded 1,721 attendees from over 80 countries. It was the largest attendance figure in EuroPython's history, and like 2020 it had originally been planned for Dublin before COVID-19 forced it online." },
{ year: "EP 2022", text: "EuroPython 2022 in Dublin, Ireland, was the first hybrid edition. Attendee survey data showed 19.81% identified as female and 1.51% as non-binary, up notably from roughly 6% women back in 2011." },
{ year: "EP 2023–2025", text: "Prague, the Czech Republic, hosted three consecutive editions in 2023, 2024, and 2025 before the move to Kraków. EuroPython 2025 was a big one, with over 1,587 participants, 165 speakers, and 6 parallel tracks plus 2 open-space rooms." },
{ year: "EP 2026", text: "EuroPython 2026 moves to Kraków, Poland, marking the 25th consecutive edition since 2002 and the conference's first time in Poland. It follows three successful years in Prague." },
{ year: "Milestone", text: "Over its history EuroPython has toured 11 countries: Belgium, Sweden, Switzerland, Lithuania, the UK, Italy, Germany, Spain, Ireland, the Czech Republic, and now Poland. The EuroPython Society, a Sweden-based non-profit, holds the 'EuroPython' trademark and is billed as the largest Python conference in Europe and one of the largest worldwide." },
]} />

<div class="not-prose my-8" style="position:relative;padding-bottom:56.25%;height:0;overflow:hidden;">
<iframe
src="https://www.youtube-nocookie.com/embed/CcgUUnO2Mbw"
title="EuroPython: Where The Community Comes Together"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen
style="position:absolute;top:0;left:0;width:100%;height:100%;border:0;"
></iframe>
</div>


Here's to the next 25 years of learning, connecting, laughs, and friendship!
2 changes: 2 additions & 0 deletions src/data/nav.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ const L = {
url: "https://ep2026.europython.eu/25anniversary",
external: true,
},
yearsOfEp: { label: "25 Years of EuroPython", url: "/25yearsofep" },
};

// ── Nav menus ────────────────────────────────────────────────
Expand Down Expand Up @@ -148,6 +149,7 @@ export const NAV_MENUS: NavMenu[] = [
L.beginnersDay,
L.speakersDinner,
L.openSpaces,
L.yearsOfEp,
],
},
{
Expand Down
Loading