@@ -8,6 +8,24 @@ interface Props {
88
99const { lang } = Astro .props
1010const 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 >
0 commit comments