diff --git a/src/components/typography/title.tsx b/src/components/typography/title.tsx
deleted file mode 100644
index d1ccfceb9..000000000
--- a/src/components/typography/title.tsx
+++ /dev/null
@@ -1,50 +0,0 @@
-import clsx from "clsx";
-import type { JSX } from "react/jsx-runtime";
-
-export const Title = ({
- children,
- highlighted = false,
- level = 1,
- className,
- ...props
-}: {
- children: React.ReactNode;
- highlighted?: boolean;
- level?: 1 | 2 | 3 | 4 | 5 | 6;
- className?: string;
-}) => {
- const Tag = `h${level}` as keyof JSX.IntrinsicElements;
-
- return (
-
a]:border-0 [&>a]:text-inherit text-pretty",
- {
- "text-4xl md:text-7xl": level === 1,
- "text-3xl md:text-5xl": level === 2,
- "text-2xl md:text-4xl": level === 3,
- "text-xl md:text-3xl": level === 4,
- "text-lg md:text-2xl": level === 5,
- "text-lg md:text-xl": level === 6,
- },
- className
- )}
- {...props}
- >
- {highlighted ? (
- = 4,
- })}
- >
- #
-
- ) : null}
-
- {children}
-
- );
-};
diff --git a/src/components/accordion/accordion.astro b/src/components/ui/Accordion.astro
similarity index 100%
rename from src/components/accordion/accordion.astro
rename to src/components/ui/Accordion.astro
diff --git a/src/components/ui/Button.astro b/src/components/ui/Button.astro
index 270f1b99e..e5d32a98c 100644
--- a/src/components/ui/Button.astro
+++ b/src/components/ui/Button.astro
@@ -23,10 +23,10 @@ const {
const resolvedIsExternal = isExternal ?? url?.startsWith("http");
-const baseClasses = "button-link font-bold text-lg px-4 py-4 rounded-lg inline-flex items-center justify-center leading-4 transition-colors duration-200 not-prose border hover:text-black";
+const baseClasses = "button-link font-bold text-lg px-4 py-4 rounded-lg inline-flex items-center justify-center leading-4 transition-colors duration-200 not-prose border text-text";
const primaryClasses = "bg-button text-text-inverted hover:bg-button-hover border-transparent";
const secondaryClasses = "bg-primary text-white hover:bg-primary-hover border-transparent";
-const clearClasses = "bg-transparent text-primary hover:bg-transparent hover:text-primary-active border-transparent";
+const clearClasses = "bg-transparent text-primary hover:bg-transparent hover:text-text-inverted border-transparent";
const outlineClasses = "border-gray-500 text-gray-700 hover:bg-gray-100 hover:bg-button-hover";
const disabledClasses = "opacity-50 pointer-events-none";
const iconClasses = "mx-2 ";
diff --git a/src/components/ui/Headline.astro b/src/components/ui/Headline.astro
index 2f3ba4ecb..12f0f887f 100644
--- a/src/components/ui/Headline.astro
+++ b/src/components/ui/Headline.astro
@@ -9,11 +9,13 @@ const isCenter = center ? "text-center" : "";
---
- {isAnchor && (
+ {isAnchor ? (
{Title}
- )}
+ ):
+ <>{Title}>
+ }
{isLink && {Title} }
diff --git a/src/components/ui/Label.astro b/src/components/ui/Label.astro
new file mode 100644
index 000000000..2b2d77184
--- /dev/null
+++ b/src/components/ui/Label.astro
@@ -0,0 +1,15 @@
+
+---
+interface Props {
+ htmlFor: string;
+}
+
+const { htmlFor } = Astro.props;
+---
+
+
diff --git a/src/components/prose/prose.astro b/src/components/ui/Prose.astro
similarity index 100%
rename from src/components/prose/prose.astro
rename to src/components/ui/Prose.astro
diff --git a/src/components/ui/Select.astro b/src/components/ui/Select.astro
new file mode 100644
index 000000000..471a458b1
--- /dev/null
+++ b/src/components/ui/Select.astro
@@ -0,0 +1,40 @@
+---
+interface Props {
+ id: string;
+ name: string;
+ defaultValue?: string;
+}
+
+const { id, name, defaultValue } = Astro.props;
+
+const selectClasses = [
+ "block w-full bg-transparent text-lg h-16 py-2 pr-16 pl-4 border-[3px] border-primary appearance-none",
+ "focus:outline-none focus:border-black focus-visible:bg-white"
+].join(" ");
+
+const svgClasses = [
+ "absolute top-1/2 -translate-y-1/2 w-6 h-6 pointer-events-none text-primary right-4"
+].join(" ");
+---
+
+
diff --git a/src/components/ui/Tag.astro b/src/components/ui/Tag.astro
new file mode 100644
index 000000000..a99009993
--- /dev/null
+++ b/src/components/ui/Tag.astro
@@ -0,0 +1,26 @@
+---
+interface Props {
+ className?: string;
+ href?: string;
+}
+
+const { className = "", href } = Astro.props;
+
+const baseClasses = [
+ "inline-block bg-secondary-light text-white px-4 py-2 rounded-xl font-bold",
+ "hover:bg-secondary hover:text-white transition-colors",
+ "duration-200 ease-in-out cursor-pointer"
+];
+
+const combinedClasses = [...baseClasses, className].join(" ");
+---
+
+{href ? (
+
+
+
+) : (
+
+
+
+)}
diff --git a/src/content/days/.gitkeep b/src/content/days/.gitkeep
deleted file mode 100644
index e69de29bb..000000000
diff --git a/src/content/deadlines/05_call_for_venues.md b/src/content/deadlines/05_call_for_venues.md
index d67679ed0..f30381a7a 100644
--- a/src/content/deadlines/05_call_for_venues.md
+++ b/src/content/deadlines/05_call_for_venues.md
@@ -1,6 +1,6 @@
---
title: Call for 2026 Venues
-subtitle: Read More
+subtitle: Propose a Venue
url: https://europython-society.org/call-for-europython-2026-host-venues
image: "./venue.jpg"
---
diff --git a/src/content/pages/sponsorship/sponsor.mdx b/src/content/pages/sponsorship/sponsor.mdx
index 5d7bc2043..3e465bbe6 100644
--- a/src/content/pages/sponsorship/sponsor.mdx
+++ b/src/content/pages/sponsorship/sponsor.mdx
@@ -10,14 +10,15 @@ toc: false
# Why Sponsor EuroPython?
Stand out in the heart of Europe’s Python ecosystem and connect with ~1,500 Python professionals
- **~1,500** participants from **~50** countries
- **24th** edition – the world’s **longest-running** Python conference
- **190+** speakers across diverse Python topics
- **40K+** social media followers
- **34K** YouTube subscribers and **4M+** YouTube views
- **25%** of participants from underrepresented groups in tech
+- **~1,500** participants from **~50** countries
+- **24th** edition – the world’s **longest-running** Python conference
+- **190+** speakers across diverse Python topics
+- **40K+** social media followers
+- **34K** YouTube subscribers and **4M+** YouTube views
+- **25%** of participants from underrepresented groups in tech
+
Join **EuroPython 2025 from 14 – 20 July** at the Prague Congress Centre (PCC) to connect, showcase your company, and shape the future of Python!
diff --git a/src/layouts/MarkdownLayout.astro b/src/layouts/MarkdownLayout.astro
index 0fa455a58..88beeb2e3 100644
--- a/src/layouts/MarkdownLayout.astro
+++ b/src/layouts/MarkdownLayout.astro
@@ -3,7 +3,7 @@ import Layout from "@layouts/Layout.astro";
import Section from "@ui/Section.astro";
import TwoCols from "@components/TwoCols.astro";
-import "../styles/markdown.css";
+import "@styles/markdown.css";
const { title, description, toc=false } = Astro.props;
diff --git a/src/layouts/SectionLayout.astro b/src/layouts/SectionLayout.astro
index 1a8d69a47..06d4d2af6 100644
--- a/src/layouts/SectionLayout.astro
+++ b/src/layouts/SectionLayout.astro
@@ -1,8 +1,7 @@
---
import Layout from "@layouts/Layout.astro";
import Section from "@ui/Section.astro";
-
-import "../styles/markdown.css";
+import "@styles/markdown.css";
const { title, description } = Astro.props;
---
diff --git a/src/pages/[...slug].astro b/src/pages/[...slug].astro
index 08de2244c..4257ea540 100644
--- a/src/pages/[...slug].astro
+++ b/src/pages/[...slug].astro
@@ -5,18 +5,17 @@ import Layout from "@layouts/MarkdownLayout.astro";
import Separator from "@ui/Separator.astro";
import Map from "@components/Map.astro";
import YouTube from "@ui/YouTube.astro";
-import HighlightCard from "@components/highlight-list/highlight-card.astro";
-import HighlightItem from "@components/highlight-list/highlight-item.astro";
+import HighlightCard from "@components/markdown/HighlightCard.astro";
import Note from "@ui/Note.astro";
import SponsorTiers from "@components/sponsor-tiers/sponsor-tiers.astro";
-import Accordion from "@components/accordion/accordion.astro";
+import Accordion from "@components/ui/Accordion.astro";
import Button from "@ui/Button.astro";
import Icon from "@ui/Icon.astro";
import IconLabel from "@components/markdown/IconLabel.astro";
import Center from "@components/markdown/Center.astro";
import EPSLogo from "@components/markdown/EPSLogo.astro";
-import Prose from "@components/prose/prose.astro";
+import Prose from "@ui/Prose.astro";
export async function getStaticPaths() {
const pages = await getCollection("pages");
@@ -61,7 +60,6 @@ const description = post.data.subtitle;
Map,
YouTube,
HighlightCard,
- HighlightItem,
Note,
SponsorTiers,
hr: Separator,
diff --git a/src/pages/api/buffer_posts.ts b/src/pages/api/buffer_posts.ts
index 6e1ff6d2a..a74bf593d 100644
--- a/src/pages/api/buffer_posts.ts
+++ b/src/pages/api/buffer_posts.ts
@@ -16,12 +16,6 @@ function getBlueskyUsername(url: string): string | undefined {
}
// Get Bluesky profile link from username
-function getBlueskyProfileLink(username: string): string {
- // Remove any leading @ if present
- const cleanUsername = username.replace(/^@/, "");
- return `https://bsky.app/profile/${cleanUsername}`;
-}
-
// Get @username@instance.tld from Mastodon URL
function getMastodonUsername(url: string): string | undefined {
if (!url) return undefined;
@@ -42,7 +36,7 @@ function getLinkedInUsernameHandler(url: string): string | undefined {
return undefined;
}
-export const GET: APIRoute = async ({ params, request }) => {
+export const GET: APIRoute = async () => {
const limit = Infinity;
const speakers = await getCollection("speakers");
const exclude = [
@@ -64,7 +58,7 @@ export const GET: APIRoute = async ({ params, request }) => {
// Tailor message templates for each platform using appropriate handle formats
const message_template = {
- instagram: ({ name, talkTitle, talkUrl }) =>
+ instagram: ({ name, talkTitle }) =>
`Join ${name} at EuroPython for "${talkTitle}".`,
x: ({ name, handle, talkTitle, talkUrl }) =>
@@ -72,7 +66,7 @@ export const GET: APIRoute = async ({ params, request }) => {
? `Join ${name} (${handle}) at EuroPython for "${talkTitle}". Talk: ${talkUrl}`
: `Join ${name} at EuroPython for "${talkTitle}". Talk: ${talkUrl}`,
- linkedin: ({ name, handle, talkTitle, talkUrl }) =>
+ linkedin: ({ name, talkTitle }) =>
`Join ${name} at EuroPython for "${talkTitle}".`,
bsky: ({ name, handle, talkTitle, talkUrl }) =>
diff --git a/src/pages/index.astro b/src/pages/index.astro
index 94ff32dd4..383529d2c 100644
--- a/src/pages/index.astro
+++ b/src/pages/index.astro
@@ -1,8 +1,8 @@
---
import Layout from "@layouts/Layout.astro";
import Hero from "@sections/hero/hero.astro";
-import Updates from "@sections/updates.astro";
-import Keynoters from "@components/keynoters/keynoters.astro";
+import Updates from "@sections/updates/updates.astro";
+import Keynoters from "@sections/keynoters/keynoters.astro";
import Speakers from "@sections/speakers.astro";
import Prague from "@sections/prague.astro";
import Sponsors from "@components/sponsors/sponsors.astro";
diff --git a/src/pages/media/social_media.csv.ts b/src/pages/media/social_media.csv.ts
index 553668b6d..3448c9002 100644
--- a/src/pages/media/social_media.csv.ts
+++ b/src/pages/media/social_media.csv.ts
@@ -1,5 +1,5 @@
import { getCollection, getEntry } from "astro:content";
-export async function GET({ params, request }) {
+export async function GET() {
const speakers = await getCollection("speakers");
const header = [
diff --git a/src/pages/session/[slug].astro b/src/pages/session/[slug].astro
index 733a8cb3f..d7f851105 100644
--- a/src/pages/session/[slug].astro
+++ b/src/pages/session/[slug].astro
@@ -1,7 +1,7 @@
---
import { getCollection, getEntries } from "astro:content";
import Layout from "@layouts/Layout.astro";
-import Prose from "@components/prose/prose.astro";
+import Prose from "@ui/Prose.astro";
import Separator from "@ui/Separator.astro";
import { formatInTimeZone } from "date-fns-tz";
import { YouTube } from "@astro-community/astro-embed-youtube";
diff --git a/src/pages/sessions.astro b/src/pages/sessions.astro
index e15b8f05c..5a98906af 100644
--- a/src/pages/sessions.astro
+++ b/src/pages/sessions.astro
@@ -1,10 +1,10 @@
---
import { getCollection } from "astro:content";
-import Layout from "../layouts/Layout.astro";
-import Prose from "../components/prose/prose.astro";
+import Layout from "@layouts/Layout.astro";
+import Prose from "@ui/Prose.astro";
import Headline from "@ui/Headline.astro"
-import Filter from "../components/sessions/filter.astro";
-import ListSessions from "../components/sessions/list-sessions.astro";
+import Filter from "@components/sessions/filter.astro";
+import ListSessions from "@components/sessions/list-sessions.astro";
import Section from "@ui/Section.astro";
const sessions = await getCollection("sessions");
diff --git a/src/pages/speaker/[slug].astro b/src/pages/speaker/[slug].astro
index a11fef7aa..9f9639c82 100644
--- a/src/pages/speaker/[slug].astro
+++ b/src/pages/speaker/[slug].astro
@@ -1,7 +1,7 @@
---
import { getCollection, getEntries } from "astro:content";
-import Layout from "../../layouts/Layout.astro";
-import Prose from "../../components/prose/prose.astro";
+import Layout from "@layouts/Layout.astro";
+import Prose from "@ui/Prose.astro";
import { Image } from "astro:assets";
import Markdown from "@ui/Markdown.astro";
import Headline from "@ui/Headline.astro";
diff --git a/src/styles/global.css b/src/styles/global.css
index 4d3806342..4d0e155f4 100644
--- a/src/styles/global.css
+++ b/src/styles/global.css
@@ -2,14 +2,20 @@
--color-primary: #151f38;
--color-primary-hover: #7a7ebd;
--color-primary-active: #7a7ebd;
- --color-button: #ee714b;
- --color-button-hover: #fabc1b;
+
+ --color-button: #6b5ca5; /* Darker orange-brown */
+ --color-button-hover: #8572c6; /* Lighter than base, but still accessible */
+ --color-button-active: #514689; /* Darker for pressed state */
+ --color-button-focus: #9c4222; /* Same as base with a visible outline */
+ --color-button-disabled: #b7b2c7; /* Desaturated, lighter version */
+ --color-button-text: #fdfdfd; /* White text on all states */
+
--color-secondary: #151f38;
--color-secondary-dark: #f5e5d6;
--color-secondary-darkest: white;
--color-secondary-light: #7a7ebd;
--color-text: #151f38;
- --color-text-inverted: white;
+ --color-text-inverted: #fdfdfd;
--color-body-background: #f5e5d6;
--color-hero-primary: #151f38;
--color-hero-secondary: #fabc1b;
diff --git a/tsconfig.json b/tsconfig.json
index ca0c62214..b8d54e624 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -3,8 +3,6 @@
"compilerOptions": {
"strictNullChecks": true,
"noImplicitAny": false,
- "jsx": "react-jsx",
- "jsxImportSource": "react",
"paths": {
"@utils/*": ["./src/utils/*"],
"@data/*": ["./src/data/*"],
@@ -13,6 +11,7 @@
"@ui/*": ["./src/components/ui/*"],
"@layouts/*": ["./src/layouts/*"],
"@assets/*": ["./src/assets/*"],
+ "@styles/*": ["./src/styles/*"],
"@i18n/*": ["./src/i18n/*"],
"@src/*": ["./src/*"]
}