Skip to content

Commit b2dc4c3

Browse files
committed
Merge remote-tracking branch 'origin/develop' into fix_anchors
2 parents 1358a21 + 8297aa3 commit b2dc4c3

15 files changed

Lines changed: 431 additions & 230 deletions

File tree

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ on:
55
branches: [main, develop]
66

77
jobs:
8-
build:
8+
check:
9+
name: Check
910
runs-on: ubuntu-latest
1011
steps:
1112
- name: Checkout
@@ -22,5 +23,11 @@ jobs:
2223
- name: Install dependencies
2324
run: pnpm install
2425

26+
- name: Astro check
27+
run: pnpm astro check
28+
29+
- name: Prettier check
30+
run: pnpm exec prettier --check src
31+
2532
- name: Build
2633
run: pnpm build

.github/workflows/deploy.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ jobs:
3434

3535
- name: Build with Astro
3636
run: pnpm run build
37+
env:
38+
PUBLIC_GA_ID: ${{ secrets.PUBLIC_GA_ID }}
3739

3840
- name: Upload artifact
3941
if: github.event_name != 'pull_request'

src/components/AccommodationPage.astro

Lines changed: 109 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,24 @@ interface Props {
88
99
const { lang } = Astro.props
1010
const t = accommodationTexts[lang as keyof typeof accommodationTexts]
11+
type AreaSlug =
12+
| 'eixampleEsquerra'
13+
| 'elRaval'
14+
| 'santAntoni'
15+
| 'ciutatVella'
16+
| 'sants'
17+
| 'poblenou22'
18+
| 'elClot'
19+
| 'lesCorts'
20+
| 'eixampleDreta'
21+
| 'collblanc'
22+
23+
const walkingAreas: AreaSlug[] = ['eixampleEsquerra', 'elRaval', 'santAntoni', 'ciutatVella']
24+
const directMetroAreas: AreaSlug[] = ['sants', 'poblenou22', 'elClot']
25+
const transferAreas: AreaSlug[] = ['lesCorts', 'eixampleDreta', 'collblanc']
26+
27+
const areaName = (slug: AreaSlug) => t[`accommodation.areas.${slug}.name` as keyof typeof t]
28+
const areaDesc = (slug: AreaSlug) => t[`accommodation.areas.${slug}.desc` as keyof typeof t]
1129
---
1230

1331
<div class="accommodation-container pb-20">
@@ -20,33 +38,91 @@ const t = accommodationTexts[lang as keyof typeof accommodationTexts]
2038
</p>
2139
</section>
2240

23-
<section
24-
class="max-w-4xl bg-white/5 backdrop-blur-md p-8 md:p-12 rounded-3xl border border-white/10 mb-16 shadow-2xl"
25-
>
26-
<p class="text-lg text-pycon-gray-25 leading-relaxed">
27-
{t['accommodation.intro']}
28-
</p>
41+
<!-- Areas -->
42+
<section class="mb-24" aria-labelledby="accommodation-areas-heading">
43+
<div class="flex items-center gap-4 mb-12">
44+
<div class="h-px bg-white/20 flex-1" aria-hidden="true"></div>
45+
<h2 id="accommodation-areas-heading" class="text-3xl font-bold text-white px-4">
46+
{t['accommodation.areas.title']}
47+
</h2>
48+
<div class="h-px bg-white/20 flex-1" aria-hidden="true"></div>
49+
</div>
50+
<div class="max-w-4xl space-y-4 mb-12 text-pycon-gray-25 leading-relaxed">
51+
<p class="text-lg">{t['accommodation.areas.transportIntro.p1']}</p>
52+
<p class="text-lg">{t['accommodation.areas.transportIntro.p2']}</p>
53+
<p class="text-lg">{t['accommodation.areas.transportIntro.p3']}</p>
54+
</div>
55+
56+
<div class="space-y-16">
57+
<div>
58+
<h3 class="text-2xl font-bold text-white mb-6">{t['accommodation.areas.category.walking']}</h3>
59+
<ul class="grid sm:grid-cols-2 lg:grid-cols-3 gap-8 list-none m-0 p-0">
60+
{
61+
walkingAreas.map((slug) => (
62+
<li class="bg-pycon-black/40 p-8 rounded-2xl border border-white/5 hover:border-pycon-orange/50 transition-all motion-safe:hover:-translate-y-2">
63+
<h4 class="text-xl font-bold text-pycon-orange mb-4 italic">{areaName(slug)}</h4>
64+
<p class="text-pycon-gray-25 text-sm leading-relaxed">{areaDesc(slug)}</p>
65+
</li>
66+
))
67+
}
68+
</ul>
69+
</div>
70+
<div>
71+
<h3 class="text-2xl font-bold text-white mb-6">{t['accommodation.areas.category.directMetro']}</h3>
72+
<ul class="grid sm:grid-cols-2 lg:grid-cols-3 gap-8 list-none m-0 p-0">
73+
{
74+
directMetroAreas.map((slug) => (
75+
<li class="bg-pycon-black/40 p-8 rounded-2xl border border-white/5 hover:border-pycon-orange/50 transition-all motion-safe:hover:-translate-y-2">
76+
<h4 class="text-xl font-bold text-pycon-orange mb-4 italic">{areaName(slug)}</h4>
77+
<p class="text-pycon-gray-25 text-sm leading-relaxed">{areaDesc(slug)}</p>
78+
</li>
79+
))
80+
}
81+
</ul>
82+
</div>
83+
<div>
84+
<h3 class="text-2xl font-bold text-white mb-6">{t['accommodation.areas.category.transferMetro']}</h3>
85+
<ul class="grid sm:grid-cols-2 lg:grid-cols-3 gap-8 list-none m-0 p-0">
86+
{
87+
transferAreas.map((slug) => (
88+
<li class="bg-pycon-black/40 p-8 rounded-2xl border border-white/5 hover:border-pycon-orange/50 transition-all motion-safe:hover:-translate-y-2">
89+
<h4 class="text-xl font-bold text-pycon-orange mb-4 italic">{areaName(slug)}</h4>
90+
<p class="text-pycon-gray-25 text-sm leading-relaxed">{areaDesc(slug)}</p>
91+
</li>
92+
))
93+
}
94+
</ul>
95+
</div>
96+
</div>
2997
</section>
3098

3199
<!-- Hotels Section -->
32-
<section class="mb-24">
100+
<section class="mb-24" aria-labelledby="accommodation-hotels-heading">
33101
<div class="flex items-center gap-4 mb-12">
34-
<div class="h-px bg-white/20 flex-1"></div>
35-
<h2 class="text-3xl font-bold text-white px-4">{t['accommodation.hotels.title']}</h2>
36-
<div class="h-px bg-white/20 flex-1"></div>
102+
<div class="h-px bg-white/20 flex-1" aria-hidden="true"></div>
103+
<h2 id="accommodation-hotels-heading" class="text-3xl font-bold text-white px-4">
104+
{t['accommodation.hotels.title']}
105+
</h2>
106+
<div class="h-px bg-white/20 flex-1" aria-hidden="true"></div>
37107
</div>
38108

39109
<div
40110
class="bg-pycon-gray-100/50 p-12 rounded-3xl border border-pycon-yellow/30 text-center relative overflow-hidden group"
41111
>
42112
<!-- Shine effect -->
43113
<div
44-
class="absolute -top-full -left-full w-[300%] h-[300%] bg-linear-to-br from-transparent via-pycon-yellow/5 to-transparent rotate-45 transition-transform duration-1000 group-hover:translate-x-[33%] group-hover:translate-y-[33%] pointer-events-none"
114+
class="absolute -top-full -left-full w-[300%] h-[300%] bg-linear-to-br from-transparent via-pycon-yellow/5 to-transparent rotate-45 transition-transform duration-1000 motion-safe:group-hover:translate-x-[33%] motion-safe:group-hover:translate-y-[33%] pointer-events-none"
115+
aria-hidden="true"
45116
>
46117
</div>
47118

48119
<div class="relative z-10">
49-
<StatusIcon type="construction" size="xl" role="img" aria-label="Construyendo" />
120+
<StatusIcon
121+
type="construction"
122+
size="xl"
123+
role="img"
124+
aria-label={t['accommodation.a11y.constructionIcon']}
125+
/>
50126
<h3 class="text-2xl font-bold text-pycon-yellow mb-4">{t['accommodation.hotels.subtitle']}</h3>
51127
<p class="text-xl text-white font-medium max-w-2xl mx-auto italic opacity-80">
52128
{t['accommodation.hotels.disclaimer']}
@@ -55,61 +131,37 @@ const t = accommodationTexts[lang as keyof typeof accommodationTexts]
55131
</div>
56132
</section>
57133

58-
<!-- Areas -->
59-
<section class="mb-24">
60-
<h2 class="text-3xl font-bold text-white mb-12 flex items-center gap-3">
61-
<span class="w-2 h-8 bg-pycon-red rounded-full"></span>
62-
{t['accommodation.areas.title']}
63-
</h2>
64-
<div class="grid md:grid-cols-3 gap-8">
65-
<div
66-
class="bg-pycon-black/40 p-8 rounded-2xl border border-white/5 hover:border-pycon-orange/50 transition-all hover:-translate-y-2"
67-
>
68-
<h3 class="text-xl font-bold text-pycon-orange mb-4 italic">
69-
{t['accommodation.areas.eixample.name']}
70-
</h3>
71-
<p class="text-pycon-gray-25 text-sm leading-relaxed">{t['accommodation.areas.eixample.desc']}</p>
72-
</div>
73-
<div
74-
class="bg-pycon-black/40 p-8 rounded-2xl border border-white/5 hover:border-pycon-orange/50 transition-all hover:-translate-y-2 text-center"
75-
>
76-
<h3 class="text-xl font-bold text-pycon-orange mb-4 italic">
77-
{t['accommodation.areas.gothic.name']}
78-
</h3>
79-
<p class="text-pycon-gray-25 text-sm leading-relaxed">{t['accommodation.areas.gothic.desc']}</p>
80-
</div>
81-
<div
82-
class="bg-pycon-black/40 p-8 rounded-2xl border border-white/5 hover:border-pycon-orange/50 transition-all hover:-translate-y-2 text-right"
83-
>
84-
<h3 class="text-xl font-bold text-pycon-orange mb-4 italic">
85-
{t['accommodation.areas.poblenou.name']}
86-
</h3>
87-
<p class="text-pycon-gray-25 text-sm leading-relaxed">{t['accommodation.areas.poblenou.desc']}</p>
88-
</div>
89-
</div>
90-
</section>
91-
92134
<!-- Apartments -->
93135
<section
94136
class="bg-linear-to-r from-pycon-red/20 to-pycon-orange/20 p-8 md:p-16 rounded-3xl border border-pycon-red/30"
137+
aria-labelledby="accommodation-apartments-heading"
95138
>
96139
<div class="flex flex-col md:flex-row gap-12 items-center">
97140
<div class="flex-1">
98-
<h2 class="text-3xl font-bold text-white mb-6 uppercase tracking-tight">
141+
<h2
142+
id="accommodation-apartments-heading"
143+
class="text-3xl font-bold text-white mb-6 uppercase tracking-tight"
144+
>
99145
{t['accommodation.apartments.title']}
100146
</h2>
101147
<p class="text-pycon-gray-25 text-lg mb-8 leading-relaxed">
102148
{t['accommodation.apartments.text']}
103149
</p>
104150
<a
105-
href="https://meet.barcelona/es/alojarse-en-barcelona"
151+
href={t['accommodation.apartments.linkUrl']}
106152
target="_blank"
107153
rel="noopener noreferrer"
108154
aria-label={`${t['accommodation.apartments.link']} ${menuT.new_tab}`}
109155
class="inline-flex items-center gap-2 bg-white text-pycon-red font-bold px-6 py-3 rounded-lg hover:scale-105 transition-transform no-underline"
110156
>
111157
{t['accommodation.apartments.link']}
112-
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"
158+
<span class="sr-only"> ({t['accommodation.a11y.linkOpensNewTab']})</span>
159+
<svg
160+
class="w-5 h-5 shrink-0"
161+
fill="none"
162+
stroke="currentColor"
163+
viewBox="0 0 24 24"
164+
aria-hidden="true"
113165
><path
114166
stroke-linecap="round"
115167
stroke-linejoin="round"
@@ -120,8 +172,9 @@ const t = accommodationTexts[lang as keyof typeof accommodationTexts]
120172
</div>
121173
<div
122174
class="w-48 h-48 bg-white/10 rounded-full flex items-center justify-center border border-white/20 shadow-2xl backdrop-blur-xl shrink-0"
175+
aria-hidden="true"
123176
>
124-
<StatusIcon type="city" size="xl" role="img" aria-label="Ubicación" />
177+
<StatusIcon type="city" size="xl" />
125178
</div>
126179
</div>
127180
</section>
@@ -142,4 +195,10 @@ const t = accommodationTexts[lang as keyof typeof accommodationTexts]
142195
transform: translateY(0);
143196
}
144197
}
198+
199+
@media (prefers-reduced-motion: reduce) {
200+
.accommodation-container {
201+
animation: none;
202+
}
203+
}
145204
</style>

src/components/Button.astro

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ const sizes = {
2424
}
2525
2626
const baseClasses =
27-
"inline-flex items-center justify-center font-['Outfit'] font-medium rounded-lg text-center transition-colors duration-200 cursor-pointer"
27+
'inline-flex items-center justify-center font-medium rounded-lg text-center transition-colors duration-200 cursor-pointer'
2828
2929
const Element = href ? 'a' : 'button'
3030
---

src/components/LocationPage.astro

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ const transportIcons = {
1919

2020
<div class="location-container pb-20">
2121
<!-- Hero Section -->
22-
<section class="relative h-[60vh] min-h-[400px] w-full overflow-hidden rounded-3xl mb-12 shadow-2xl">
22+
<section class="relative h-[40vh] min-h-10 w-full overflow-hidden rounded-3xl mb-12 shadow-2xl">
2323
<img
2424
src="/images/Barcelona/seuUB.jpg"
2525
alt={t['location.hero.title']}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
---
2+
import { texts } from '../../i18n/home'
3+
import SectionTitle from '../SectionTitle.astro'
4+
import Button from '../Button.astro'
5+
6+
interface Props {
7+
lang: string
8+
}
9+
10+
const { lang } = Astro.props
11+
const t = texts[lang as keyof typeof texts]
12+
---
13+
14+
<div class="flex flex-col items-center gap-6">
15+
<SectionTitle title={t['cfp.title']} />
16+
17+
<div
18+
class="bg-white/5 backdrop-blur-md p-8 rounded-2xl border border-white/10 hover:border-pycon-orange/50 transition-all shadow-xl w-full"
19+
>
20+
<p class="text-lg text-pycon-gray-25 leading-relaxed mb-6 text-center">
21+
{t['cfp.description']}
22+
</p>
23+
24+
<div class="flex justify-center">
25+
<Button
26+
variant="primary"
27+
size="lg"
28+
href="https://pretalx.com/pycones-2026/cfp"
29+
target="_blank"
30+
rel="noopener noreferrer"
31+
>
32+
{t['cfp.button']}
33+
</Button>
34+
</div>
35+
</div>
36+
</div>

src/components/index.astro

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
---
22
import Layout from '@/layouts/Layout.astro'
33
import SectionMain from './home/SectionMain.astro'
4+
import SectionCallForProposals from './home/SectionCallForProposals.astro'
45
import SectionSponsors from './home/SectionSponsors.astro'
56
67
interface Props {
@@ -13,6 +14,7 @@ const { lang } = Astro.props
1314
<Layout title="PyConES 2026">
1415
<div class="flex flex-col gap-20">
1516
<SectionMain lang={lang} />
17+
<SectionCallForProposals lang={lang} />
1618
<SectionSponsors lang={lang} />
1719
</div>
1820
</Layout>

src/i18n/accommodation/ca.ts

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,55 @@ export const ca = {
22
'accommodation.title': 'Allotjament',
33
'accommodation.hero.title': 'On allotjar-se',
44
'accommodation.hero.subtitle': 'Recomanacions per a la teva estada a Barcelona',
5-
'accommodation.intro':
6-
"Barcelona és una de les ciutats amb més oferta hotelera d'Europa. Per a la PyConES 2026, recomanem buscar allotjament al districte de l'Eixample o a Ciutat Vella per estar a pocs minuts a peu de la seu (UB Edifici Històric).",
75
'accommodation.hotels.title': 'Hotels Recomanats',
86
'accommodation.hotels.subtitle': 'Convenis i opcions properes',
97
'accommodation.hotels.disclaimer':
108
'Estem treballant per tancar convenis exclusius amb descomptes per als assistents. Torna aviat per veure els codis promocionals!',
119
'accommodation.areas.title': 'Millors Zones',
12-
'accommodation.areas.eixample.name': "L'Eixample",
13-
'accommodation.areas.eixample.desc':
14-
'La zona més segura i elegant, amb arquitectura modernista i a un pas de la seu.',
15-
'accommodation.areas.gothic.name': 'Barri Gòtic',
16-
'accommodation.areas.gothic.desc':
17-
'El centre històric, amb carrers màgics i molta vida nocturna, a 10 min de la UB.',
18-
'accommodation.areas.poblenou.name': 'Poblenou / 22@',
19-
'accommodation.areas.poblenou.desc':
20-
'El hub tecnològic. Un poc més allunyat però molt ben connectat per metro (L1).',
10+
'accommodation.areas.transportIntro.p1':
11+
'Si has de tornar a casa en tren, les millors opcions són Sants, Eixample Esquerra o Les Corts (per anar a Sants Estació).',
12+
'accommodation.areas.transportIntro.p2':
13+
"Si tornes en avió, et recomanem els barris d'El Raval, Sant Antoni, Eixample Esquerra (Aerobús), Sants (tren Rodalies R2) o Les Corts i Collblanc (L9 Sud). Tanmateix hi ha una parada de l'autobús directe a l'aeroport (Aerobús) davant de la seu.",
14+
'accommodation.areas.transportIntro.p3':
15+
'Tindrem servei de consigna, així que si marxes el diumenge pots fer check-out i deixar les maletes aquí.',
16+
'accommodation.areas.category.walking': 'A peu',
17+
'accommodation.areas.category.directMetro': 'Metro directe',
18+
'accommodation.areas.category.transferMetro': 'Metro amb transbord',
19+
'accommodation.areas.eixampleEsquerra.name': 'Eixample Esquerra',
20+
'accommodation.areas.eixampleEsquerra.desc':
21+
"Costat esquerre de l'eixample, modernista i molt a prop de la UB a peu; bona opció si també fas servir Sants.",
22+
'accommodation.areas.elRaval.name': 'El Raval',
23+
'accommodation.areas.elRaval.desc':
24+
'Barri cèntric i multicultural, a poca distància a peu de la seu; l’Aerobús enllaça bé amb l’aeroport.',
25+
'accommodation.areas.santAntoni.name': 'Sant Antoni',
26+
'accommodation.areas.santAntoni.desc':
27+
'Mercat i terrasses, ambient de barri i una passejada còmoda fins a la universitat.',
28+
'accommodation.areas.ciutatVella.name': 'Ciutat Vella',
29+
'accommodation.areas.ciutatVella.desc':
30+
'Nucli històric (Gòtic, Born…): ambient únic i ubicacions a prop de l’esdeveniment.',
31+
'accommodation.areas.sants.name': 'Sants',
32+
'accommodation.areas.sants.desc':
33+
'Al costat de l’estació de Sants: ideal per trens de llarg recorregut i Rodalies cap a l’aeroport.',
34+
'accommodation.areas.poblenou22.name': 'Poblenou / 22@',
35+
'accommodation.areas.poblenou22.desc':
36+
'Districte 22@ i platja; ben connectat per metro en línia directa al centre i la UB.',
37+
'accommodation.areas.elClot.name': 'El Clot',
38+
'accommodation.areas.elClot.desc':
39+
'Barri consolidat amb bon accés en metro directe al centre on hi ha la seu.',
40+
'accommodation.areas.lesCorts.name': 'Les Corts',
41+
'accommodation.areas.lesCorts.desc':
42+
'A prop de la L9 Sud a l’aeroport; per arribar a la seu sol cal transbord en metro.',
43+
'accommodation.areas.eixampleDreta.name': 'Eixample Dreta',
44+
'accommodation.areas.eixampleDreta.desc':
45+
'Eixample dret: emblemàtic i ben comunicat, amb enllaços que sovint impliquen una correspondència.',
46+
'accommodation.areas.collblanc.name': 'Collblanc',
47+
'accommodation.areas.collblanc.desc':
48+
'L9 Sud a l’aeroport; per arribar a la UB normalment faràs transbord.',
2149
'accommodation.apartments.title': 'Apartaments Turístics',
2250
'accommodation.apartments.text':
2351
"Si prefereixes un apartament, assegura't que compti amb llicència turística oficial (HUTB). Barcelona és molt estricta amb la regulació d'allotjaments.",
2452
'accommodation.apartments.link': "Veure guia d'allotjament segur a Barcelona",
53+
'accommodation.apartments.linkUrl': 'https://meet.barcelona.cat/habitatgesturistics/ca',
54+
'accommodation.a11y.constructionIcon': 'En construcció',
55+
'accommodation.a11y.linkOpensNewTab': "s'obre en una pestanya nova",
2556
} as const

0 commit comments

Comments
 (0)