From a0173b50894036fe53d809ee93d079d03e85a4ec Mon Sep 17 00:00:00 2001 From: Niko Date: Tue, 30 Jun 2026 08:16:04 +0200 Subject: [PATCH] Nav --- .env.development | 1 + .env.preview | 1 + src/components/Header.astro | 240 +++++++++++++++++++++++------ src/components/sections/city.astro | 2 +- src/content/pages/faq.mdx | 2 +- src/content/pages/krakow.mdx | 120 --------------- src/content/pages/remote/index.mdx | 2 +- src/content/pages/tickets.mdx | 2 +- src/content/pages/venue.mdx | 94 ++++++++++- src/data/nav.ts | 132 ++++++++++------ src/pages/tips.astro | 15 ++ 11 files changed, 391 insertions(+), 220 deletions(-) delete mode 100644 src/content/pages/krakow.mdx create mode 100644 src/pages/tips.astro diff --git a/.env.development b/.env.development index 5b41cdf93..a19427f93 100644 --- a/.env.development +++ b/.env.development @@ -2,3 +2,4 @@ EP_SESSIONS_API="https://static.europython.eu/programme/ep2026/releases/current/ EP_SPEAKERS_API="https://static.europython.eu/programme/ep2026/releases/current/speakers.json" EP_SCHEDULE_API="https://static.europython.eu/programme/ep2026/releases/current/schedule.json" EP_FAST_BUILD="true" +EP_SHOW_HIDDEN="true" diff --git a/.env.preview b/.env.preview index c00bb0d68..f3d8b1d2d 100644 --- a/.env.preview +++ b/.env.preview @@ -1,3 +1,4 @@ EP_SESSIONS_API="https://static.europython.eu/programme/ep2026/releases/current/sessions.json" EP_SPEAKERS_API="https://static.europython.eu/programme/ep2026/releases/current/speakers.json" EP_SCHEDULE_API="https://static.europython.eu/programme/ep2026/releases/current/schedule.json" +EP_SHOW_HIDDEN="true" diff --git a/src/components/Header.astro b/src/components/Header.astro index 5656db823..139b3753a 100644 --- a/src/components/Header.astro +++ b/src/components/Header.astro @@ -6,18 +6,38 @@ import ThemeToggle from "@components/ThemeToggle.astro"; import { NAV_MENUS, type NavMenu } from "@data/nav"; import { buildLinkChecker } from "@utils/nav"; +const showHidden = + import.meta.env.EP_SHOW_HIDDEN === "true" || + import.meta.env.PUBLIC_EP_SHOW_HIDDEN === "true"; + const linkExists = await buildLinkChecker(); -// Filter nav menus to only show links that point to existing pages +// Build a set of existing URLs for hidden-page detection +const existingUrls = new Set(); +for (const menu of NAV_MENUS) { + if (menu.url && linkExists(menu.url)) existingUrls.add(menu.url); + for (const section of menu.sections ?? []) { + for (const item of section.items) { + if (linkExists(item.url)) existingUrls.add(item.url); + } + } +} + +// Filter nav menus — in showHidden mode keep everything and mark missing pages const activeMenus = NAV_MENUS.map((menu) => ({ ...menu, sections: menu.sections ?.map((section) => ({ ...section, - items: section.items.filter((item) => linkExists(item.url)), + items: section.items + .filter((item) => showHidden || linkExists(item.url)) + .map((item) => ({ + ...item, + _hidden: !linkExists(item.url), + })), })) - .filter((section) => section.items.length > 0), -})).filter((menu) => !menu.sections || menu.sections.length > 0); + .filter((section) => showHidden || section.items.length > 0 || (!section.label && section.items.length === 0)), +})).filter((menu) => showHidden || !menu.sections || menu.sections.length > 0); --- @@ -133,7 +152,8 @@ nav { position: relative; } -.nav-item > a { +.nav-item > a, +.nav-item > button { display: flex; align-items: center; gap: 0.3em; @@ -150,13 +170,26 @@ nav { transition: color 0.15s, text-decoration-color 0.15s; } +.nav-item > button { + background: none; + border: none; + cursor: pointer; +} + .nav-item > a:hover, +.nav-item > button:hover, .nav-item:hover > a, -.nav-item > a:focus { +.nav-item:hover > button, +.nav-item > a:focus-visible, +.nav-item > button:focus-visible { color: var(--color-accent-themed); text-decoration-color: var(--color-accent-themed); } +.nav-hidden-page { + color: oklch(0.6 0.2 30) !important; +} + .nav-arrow { font-size: 0.55em; opacity: 0.6; @@ -204,12 +237,42 @@ nav { } .nav-dropdown-wide { - min-width: 540px; + position: fixed; + top: 52px; + left: 0; + right: 0; + margin: 0 auto; + max-width: 1200px; + padding-top: 0.25rem; +} + +@media (max-width: 900px) { + .nav-dropdown-wide { + position: static; + top: auto; + left: auto; + right: auto; + margin: 0; + max-width: none; + padding-top: 0; + } +} + +@media (max-width: 900px) { + .nav-dropdown-wide { + position: static; + top: auto; + left: auto; + right: auto; + margin: 0; + max-width: none; + padding: 0; + } } .nav-dropdown-grid { display: grid; - grid-template-columns: repeat(3, 1fr); + grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 0.5rem; } @@ -256,26 +319,38 @@ nav { .nav-mobile-search { display: none; } .nav-search-btn { + background: none; + border: none; + cursor: pointer; + padding: 0.45rem; + border-radius: 4px; + color: var(--color-text-secondary); + transition: color 0.2s, background 0.2s; display: flex; align-items: center; - gap: 0.45rem; - background: var(--color-surface-medium); - border: 1px solid var(--color-border-strong); - border-radius: 4px; - padding: 0.45rem 0.9rem; + justify-content: center; + flex-shrink: 0; margin-left: auto; - margin-right: 0.5rem; - cursor: pointer; + margin-right: 0.25rem; +} + +.nav-icon-btn { + background: none; + border: none; + padding: 0.45rem; + border-radius: 4px; color: var(--color-text-secondary); - font-family: 'Roboto', sans-serif; - font-size: 1rem; - transition: background 0.15s, color 0.15s; + transition: color 0.2s, background 0.2s; + display: flex; + align-items: center; + justify-content: center; flex-shrink: 0; } -.nav-search-btn:hover { - background: var(--color-border-strong); +.nav-search-btn:hover, +.nav-icon-btn:hover { color: var(--color-text); + background: var(--color-border); } .nav-cta { @@ -294,6 +369,25 @@ nav { } .nav-cta:hover { opacity: 0.85; } +.nav-cta-secondary { + font-size: 0.82rem; + letter-spacing: 0.06em; + text-transform: uppercase; + color: var(--color-text-secondary); + border: 1px solid var(--color-border-strong); + border-radius: 2px; + padding: 0.55rem 1.1rem; + text-decoration: none; + display: inline-block; + flex-shrink: 0; + margin-left: 0.25rem; + transition: color 0.15s, border-color 0.15s; +} +.nav-cta-secondary:hover { + color: var(--color-accent-themed); + border-color: var(--color-accent-themed); +} + /* Hamburger toggle - visible on mobile */ .nav-toggle { display: none; @@ -314,6 +408,11 @@ nav { display: flex; flex-direction: column; gap: 4px; + order: 100; + margin-left: 0; + } + + .nav-search-btn { margin-left: auto; } @@ -348,16 +447,13 @@ nav { display: flex; } - .nav-item > a { + .nav-item > a, + .nav-item > button { font-size: 1.1rem; padding: 0.8rem 0; border-bottom: 1px solid var(--color-border); } - .nav-search-btn { - display: none; - } - .nav-mobile-search { display: block; } @@ -381,7 +477,8 @@ nav { text-align: left; } - .nav-cta { + .nav-cta, + .nav-cta-secondary { display: none; } @@ -447,21 +544,23 @@ nav { border-bottom-color: oklch(0 0 0 / 0.1) !important; } -:global(.light) nav a:not(.nav-cta), +:global(.light) nav a:not(.nav-cta):not(.nav-cta-secondary), :global(.light) .nav-item > a, +:global(.light) .nav-item > button, :global(.light) .nav-toggle span, :global(.light) .theme-toggle { color: oklch(0.228 0.038 282.9) !important; /* #1a1a2e */ } -:global(.light) .nav-search-btn { - background: oklch(0 0 0 / 0.04) !important; - border-color: var(--color-scrim-15) !important; - color: var(--color-scrim-50) !important; +:global(.light) .nav-search-btn, +:global(.light) .nav-icon-btn { + color: oklch(0.228 0.038 282.9) !important; /* #1a1a2e */ } -:global(.light) .nav-search-btn:hover { +:global(.light) .nav-search-btn:hover, +:global(.light) .nav-icon-btn:hover { color: oklch(0.228 0.038 282.9) !important; /* #1a1a2e */ + background: oklch(0 0 0 / 0.06) !important; } :global(.light) a.nav-cta { @@ -469,6 +568,15 @@ nav { color: var(--color-white) !important; } +:global(.light) a.nav-cta-secondary { + color: var(--color-scrim-60) !important; + border-color: var(--color-scrim-30) !important; +} +:global(.light) a.nav-cta-secondary:hover { + color: var(--color-accent-themed) !important; + border-color: var(--color-accent-themed) !important; +} + :global(.light) .nav-dropdown-inner { background: oklch(1 0 0 / 0.95) !important; border-color: var(--color-scrim-15) !important; @@ -478,6 +586,10 @@ nav { color: oklch(0.228 0.038 282.9) !important; /* #1a1a2e */ } +:global(.light) .nav-dropdown li a.nav-hidden-page { + color: oklch(0.6 0.2 30) !important; +} + :global(.light) .nav-dropdown li a:hover { background: oklch(0 0 0 / 0.04) !important; } @@ -527,7 +639,7 @@ document.addEventListener("DOMContentLoaded", function() { }); // Dropdown toggle on mobile - navLinksEl.querySelectorAll(".nav-item.has-dropdown > a").forEach(function(link) { + navLinksEl.querySelectorAll(".nav-item.has-dropdown > button").forEach(function(link) { link.addEventListener("click", function(e) { if (window.innerWidth <= 900) { e.preventDefault(); @@ -551,8 +663,8 @@ document.addEventListener("DOMContentLoaded", function() { var isOpen = item.classList.contains("dropdown-open"); navLinksEl.querySelectorAll(".nav-item.dropdown-open").forEach(function(other) { other.classList.remove("dropdown-open"); - var otherLink = other.querySelector(":scope > a"); - if (otherLink) otherLink.setAttribute("aria-expanded", "false"); + var otherTrigger = other.querySelector(":scope > a, :scope > button"); + if (otherTrigger) otherTrigger.setAttribute("aria-expanded", "false"); }); if (!isOpen) { item.classList.add("dropdown-open"); @@ -575,7 +687,7 @@ document.addEventListener("DOMContentLoaded", function() { if (ke.key === "Escape") { var item = ddLink.closest(".nav-item.has-dropdown") as HTMLElement | null; if (item) item.classList.remove("dropdown-open"); - var trigger = item ? item.querySelector(":scope > a") as HTMLElement | null : null; + var trigger = item ? item.querySelector(":scope > a, :scope > button") as HTMLElement | null : null; if (trigger) { trigger.setAttribute("aria-expanded", "false"); trigger.focus(); @@ -689,4 +801,34 @@ document.addEventListener("DOMContentLoaded", function() { } }); }); + + // Keep wide dropdowns open while moving mouse from trigger to dropdown + var ddTimeout = null as any; + var activeDropdown = null as HTMLElement | null; + document.querySelectorAll('.nav-item.has-dropdown').forEach(function(item) { + var itemEl = item as HTMLElement; + itemEl.addEventListener('mouseenter', function() { + // Close previous dropdown immediately + if (activeDropdown && activeDropdown !== itemEl) { + if (ddTimeout) clearTimeout(ddTimeout); + activeDropdown.classList.remove('dropdown-open'); + var prevBtn = activeDropdown.querySelector(':scope > button'); + if (prevBtn) prevBtn.setAttribute('aria-expanded', 'false'); + } + activeDropdown = itemEl; + itemEl.classList.add('dropdown-open'); + var btn = itemEl.querySelector(':scope > button'); + if (btn) btn.setAttribute('aria-expanded', 'true'); + }); + itemEl.addEventListener('mouseleave', function() { + if (ddTimeout) clearTimeout(ddTimeout); + ddTimeout = setTimeout(function() { + itemEl.classList.remove('dropdown-open'); + var btn = itemEl.querySelector(':scope > button'); + if (btn) btn.setAttribute('aria-expanded', 'false'); + if (activeDropdown === itemEl) activeDropdown = null; + }, 250); + }); + }); + diff --git a/src/components/sections/city.astro b/src/components/sections/city.astro index 34388e508..0ffc28a35 100644 --- a/src/components/sections/city.astro +++ b/src/components/sections/city.astro @@ -29,7 +29,7 @@ import Section from "@ui/Section.astro"

- +
diff --git a/src/content/pages/faq.mdx b/src/content/pages/faq.mdx index 34cae62e7..5b2e6186b 100644 --- a/src/content/pages/faq.mdx +++ b/src/content/pages/faq.mdx @@ -44,7 +44,7 @@ subtitle: Frequently Asked Questions about EuroPython The conference will return to **Kraków, Poland**, with the main conference hosted at the [ICE Kraków Congress Centre](https://icekrakow.pl/en). -Need help getting around? Check out [how to navigate Kraków](/venue) and our volunteer-curated [Kraków exploration tips](/krakow). +Need help getting around? Check out [how to navigate Kraków](/venue) and our volunteer-curated [Kraków exploration tips](/tips). diff --git a/src/content/pages/krakow.mdx b/src/content/pages/krakow.mdx deleted file mode 100644 index f670e194e..000000000 --- a/src/content/pages/krakow.mdx +++ /dev/null @@ -1,120 +0,0 @@ ---- -title: About Kraków -subtitle: Everything you need to know about traveling to, getting around, and enjoying the city. ---- - -import { Image } from "astro:assets"; - -# Kraków Tips - -
- -At EuroPython 2026, many participants come with their families and friends. When you're -not at the conference, why not take some time to explore Kraków and its nearby areas? - -Below you'll find tips and recommendations to help you make the most of your stay in -Poland's cultural capital! - -## Fun Facts about Kraków - -- **Former Royal Capital**: Kraków was Poland's capital for over 500 years and home to Polish kings at Wawel Castle -- **UNESCO Heritage**: The entire Old Town was one of the first 12 sites listed as UNESCO World Heritage in 1978 -- **Dragon Legend**: According to legend, a dragon once lived in a cave beneath Wawel Hill - you can still visit the dragon's den today! -- **Europe's Largest Square**: The Main Market Square (Rynek Główny) is one of the largest medieval town squares in Europe at 40,000 m² -- **Underground City**: Beneath the Main Square lies a fascinating underground museum showcasing medieval Kraków -- **Salt Mine Wonder**: The nearby Wieliczka Salt Mine is an underground city of chambers, chapels, and sculptures carved entirely from salt -- **Student City**: With over 180,000 students, Kraków has one of the highest student populations in Europe -- **Trumpet Call**: Every hour, a trumpet signal (Hejnał mariacki) is played from St. Mary's Basilica - it stops abruptly mid-melody, commemorating a 13th-century trumpeter shot while warning the city of an attack - -## Getting Around - -### How to get to Kraków? -- **By plane**: [Kraków John Paul II Airport (KRK)](https://www.krakowairport.pl/en) is well connected to the city center (about 20 minutes by train/bus) -- **By train**: [Polish Railways (PKP)](https://www.pkp.pl/en/) connects Kraków to major European cities. The main station (Kraków Główny) is in the city center -- **From the airport**: Take bus 208, 209, or 252 to the city center, or the train from "Kraków Airport" station - -### Public Transport -In Kraków, public transport is efficient and affordable: -- Extensive tram and bus network operated by [MPK Kraków](https://www.mpk.krakow.pl/en/) -- Purchase tickets via mobile app [Jakdojade](https://jakdojade.pl/krakow) or at kiosks -- 20-minute ticket costs around 4.00 PLN (€0.90) -- Night buses run when trams stop -- The city center is very walkable - many attractions are within walking distance - -### Do I need to rent a car? -- Not necessary in Kraków; the Old Town is pedestrian-friendly and parking is limited -- Public transport and walking are the best ways to explore -- For day trips to nearby destinations (Wieliczka, Zakopane, Auschwitz), organized tours or trains are convenient - -### Weather in July -- Average temperatures: 18-25°C (64-77°F) -- Pack layers - evenings can be cooler -- Occasional summer rain showers - - -### Resources -- [Kraków Official Tourism](https://www.krakow.pl/english/) -- [Kraków Travel Guide](https://www.visitkrakow.com/) -- [Culture.pl - Kraków](https://culture.pl/en/city/krakow) - -### Must-See Attractions -- **Wawel Castle & Cathedral**: Royal residence with stunning architecture and the Crown Treasury -- **Main Market Square**: Europe's largest medieval square, with the iconic Cloth Hall and St. Mary's Basilica -- **St. Mary's Basilica**: Gothic church famous for its stunning altarpiece by Veit Stoss and hourly trumpet call -- **Kazimierz (Old Jewish Quarter)**: Historic district with synagogues, museums, and vibrant nightlife -- **Schindler's Factory Museum**: Poignant WWII museum telling the story of Nazi-occupied Kraków -- **Wawel Dragon's Den**: Cave beneath the castle - visit the legendary dragon and see the fire-breathing dragon statue outside -- **Underground Museum**: Beneath the Main Square, discover medieval Kraków through archaeological excavations - -### Day Trips -- **Wieliczka Salt Mine**: UNESCO World Heritage site - an underground cathedral carved entirely from salt (30 minutes from Kraków) -- **Auschwitz-Birkenau**: Important memorial and museum (1.5 hours from Kraków) -- **Zakopane & Tatra Mountains**: Poland's mountain resort with hiking and stunning views (2 hours from Kraków) -- **Ojców National Park**: Beautiful limestone formations and medieval castle ruins (30 minutes from Kraków) -- **Energylandia**: The bigest amusement park in Europe (half an hour from Kraków) - -### For Culture Lovers -- **National Museum**: Outstanding collection of Polish art -- **Manggha Museum**: Japanese art and technology -- **Cricoteka**: Center for the Documentation of the Art of Tadeusz Kantor -- **Starmach Gallery**: Contemporary art gallery in Kazimierz - -### For Nature Lovers -- **Vistula Boulevards**: Riverside promenade popular for walks, cycling, and evening drinks -- **Planty Park**: Green belt encircling the Old Town - perfect for a peaceful walk -- **Las Wolski (Wolski Forest)**: Large forest area with the Zoo and Camaldolese Monastery -- **Błonia Meadow**: Vast green space for picnics and outdoor activities -- **Kościuszko Mound**: Climb for panoramic views of Kraków and surrounding mountains - -### For Food Lovers -Kraków's food scene is thriving! Try these Polish specialties: -- **Pierogi**: Traditional dumplings (try Pierożek for local favorites) -- **Zapiekanka**: Polish open-faced baguette sandwich (find the best on Plac Nowy in Kazimierz) -- **Obwarzanek**: Kraków's unique twisted bagel - grab one fresh from street vendors -- **Barszcz**: Beetroot soup, a Polish classic -- **Żurek**: Sour rye soup served in a bread bowl -- **Milk bars (Bar mleczny)**: Cheap, traditional Polish cafeteria-style eateries - - -## Practical Tips - -### Money -- Currency: Polish Złoty (PLN) -- Almost all places accept cards, but please carry some cash for smaller vendors -- ATMs are widely available - -### Language -- Polish is the official language -- English is widely spoken in tourist areas, restaurants, and hotels - -### Safety -- Kraków is generally very safe -- Watch out for pickpockets in crowded tourist areas -- Use official taxis or ride-sharing apps (Uber, Bolt) - -### Opening Hours -- Shops: Typically 10:00-20:00 Monday-Saturday, closed on Sunday -- Restaurants: Usually open until 22:00-23:00 -- Museums: Often closed Mondays - ---- diff --git a/src/content/pages/remote/index.mdx b/src/content/pages/remote/index.mdx index c3762e016..19e14e865 100644 --- a/src/content/pages/remote/index.mdx +++ b/src/content/pages/remote/index.mdx @@ -10,7 +10,7 @@ import remote from "./remote.png"; # EuroPython 2026 Remote -As happy as we are about seeing many friends in [Kraków](/krakow) +As happy as we are about seeing many friends in [Kraków](/tips) this year, we are also aware that many of you will not be able to make it in person. That’s why EuroPython 2026 Remote is back. Wherever you are, let's celebrate Python and our community, rejoice at our diversity, diff --git a/src/content/pages/tickets.mdx b/src/content/pages/tickets.mdx index 284d5f58b..f21ac146f 100644 --- a/src/content/pages/tickets.mdx +++ b/src/content/pages/tickets.mdx @@ -15,7 +15,7 @@ Discover the latest Python trends, learn from 180+ expert speakers, network with ## Where and When? -🏛️ Kraków, Poland +🏛️ Kraków, Poland

A week of all things Python:

diff --git a/src/content/pages/venue.mdx b/src/content/pages/venue.mdx index 193ba7998..749a2664e 100644 --- a/src/content/pages/venue.mdx +++ b/src/content/pages/venue.mdx @@ -27,5 +27,95 @@ The ICE Kraków Congress Centre is located in the very heart of Kraków, directl - **Kazimierz (Jewish Quarter):** A short tram ride or 20-minute walk southeast. This historic district is known for its synagogues, Jewish heritage, vibrant nightlife, and trendy restaurants and bars. -## Sprints Venue -To be announced soon! +## Fun Facts about Kraków + +- **Former Royal Capital**: Kraków was Poland's capital for over 500 years and home to Polish kings at Wawel Castle +- **UNESCO Heritage**: The entire Old Town was one of the first 12 sites listed as UNESCO World Heritage in 1978 +- **Dragon Legend**: According to legend, a dragon once lived in a cave beneath Wawel Hill — you can still visit the dragon's den today! +- **Europe's Largest Square**: The Main Market Square (Rynek Główny) is one of the largest medieval town squares in Europe at 40,000 m² +- **Underground City**: Beneath the Main Square lies a fascinating underground museum showcasing medieval Kraków +- **Salt Mine Wonder**: The nearby Wieliczka Salt Mine is an underground city of chambers, chapels, and sculptures carved entirely from salt +- **Student City**: With over 180,000 students, Kraków has one of the highest student populations in Europe +- **Trumpet Call**: Every hour, a trumpet signal (Hejnał mariacki) is played from St. Mary's Basilica — it stops abruptly mid-melody, commemorating a 13th-century trumpeter shot while warning the city of an attack + +## Getting to Kraków + +- **By plane**: [Kraków John Paul II Airport (KRK)](https://www.krakowairport.pl/en) is well connected to the city center — about 20 minutes by train or bus +- **By train**: [Polish Railways (PKP)](https://www.pkp.pl/en/) connects Kraków to major European cities. The main station (Kraków Główny) is in the city center +- **From the airport**: Take bus 208, 209, or 252 to the city center, or the train from "Kraków Airport" station + +## Getting Around + +Kraków's public transport is efficient and affordable: + +- Extensive tram and bus network operated by [MPK Kraków](https://www.mpk.krakow.pl/en/) +- Purchase tickets via mobile app [Jakdojade](https://jakdojade.pl/krakow) or at kiosks +- 20-minute ticket costs around 4.00 PLN (€0.90) +- Night buses run when trams stop +- The city center is very walkable — many attractions are within walking distance + +**Do you need a car?** Not in Kraków; the Old Town is pedestrian-friendly and parking is limited. Public transport and walking are the best ways to explore. For day trips to nearby destinations (Wieliczka, Zakopane, Auschwitz), organized tours or trains are convenient. + +## Weather in July + +Average temperatures: 18–25°C (64–77°F). Pack layers — evenings can be cooler. Occasional summer rain showers. + +## Must-See Attractions + +- **Wawel Castle & Cathedral**: Royal residence with stunning architecture and the Crown Treasury +- **Main Market Square**: Europe's largest medieval square, with the iconic Cloth Hall and St. Mary's Basilica +- **St. Mary's Basilica**: Gothic church famous for its stunning altarpiece by Veit Stoss and hourly trumpet call +- **Kazimierz (Old Jewish Quarter)**: Historic district with synagogues, museums, and vibrant nightlife +- **Schindler's Factory Museum**: Poignant WWII museum telling the story of Nazi-occupied Kraków +- **Wawel Dragon's Den**: Cave beneath the castle — visit the legendary dragon and see the fire-breathing dragon statue outside +- **Underground Museum**: Beneath the Main Square, discover medieval Kraków through archaeological excavations + +## Day Trips + +- **Wieliczka Salt Mine**: UNESCO World Heritage site — an underground cathedral carved entirely from salt (30 minutes from Kraków) +- **Auschwitz-Birkenau**: Important memorial and museum (1.5 hours from Kraków) +- **Zakopane & Tatra Mountains**: Poland's mountain resort with hiking and stunning views (2 hours from Kraków) +- **Ojców National Park**: Beautiful limestone formations and medieval castle ruins (30 minutes from Kraków) +- **Energylandia**: The biggest amusement park in Europe (half an hour from Kraków) + +## For Culture & Nature Lovers + +**Culture:** +- **National Museum**: Outstanding collection of Polish art +- **Manggha Museum**: Japanese art and technology +- **Cricoteka**: Center for the Documentation of the Art of Tadeusz Kantor +- **Starmach Gallery**: Contemporary art gallery in Kazimierz + +**Nature:** +- **Vistula Boulevards**: Riverside promenade popular for walks, cycling, and evening drinks +- **Planty Park**: Green belt encircling the Old Town — perfect for a peaceful walk +- **Las Wolski (Wolski Forest)**: Large forest area with the Zoo and Camaldolese Monastery +- **Błonia Meadow**: Vast green space for picnics and outdoor activities +- **Kościuszko Mound**: Climb for panoramic views of Kraków and surrounding mountains + +## Food & Drink + +Kraków's food scene is thriving! Try these Polish specialties: + +- **Pierogi**: Traditional dumplings (try Pierożek for local favorites) +- **Zapiekanka**: Polish open-faced baguette sandwich (find the best on Plac Nowy in Kazimierz) +- **Obwarzanek**: Kraków's unique twisted bagel — grab one fresh from street vendors +- **Barszcz**: Beetroot soup, a Polish classic +- **Żurek**: Sour rye soup served in a bread bowl +- **Milk bars (Bar mleczny)**: Cheap, traditional Polish cafeteria-style eateries + +## Practical Tips + +**Money:** Polish Złoty (PLN). Almost all places accept cards, but carry some cash for smaller vendors. ATMs are widely available. + +**Language:** Polish is the official language. English is widely spoken in tourist areas, restaurants, and hotels. + +**Safety:** Kraków is generally very safe. Watch out for pickpockets in crowded tourist areas. Use official taxis or ride-sharing apps (Uber, Bolt). + +**Opening Hours:** Shops typically 10:00–20:00 Monday–Saturday, closed on Sunday. Restaurants usually open until 22:00–23:00. Museums often closed Mondays. + +## Resources + +- [Kraków Official Tourism](https://www.krakow.pl/english/) +- [Kraków Travel Guide](https://www.visitkrakow.com/) +- [Culture.pl - Kraków](https://culture.pl/en/city/krakow) diff --git a/src/data/nav.ts b/src/data/nav.ts index 5ae86618b..d033ac48c 100644 --- a/src/data/nav.ts +++ b/src/data/nav.ts @@ -1,13 +1,8 @@ -/** - * Single source of truth for all navigation and footer links. - * - * Inspired by ep26-draft/src/menu.py — typed, structured, reusable. - */ - export interface Link { label: string; url: string; external?: boolean; + _hidden?: boolean; } export interface NavSection { @@ -31,12 +26,13 @@ export interface FooterColumn { const L = { // Programme + schedule: { label: "Schedule", url: "/schedule" }, talks: { label: "Talks", url: "/talks" }, tutorials: { label: "Tutorials", url: "/tutorials" }, posters: { label: "Posters", url: "/posters" }, tracks: { label: "Tracks", url: "/tracks" }, - speakers: { label: "Speakers", url: "/speakers" }, + speakers: { label: "Our Speakers", url: "/speakers" }, sessions: { label: "List of all Sessions", url: "/sessions" }, guidelines: { label: "Speaker Guidelines", url: "/guidelines" }, mentorship: { label: "Speaker Mentorship", url: "/mentorship" }, @@ -51,7 +47,22 @@ const L = { socialEvent: { label: "Social Event", url: "/social-event" }, beginnersDay: { label: "Beginners' Day", url: "/beginners-day" }, speakersDinner: { label: "Speakers' Dinner", url: "/speakers-dinner" }, + cfp: { label: "CFP & Talk Selection", url: "/cfp" }, openSpaces: { label: "Open Spaces", url: "/open-spaces" }, + keynotes: { label: "Keynotes", url: "/keynotes" }, + cAPISummit: { label: "C-API Summit", url: "/c-api-summit" }, + wasmSummit: { label: "WASM Summit", url: "/wasm-summit" }, + pyladies: { label: "PyLadies", url: "/pyladies" }, + euroSciPy: { label: "EuroSciPy", url: "/euroscipy" }, + organisersSummit: { label: "Organisers Summit", url: "/organisers-summit" }, + beginners: { label: "Beginners", url: "/beginners" }, + lightningTalks: { label: "Lightning Talks", url: "/lightning-talks" }, + dataAI: { label: "Data & AI", url: "/data-ai" }, + inclusivity: { label: "Inclusivity", url: "/inclusivity" }, + childcare: { label: "Childcare", url: "/childcare" }, + help: { label: "Help", url: "/help" }, + discord: { label: "Discord", url: "/discord" }, + team: { label: "Our Team", url: "/team" }, // Participate tickets: { label: "Tickets", url: "/tickets" }, @@ -68,7 +79,7 @@ const L = { // Venue venue: { label: "Venue", url: "/venue" }, - krakow: { label: "Kraków", url: "/krakow" }, + krakow: { label: "Tips", url: "/tips" }, hotels: { label: "Hotels", url: "/hotels" }, // Sponsorship @@ -80,7 +91,7 @@ const L = { }, // Community - about: { label: "About Us", url: "/about" }, + about: { label: "About EuroPython", url: "/about" }, eps: { label: "EuroPython Society", url: "https://europython-society.org/", @@ -123,23 +134,34 @@ export const NAV_MENUS: NavMenu[] = [ // Programme — rich multi-column with labelled sections { label: "Programme", - url: "/sessions", + url: "/schedule", wide: true, sections: [ { - label: "Talks & Schedule", + label: "Sessions", items: [ - L.schedule, + L.keynotes, L.talks, L.tutorials, L.posters, - L.tracks, - L.speakers, + L.lightningTalks, + L.openSpaces, + L.dataAI, ], }, { label: "Summits", - items: [L.langSummit, L.rustSummit, L.packagingSummit], + items: [ + L.langSummit, + L.cAPISummit, + L.packagingSummit, + L.rustSummit, + L.wasmSummit, + ], + }, + { + label: "Community", + items: [L.pyladies, L.euroSciPy, L.organisersSummit], }, { label: "Events & Social", @@ -147,65 +169,85 @@ export const NAV_MENUS: NavMenu[] = [ L.sprints, L.socialEvent, L.beginnersDay, - L.speakersDinner, - L.openSpaces, + L.beginners, L.yearsOfEp, ], }, - { - label: "For Speakers", - items: [L.guidelines, L.mentorship], - }, ], }, - // Attend — simple flat list + // Attend — wide dropdown with 4 columns { label: "Attend", url: "/tickets", + wide: true, sections: [ { + label: "Registration", + items: [L.tickets, L.finaid, L.visa, L.hotels], + }, + { + label: "Speakers", items: [ - L.tickets, - L.finaid, - L.visa, - L.volunteering, - L.faq, - L.coc, - L.accessibility, + L.speakers, + L.guidelines, + L.mentorship, + L.cfp, + L.speakersDinner, ], }, + { + label: "Community", + items: [L.volunteering, L.inclusivity, L.accessibility], + }, + { + label: "Support", + items: [L.childcare, L.help, L.faq, L.coc], + }, ], }, - // Venue — simple flat list + // Venue — single link, no dropdown { label: "Venue", url: "/venue", - sections: [{ items: [L.venue, L.krakow, L.hotels] }], }, - // Sponsorship — simple flat list + // Sponsors — single link, no dropdown { - label: "Sponsorship", - url: "/sponsorship/sponsor", - sections: [{ items: [L.ourSponsors, L.sponsorPkg, L.sponsorInfo] }], + label: "Sponsors", + url: "/sponsors", }, - // Community — simple flat list + // About — simple flat list { label: "Community", url: "/about", + wide: true, sections: [ - { items: [L.about, L.eps, L.communityPartners, L.mediaPartners] }, + { + label: "Organization", + items: [ + L.about, + L.team, + L.communityPartners, + L.mediaPartners, + L.sponsorPkg, + L.sponsorInfo, + ], + }, + { + label: "Online", + items: [L.blog, L.eps], + }, + { + items: [], + }, + { + items: [], + }, ], }, - - // Jobs — single link, no dropdown - { - label: "Jobs", - url: "/jobs", - }, ]; // ── Social links ──────────────────────────────────────────── @@ -244,7 +286,7 @@ export const FOOTER_COLUMNS: FooterColumn[] = [ items: [L.tickets, L.krakow, L.visa], }, { - title: "Programme", + title: "Schedule", items: [ L.schedule, L.talks, @@ -270,7 +312,7 @@ export const FOOTER_COLUMNS: FooterColumn[] = [ ], }, { - title: "Sponsorship", + title: "Sponsors", items: [L.ourSponsors, L.sponsorPkg, L.sponsorInfo, L.jobs], }, { diff --git a/src/pages/tips.astro b/src/pages/tips.astro new file mode 100644 index 000000000..2b048397c --- /dev/null +++ b/src/pages/tips.astro @@ -0,0 +1,15 @@ +--- +--- + + + + + + + Redirecting… + + + +

Moved to /venue.

+ +