/* global React, Icon, useT */
const { useState: useStateSp, useEffect: useEffectSp } = React;
/* ============== DATA ============== */
const ROOMS_DATA = [
{ id:'h01', n:'01', img:'img/hab-01.jpeg', tint:'#FFE4E0',
floor:'pb', size:'r01_size', bath:'bath_private', cap:2, bed:'bed_twin',
hk:'r01_h', subk:'r01_sub', dk:'r01_d',
feat:['r01_f1','r01_f2','r01_f3','r01_f4','r01_f5'] },
{ id:'h02', n:'02', img:'img/hab-02.jpeg', tint:'#F2EBDB',
floor:'p1', size:'r02_size', bath:'bath_private', cap:2, bed:'bed_double',
hk:'r02_h', subk:'r02_sub', dk:'r02_d',
feat:['r02_f1','r02_f2','r02_f3','r02_f4'] },
{ id:'h03', n:'03', img:'img/hab-03.jpeg', tint:'#E5EAE0',
floor:'p1', size:'r03_size', bath:'bath_shared_05', cap:2, bed:'bed_double',
hk:'r03_h', subk:'r03_sub', dk:'r03_d',
feat:['r03_f3','r03_f4','r03_f5'] },
{ id:'h04', n:'04', img:'img/hab-04.jpeg', tint:'#FFF3B8',
floor:'p1', size:'r04_size', bath:'bath_private', cap:2, bed:'bed_double',
hk:'r04_h', subk:'r04_sub', dk:'r04_d',
feat:['r04_f1','r04_f2','r04_f3','r04_f4','r04_f5'] },
{ id:'h05', n:'05', img:'img/hab-05.jpeg', tint:'#F4F1EC',
floor:'p1', size:'r05_size', bath:'bath_shared_03', cap:2, bed:'bed_double',
hk:'r05_h', subk:'r05_sub', dk:'r05_d',
feat:['r05_f1','r05_f2','r05_f3','r05_f4','r05_f5'] },
];
const COMMON_DATA = [
{ id:'kitchen', img:'img/cocina-comedor.jpeg', icon:'coffee',
hk:'c_kitchen_h', subk:'c_kitchen_sub', dk:'c_kitchen_d', eqk:'c_kitchen_eq', notek:'c_kitchen_note' },
{ id:'lounge', img:'img/salon-02.jpeg', icon:'tv',
hk:'c_lounge_h', subk:'c_lounge_sub', dk:'c_lounge_d', eqk:'c_lounge_eq' },
{ id:'patio', img:'img/patio.jpeg', icon:'leaf',
hk:'c_patio_h', subk:'c_patio_sub', dk:'c_patio_d', eqk:'c_patio_eq' },
{ id:'attic', img:'img/bajo-cubierta.jpeg', icon:'sun',
hk:'c_attic_h', subk:'c_attic_sub', dk:'c_attic_d', eqk:'c_attic_eq' },
{ id:'baths', img:'img/bano.jpeg', icon:'bath',
hk:'c_baths_h', subk:'c_baths_sub', dk:'c_baths_d', eqk:'c_baths_eq' },
{ id:'access', img:'img/fachada.jpeg', icon:'key',
hk:'c_access_h', subk:'c_access_sub', dk:'c_access_d', eqk:'c_access_eq' },
];
/* ============== HEADER ============== */
function SpacesHeader() {
const { t } = useT();
return (
{t('sf_back')}
{t('sf_eyebrow')}
{t('sf_h1_a')} {t('sf_h1_b')}
{t('sf_lede')}
);
}
const SH = {
wrap:{ background:'#1A1A1A', color:'#fff', padding:'72px 28px 80px' },
inner:{ maxWidth:1280, margin:'0 auto' },
back:{ display:'inline-flex', alignItems:'center', gap:8, fontFamily:'Montserrat, sans-serif', fontWeight:700,
fontSize:12, letterSpacing:'.15em', textTransform:'uppercase', color:'#F5C801',
textDecoration:'none', marginBottom:32 },
eyebrow:{ fontFamily:'Montserrat, sans-serif', fontWeight:700, fontSize:12, letterSpacing:'.25em', textTransform:'uppercase', color:'#F5C801' },
h1:{ color:'#fff', fontFamily:'Montserrat, sans-serif', fontWeight:900, fontSize:'clamp(40px,5vw,76px)', lineHeight:.95,
letterSpacing:'-0.02em', margin:'18px 0 22px', textTransform:'uppercase' },
lede:{ fontFamily:'Inter, sans-serif', fontSize:'clamp(15px,1.2vw,18px)', maxWidth:680, lineHeight:1.55,
margin:0, color:'#D9D9D9' },
};
/* ============== TOC ============== */
function TOC() {
const { t } = useT();
return (
);
}
const TC = {
wrap:{ borderBottom:'1px solid #ECECEC', background:'#FAFAFA' },
inner:{ maxWidth:1280, margin:'0 auto', padding:'40px 28px' },
label:{ fontFamily:'Montserrat, sans-serif', fontWeight:700, fontSize:11, letterSpacing:'.25em',
textTransform:'uppercase', color:'#6B6B6B', marginBottom:18 },
cols:{ display:'grid', gridTemplateColumns:'1fr 1.5fr', gap:36 },
col:{},
colH:{ fontFamily:'Montserrat, sans-serif', fontWeight:800, fontSize:13, letterSpacing:'.1em',
textTransform:'uppercase', color:'#1A1A1A', marginBottom:14, paddingBottom:8, borderBottom:'1px solid #ECECEC' },
ul:{ listStyle:'none', padding:0, margin:0, display:'grid', gridTemplateColumns:'1fr 1fr', gap:'10px 16px' },
link:{ display:'flex', alignItems:'center', gap:10, textDecoration:'none', color:'#2B2B2B',
fontFamily:'Inter, sans-serif', fontSize:14, lineHeight:1.3 },
num:{ flex:'0 0 auto', fontFamily:'ui-monospace, monospace', fontSize:11, color:'#FBB700',
background:'#1A1A1A', padding:'2px 6px', borderRadius:4 },
};
/* ============== ROOM CARD ============== */
function RoomCard({ room, alt, withCta }) {
const { t, lang } = useT();
const floorTxt = room.floor === 'pb' ? t('floor_pb') : t('floor_p1');
const capTxt = room.cap === 1 ? t('sf_capacity_1') : t('sf_capacity_n').replace('{n}', room.cap);
const ctaLabel = ({ es:`Reservar habitación ${room.n}`, en:`Book Room ${room.n}`, fr:`Réserver Chambre ${room.n}` }[lang]) || `Reservar habitación ${room.n}`;
const detailLabel = ({ es:'Ver ficha completa', en:'See full sheet', fr:'Voir la fiche' }[lang]) || 'Ver ficha completa';
return (
{room.n}
{t(room.hk)}
{t(room.subk)}
{t(room.dk)}
{t('sf_lbl_features')}
{room.feat.map(f => (
{t(f)}
))}
{withCta && (
)}
);
}
function Spec({ k, v }) {
return (
{k}
{v}
);
}
const RC = {
wrap:{ display:'flex', gap:48, alignItems:'stretch', padding:'56px 0', borderBottom:'1px solid #ECECEC' },
imgWrap:{ flex:'0 0 46%', position:'relative', borderRadius:18, overflow:'hidden',
aspectRatio:'4/5', background:'#F4F4F4' },
img:{ position:'absolute', inset:0, width:'100%', height:'100%', objectFit:'cover' },
numTag:{ position:'absolute', top:18, left:18, fontFamily:'Montserrat, sans-serif', fontWeight:900,
fontSize:30, padding:'4px 14px', color:'#1A1A1A', borderRadius:6, letterSpacing:'-0.02em' },
body:{ flex:1, display:'flex', flexDirection:'column' },
h2:{ fontFamily:'Montserrat, sans-serif', fontWeight:900, fontSize:'clamp(28px,3.2vw,44px)',
lineHeight:1, letterSpacing:'-0.02em', margin:'0 0 8px', textTransform:'uppercase', color:'#1A1A1A' },
sub:{ fontFamily:'Montserrat, sans-serif', fontWeight:700, fontSize:13, letterSpacing:'.1em',
textTransform:'uppercase', color:'#FBB700', marginBottom:18 },
desc:{ fontFamily:'Inter, sans-serif', fontSize:16, lineHeight:1.6, color:'#2B2B2B',
margin:'0 0 24px', maxWidth:560 },
specs:{ display:'grid', gridTemplateColumns:'repeat(2, 1fr)', gap:'14px 24px',
margin:'0 0 28px', padding:'18px 20px', background:'#FAFAFA', borderRadius:12, border:'1px solid #ECECEC' },
specItem:{ margin:0 },
specK:{ fontFamily:'Montserrat, sans-serif', fontWeight:700, fontSize:10, letterSpacing:'.15em',
textTransform:'uppercase', color:'#9A9A9A', marginBottom:3 },
specV:{ margin:0, fontFamily:'Inter, sans-serif', fontSize:14, color:'#1A1A1A', fontWeight:500, lineHeight:1.4 },
featLabel:{ fontFamily:'Montserrat, sans-serif', fontWeight:700, fontSize:11, letterSpacing:'.15em',
textTransform:'uppercase', color:'#1A1A1A', marginBottom:12 },
feat:{ listStyle:'none', padding:0, margin:0, display:'flex', flexDirection:'column', gap:8 },
featLi:{ display:'flex', gap:10, alignItems:'flex-start', fontFamily:'Inter, sans-serif',
fontSize:14, color:'#2B2B2B', lineHeight:1.5 },
featDot:{ flex:'0 0 auto', width:6, height:6, borderRadius:'50%', background:'#F5C801', marginTop:7 },
ctaRow:{ display:'flex', flexWrap:'wrap', gap:14, alignItems:'center', marginTop:28 },
ctaPrimary:{ display:'inline-flex', alignItems:'center', gap:8, background:'#1A1A1A', color:'#F5C801',
padding:'14px 22px', borderRadius:999, textDecoration:'none',
fontFamily:'Montserrat, sans-serif', fontWeight:800, fontSize:13,
letterSpacing:'.08em', textTransform:'uppercase' },
ctaGhost:{ display:'inline-flex', alignItems:'center', gap:8, color:'#1A1A1A',
padding:'12px 4px', textDecoration:'none', borderBottom:'1px solid #1A1A1A',
fontFamily:'Montserrat, sans-serif', fontWeight:700, fontSize:12,
letterSpacing:'.12em', textTransform:'uppercase' },
};
/* ============== COMMON CARD ============== */
function CommonCard({ space, alt }) {
const { t, lang } = useT();
const equipment = (I18N[lang] && I18N[lang][space.eqk]) || I18N.es[space.eqk] || [];
return (
{t(space.hk)}
{t(space.subk)}
{t(space.dk)}
{t('sf_lbl_equipment')}
{equipment.map((line,i) => (
{line}
))}
{space.notek &&
{t(space.notek)}
}
);
}
const CC = {
wrap:{ display:'flex', gap:48, alignItems:'stretch', padding:'56px 0', borderBottom:'1px solid #ECECEC' },
imgWrap:{ flex:'0 0 50%', position:'relative', borderRadius:18, overflow:'hidden',
aspectRatio:'4/3', background:'#F4F4F4' },
img:{ position:'absolute', inset:0, width:'100%', height:'100%', objectFit:'cover' },
iconBadge:{ position:'absolute', top:18, left:18, width:42, height:42, background:'#F5C801', color:'#1A1A1A',
display:'flex', alignItems:'center', justifyContent:'center', borderRadius:12,
boxShadow:'0 4px 12px rgba(0,0,0,.15)' },
body:{ flex:1, display:'flex', flexDirection:'column' },
h2:{ fontFamily:'Montserrat, sans-serif', fontWeight:900, fontSize:'clamp(28px,3.2vw,44px)',
lineHeight:1, letterSpacing:'-0.02em', margin:'0 0 8px', textTransform:'uppercase', color:'#1A1A1A' },
sub:{ fontFamily:'Montserrat, sans-serif', fontWeight:700, fontSize:13, letterSpacing:'.1em',
textTransform:'uppercase', color:'#FBB700', marginBottom:18 },
desc:{ fontFamily:'Inter, sans-serif', fontSize:16, lineHeight:1.6, color:'#2B2B2B',
margin:'0 0 28px', maxWidth:560 },
eqLabel:{ fontFamily:'Montserrat, sans-serif', fontWeight:700, fontSize:11, letterSpacing:'.15em',
textTransform:'uppercase', color:'#1A1A1A', marginBottom:12 },
eq:{ listStyle:'none', padding:0, margin:0, display:'grid', gridTemplateColumns:'1fr 1fr', gap:'8px 18px' },
eqLi:{ display:'flex', gap:8, alignItems:'flex-start', fontFamily:'Inter, sans-serif',
fontSize:13.5, color:'#2B2B2B', lineHeight:1.5 },
note:{ margin:'18px 0 0', fontFamily:'Inter, sans-serif', fontSize:14, fontStyle:'italic',
color:'#6B6B6B', lineHeight:1.55 },
};
/* ============== SECTION HEADERS ============== */
function SectionHeader({ eyebrowK, hK, pK, dark }) {
const { t } = useT();
return (
{t(eyebrowK)}
{t(hK)}
{t(pK)}
);
}
const SX = {
wrap:{ padding:'80px 0 60px' },
inner:{ maxWidth:1280, margin:'0 auto', padding:'0 28px', maxWidth:780 },
eyebrow:{ fontFamily:'Montserrat, sans-serif', fontWeight:700, fontSize:12, letterSpacing:'.25em', textTransform:'uppercase' },
h2:{ fontFamily:'Montserrat, sans-serif', fontWeight:900, fontSize:'clamp(36px,4.2vw,58px)', lineHeight:1,
letterSpacing:'-0.02em', margin:'16px 0 18px', textTransform:'uppercase' },
p:{ fontFamily:'Inter, sans-serif', fontSize:17, lineHeight:1.55, margin:0 },
};
/* ============== APP ============== */
function SpacesApp() {
return (
{COMMON_DATA.map((c,i) => )}
{ROOMS_DATA.map((r,i) => )}
);
}
window.SpacesApp = SpacesApp;
/* ============== ROOMS-ONLY APP ============== */
function RoomsHeader() {
const { t, lang } = useT();
const L = {
es: { eyebrow:'Habitaciones', h1a:'5 habitaciones,', h1b:'5 maneras de dormir.', lede:'Cada habitación tiene su carácter — desde la planta baja adaptada hasta la abuhardillada bajo cubierta. Mira los detalles y reserva la que mejor te encaje.' },
en: { eyebrow:'Rooms', h1a:'5 rooms,', h1b:'5 ways to sleep.', lede:'Each room has its own character — from the accessible ground-floor to the attic. Check the details and book the one that fits you.' },
fr: { eyebrow:'Chambres', h1a:'5 chambres,', h1b:'5 façons de dormir.', lede:'Chaque chambre a son caractère — du rez-de-chaussée adapté à la mansarde. Consulte les détails et réserve celle qui te convient.' },
};
const C = L[lang] || L.es;
return (
);
}
function RoomsApp() {
return (
{ROOMS_DATA.map((r,i) => )}
);
}
window.RoomsApp = RoomsApp;