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
105 changes: 105 additions & 0 deletions src/components/home/SectionMain.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
---
import { texts } from '../../i18n/home'

interface Props {
lang: string
}

const { lang } = Astro.props
const t = texts[lang as keyof typeof texts]
---

<div class="mt-20 p-20 flex gap-4 flex-col lg:flex-row">
<div class="flex-1">
<h1>
<img
src="/images/logo-vertical-alt-color-dark.svg"
alt="PyconES Barcelona 2026"
class="h-80 mx-auto mb-4"
/>
</h1>

<h2
id="subtitle-container"
class="mt-4 text-xl md:text-2xl text-pycon-red-75 font-mono h-8 flex justify-center items-start gap-2 [text-shadow:0_0_3px_var(--color-pycon-black),0_0_6px_var(--color-pycon-black),0_0_6px_var(--color-pycon-black),0_0_12px_var(--color-pycon-black)]"
aria-live="polite"
aria-busy="true"
>
<span aria-hidden="true" class="select-none">&gt;</span>
<span id="subtitle" data-final-text={t['index.subtitle']}>
{t['index.initializing']}
<span class="animate-pulse motion-reduce:animate-none" aria-hidden="true">_</span>
</span>
</h2>
</div>
<div class="flex-1 flex items-center justify-center mt-10 lg:mt-0">
<h3>
<p class="text-center text-xl max-w-3xl">
{t['index.message']}
</p>
</h3>
</div>
</div>

<script>
const letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()_+'

let interval: number | null = null

const runMatrixEffect = (element: HTMLElement) => {
const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches
if (prefersReducedMotion) return

let iteration = 0
clearInterval(interval as number)
const originalText = element.dataset.value || ''

interval = window.setInterval(() => {
element.innerText = originalText
.split('')
.map((_, index) => {
if (index < iteration) {
return originalText[index]
}
return letters[Math.floor(Math.random() * letters.length)]
})
.join('')

if (iteration >= originalText.length) {
clearInterval(interval as number)
}

iteration += 1 / 3
}, 30)
}

const init = () => {
const matrixText = document.getElementById('matrix-text')
const h1 = document.querySelector('h1')
const subtitle = document.getElementById('subtitle')
const actions = document.querySelector('#actions')

if (matrixText && h1) {
runMatrixEffect(matrixText)
h1.onmouseover = () => runMatrixEffect(matrixText)
}

if (subtitle) {
setTimeout(() => {
const finalText = subtitle.dataset.finalText
if (finalText) {
subtitle.textContent = finalText
}
const container = document.getElementById('subtitle-container')
if (container) {
container.setAttribute('aria-busy', 'false')
}
if (actions) {
actions.classList.remove('opacity-0')
}
}, 1500)
}
}

init()
</script>
118 changes: 2 additions & 116 deletions src/components/index.astro
Original file line number Diff line number Diff line change
@@ -1,129 +1,15 @@
---
import Layout from '../layouts/Layout.astro'
import '@fontsource-variable/jetbrains-mono'
import { texts } from '../i18n/home'
import { getRelativeLocaleUrl } from 'astro:i18n'
import SectionMain from './home/SectionMain.astro'

interface Props {
lang: string
}

const { lang } = Astro.props
const t = texts[lang as keyof typeof texts]
---

<Layout title="PyConES 2026">
<main class="min-h-screen flex flex-col justify-center items-center text-center px-4">
<div class="relative z-10 max-w-3xl">
<h1>
<img
src="/images/logo-vertical-alt-color-dark.svg"
alt="PyconES Barcelona 2026"
class="h-80 mx-auto mb-4"
/>
</h1>

<h2
id="subtitle-container"
class="mt-4 text-xl md:text-2xl text-pycon-red-75 font-mono h-8 flex justify-center items-center gap-2 [text-shadow:0_0_3px_var(--color-pycon-black),0_0_6px_var(--color-pycon-black),0_0_6px_var(--color-pycon-black),0_0_12px_var(--color-pycon-black)]"
aria-live="polite"
aria-busy="true"
>
<span aria-hidden="true" class="select-none">&gt;</span>
<span id="subtitle" data-final-text={t['index.subtitle']}>{t['index.initializing']}</span>
<span class="animate-pulse motion-reduce:animate-none" aria-hidden="true">_</span>
</h2>

<div
id="actions"
class="mt-12 flex flex-col md:flex-row gap-6 justify-center items-center opacity-0 transition-opacity duration-1000 ease-in"
>
<a href={getRelativeLocaleUrl(lang, 'sponsors')}>
<button
id="sponsor-btn"
type="button"
aria-describedby="sponsor-hint"
class="group relative px-7 py-2 bg-pycon-orange text-pycon-black font-mono font-bold text-lg hover:bg-pycon-yellow transition-all duration-300 shadow-[0_0_15px_rgba(255,130,0,0.5)] hover:shadow-[0_0_25px_rgba(255,130,0,0.8)] cursor-pointer focus:outline-none focus:ring-4 focus:ring-pycon-orange/50 rounded-sm"
>
<span
class="absolute inset-0 w-full h-full bg-white opacity-0 group-hover:opacity-20 transition-opacity pointer-events-none"
></span>

<span id="sponsor-text">
<span aria-hidden="true">&lt; </span><span lang="en">{t['index.sponsor_btn']}</span><span
aria-hidden="true"
>
/&gt;</span
>
</span>
</button>
</a>
</div>
</div>
</main>
<SectionMain lang={lang} />
</Layout>

<script>
const letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()_+'

let interval: number | null = null

const runMatrixEffect = (element: HTMLElement) => {
const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches
if (prefersReducedMotion) return

let iteration = 0
clearInterval(interval as number)
const originalText = element.dataset.value || ''

interval = window.setInterval(() => {
element.innerText = originalText
.split('')
.map((_, index) => {
if (index < iteration) {
return originalText[index]
}
return letters[Math.floor(Math.random() * letters.length)]
})
.join('')

if (iteration >= originalText.length) {
clearInterval(interval as number)
}

iteration += 1 / 3
}, 30)
}

const init = () => {
const matrixText = document.getElementById('matrix-text')
const h1 = document.querySelector('h1')
const subtitle = document.getElementById('subtitle')
const actions = document.querySelector('#actions')

if (matrixText && h1) {
runMatrixEffect(matrixText)
h1.onmouseover = () => runMatrixEffect(matrixText)
}

if (subtitle) {
setTimeout(() => {
const finalText = subtitle.dataset.finalText
if (finalText) {
subtitle.textContent = finalText
}
const container = document.getElementById('subtitle-container')
if (container) {
container.setAttribute('aria-busy', 'false')
}
if (actions) {
actions.classList.remove('opacity-0')
}
}, 1500)
}
}

//not needed now
document.addEventListener('astro:page-load', init)
init()
</script>
9 changes: 6 additions & 3 deletions src/i18n/home.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,19 @@ export const texts = {
es: {
'index.initializing': 'Inicializando sistema...',
'index.subtitle': 'Sede UB Barcelona | 6-8 Nov 2026',
'index.sponsor_btn': 'PATROCINA',
'index.message':
'Forma parte de la mayor conferencia nacional de Python, donde cientos de entusiastas, profesionales y empresas se reúnen para compartir conocimientos, experiencias y oportunidades en el mundo de Python. ¡No te pierdas esta oportunidad única de aprender, conectar y crecer en la comunidad Python!',
},
en: {
'index.initializing': 'Initialising system...',
'index.subtitle': 'UB Barcelona Venue | Nov 6-8, 2026',
'index.sponsor_btn': 'BECOME A SPONSOR',
'index.message':
"Join the largest national Python conference, where hundreds of enthusiasts, professionals, and companies come together to share knowledge, experiences, and opportunities in the world of Python. Don't miss this unique opportunity to learn, connect, and grow in the Python community!",
},
ca: {
'index.initializing': 'Inicialitzant sistema...',
'index.subtitle': 'Seu UB Barcelona | 6-8 Nov 2026',
'index.sponsor_btn': 'PATROCINA',
'index.message':
'Forma part de la major conferència nacional de Python, on centenars d’entusiastes, professionals i empreses es reuneixen per compartir coneixements, experiències i oportunitats en el món de Python. No et perdis aquesta oportunitat única d’aprendre, connectar i créixer en la comunitat Python!',
},
} as const
2 changes: 1 addition & 1 deletion src/layouts/Layout.astro
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ const { title, description = 'PyconES 2026' } = Astro.props
<LanguagePicker lang={lang} />
</nav>

<main class="relative z-10 flex flex-col justify-center">
<main class="relative z-10 flex flex-col justify-center text-white">
<slot />
</main>
</body>
Expand Down