Initial commit with LFS
1
.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
*.mp4 filter=lfs diff=lfs merge=lfs -text
|
||||||
1
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{}
|
||||||
117
src/assets/css/style.css
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
:root {
|
||||||
|
--bg: #fff;
|
||||||
|
--fg: #222;
|
||||||
|
--accent: #007acc;
|
||||||
|
}
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
:root {
|
||||||
|
--bg: #111;
|
||||||
|
--fg: #eee;
|
||||||
|
--accent: #46c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Explicit “.dark” toggle override */
|
||||||
|
html.dark {
|
||||||
|
--bg: #111;
|
||||||
|
--fg: #eee;
|
||||||
|
--accent: #46c;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
font-family: sans-serif;
|
||||||
|
background-color: var(--bg);
|
||||||
|
color: var(--fg);
|
||||||
|
}
|
||||||
|
.lightbox-open {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.site-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 1rem;
|
||||||
|
background: var(--bg);
|
||||||
|
border-bottom: 1px solid #ccc;
|
||||||
|
}
|
||||||
|
.emoji-button {
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
cursor: pointer;
|
||||||
|
color: var(--accent);
|
||||||
|
}
|
||||||
|
.gallery-grid {
|
||||||
|
column-count: 1;
|
||||||
|
column-gap: 1rem;
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.gallery-grid { column-count: 2; }
|
||||||
|
}
|
||||||
|
@media (min-width: 1024px) {
|
||||||
|
.gallery-grid { column-count: 3; }
|
||||||
|
}
|
||||||
|
.gallery-item {
|
||||||
|
margin: 0 0 1rem;
|
||||||
|
position: relative;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.gallery-item img {
|
||||||
|
width: 100%;
|
||||||
|
display: block;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
.gallery-item figcaption {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
padding: 0.5rem;
|
||||||
|
background: rgba(0,0,0,0.6);
|
||||||
|
color: #fff;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.2s;
|
||||||
|
}
|
||||||
|
.gallery-item:focus figcaption,
|
||||||
|
.gallery-item:hover figcaption {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
#lightbox {
|
||||||
|
position: fixed;
|
||||||
|
top:0; left:0; right:0; bottom:0;
|
||||||
|
background: rgba(0,0,0,0.9);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
visibility: hidden;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.3s;
|
||||||
|
}
|
||||||
|
#lightbox[aria-hidden="false"] {
|
||||||
|
visibility: visible;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
#lb-content img,
|
||||||
|
#lb-content video {
|
||||||
|
max-width: 90vw;
|
||||||
|
max-height: 80vh;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
#lb-caption {
|
||||||
|
color: #fff;
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
text-align: center;
|
||||||
|
max-width: 90vw;
|
||||||
|
}
|
||||||
|
#lb-close {
|
||||||
|
position: absolute;
|
||||||
|
top: 1rem;
|
||||||
|
right: 1rem;
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
font-size: 2rem;
|
||||||
|
color: #fff;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
97
src/assets/js/script.js
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
// --- theme toggle (unchanged) ---
|
||||||
|
const toggle = document.getElementById('theme-toggle');
|
||||||
|
const root = document.documentElement;
|
||||||
|
const saved = localStorage.getItem('dark-mode');
|
||||||
|
const sysDark= window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||||
|
if (saved==='true' || (saved===null && sysDark)) root.classList.add('dark');
|
||||||
|
toggle.addEventListener('click', ()=>{
|
||||||
|
const isDark = root.classList.toggle('dark');
|
||||||
|
localStorage.setItem('dark-mode', isDark);
|
||||||
|
});
|
||||||
|
|
||||||
|
const body = document.body;
|
||||||
|
|
||||||
|
// --- lightbox base ---
|
||||||
|
const lb = document.getElementById('lightbox');
|
||||||
|
const lbCnt = document.getElementById('lb-content');
|
||||||
|
const lbCap = document.getElementById('lb-caption');
|
||||||
|
document.getElementById('lb-close')
|
||||||
|
.addEventListener('click', ()=>{
|
||||||
|
lb.setAttribute('aria-hidden','true');
|
||||||
|
body.classList.remove('lightbox-open');
|
||||||
|
lbCnt.innerHTML='';
|
||||||
|
});
|
||||||
|
|
||||||
|
// --- build gallery ---
|
||||||
|
const gallery = document.getElementById('gallery');
|
||||||
|
const mediaData= JSON.parse(document.getElementById('media-data').textContent);
|
||||||
|
|
||||||
|
const createPicture = (item) => {
|
||||||
|
const pic = document.createElement('picture');
|
||||||
|
['desktop','tablet','mobile'].forEach(bp=>{
|
||||||
|
const src = document.createElement('source');
|
||||||
|
const widthQuery = bp==='desktop'?1024: bp==='tablet'?768: 0;
|
||||||
|
src.media = `(min-width:${widthQuery}px)`;
|
||||||
|
if(item.type==='image'){
|
||||||
|
src.srcset =
|
||||||
|
`assets/media/${bp}/${item.name}@1x.webp 1x, ` +
|
||||||
|
`assets/media/${bp}/${item.name}.webp 2x`;
|
||||||
|
} else {
|
||||||
|
// video poster still
|
||||||
|
src.srcset =
|
||||||
|
`assets/media/${bp}/${item.name}_still@1x.webp 1x, ` +
|
||||||
|
`assets/media/${bp}/${item.name}_still.webp 2x`;
|
||||||
|
}
|
||||||
|
pic.appendChild(src);
|
||||||
|
});
|
||||||
|
|
||||||
|
// thumbnail fallback (always 300px/2×)
|
||||||
|
const img = document.createElement('img');
|
||||||
|
img.src = `assets/media/thumbnail/${item.name}.webp`;
|
||||||
|
img.alt = item.alt.replace(/[‘’]/g,'');
|
||||||
|
pic.appendChild(img);
|
||||||
|
return pic;
|
||||||
|
};
|
||||||
|
|
||||||
|
mediaData.forEach(item=>{
|
||||||
|
const fig = document.createElement('figure');
|
||||||
|
fig.className = `gallery-item${item.type==='video'?' video':''}`;
|
||||||
|
fig.tabIndex = 0;
|
||||||
|
fig.dataset.name = item.name;
|
||||||
|
fig.dataset.type = item.type;
|
||||||
|
fig.dataset.caption = item.caption;
|
||||||
|
fig.appendChild(createPicture(item));
|
||||||
|
|
||||||
|
// overlay caption
|
||||||
|
const cap = document.createElement('figcaption');
|
||||||
|
cap.textContent = item.caption;
|
||||||
|
fig.appendChild(cap);
|
||||||
|
|
||||||
|
// events
|
||||||
|
fig.addEventListener('click', ()=> openLightbox(item));
|
||||||
|
fig.addEventListener('keypress', e=> e.key==='Enter' && openLightbox(item));
|
||||||
|
|
||||||
|
gallery.appendChild(fig);
|
||||||
|
});
|
||||||
|
|
||||||
|
// --- video toggle ---
|
||||||
|
const videoTgl = document.getElementById('show_video');
|
||||||
|
videoTgl.addEventListener('click', ()=>{
|
||||||
|
openLightbox(mediaData.find(i=>i.type==='video'));
|
||||||
|
});
|
||||||
|
|
||||||
|
function openLightbox(item){
|
||||||
|
lbCnt.innerHTML = '';
|
||||||
|
if(item.type==='video'){
|
||||||
|
const v = document.createElement('video');
|
||||||
|
v.src = `assets/media/videos/${item.name}.mp4`;
|
||||||
|
v.controls = true;
|
||||||
|
v.autoplay = true;
|
||||||
|
lbCnt.appendChild(v);
|
||||||
|
} else {
|
||||||
|
lbCnt.appendChild(createPicture(item));
|
||||||
|
}
|
||||||
|
lbCap.textContent = item.caption;
|
||||||
|
body.classList.add('lightbox-open');
|
||||||
|
lb.setAttribute('aria-hidden','false');
|
||||||
|
}
|
||||||
BIN
src/assets/media/desktop/backyard_parking.webp
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
src/assets/media/desktop/backyard_parking@1x.webp
Normal file
|
After Width: | Height: | Size: 347 KiB |
BIN
src/assets/media/desktop/bedroom_suite_1.webp
Normal file
|
After Width: | Height: | Size: 826 KiB |
BIN
src/assets/media/desktop/bedroom_suite_1@1x.webp
Normal file
|
After Width: | Height: | Size: 130 KiB |
BIN
src/assets/media/desktop/bedroom_suite_2.webp
Normal file
|
After Width: | Height: | Size: 903 KiB |
BIN
src/assets/media/desktop/bedroom_suite_2@1x.webp
Normal file
|
After Width: | Height: | Size: 146 KiB |
BIN
src/assets/media/desktop/bedroom_suite_3.webp
Normal file
|
After Width: | Height: | Size: 637 KiB |
BIN
src/assets/media/desktop/bedroom_suite_3@1x.webp
Normal file
|
After Width: | Height: | Size: 100 KiB |
BIN
src/assets/media/desktop/coat_closet.webp
Normal file
|
After Width: | Height: | Size: 630 KiB |
BIN
src/assets/media/desktop/coat_closet@1x.webp
Normal file
|
After Width: | Height: | Size: 92 KiB |
BIN
src/assets/media/desktop/deck_1.webp
Normal file
|
After Width: | Height: | Size: 494 KiB |
BIN
src/assets/media/desktop/deck_1@1x.webp
Normal file
|
After Width: | Height: | Size: 135 KiB |
BIN
src/assets/media/desktop/deck_2.webp
Normal file
|
After Width: | Height: | Size: 618 KiB |
BIN
src/assets/media/desktop/deck_2@1x.webp
Normal file
|
After Width: | Height: | Size: 167 KiB |
BIN
src/assets/media/desktop/exterior.webp
Normal file
|
After Width: | Height: | Size: 294 KiB |
BIN
src/assets/media/desktop/exterior@1x.webp
Normal file
|
After Width: | Height: | Size: 142 KiB |
BIN
src/assets/media/desktop/guest_bath.webp
Normal file
|
After Width: | Height: | Size: 315 KiB |
BIN
src/assets/media/desktop/guest_bath@1x.webp
Normal file
|
After Width: | Height: | Size: 85 KiB |
BIN
src/assets/media/desktop/kitchen.webp
Normal file
|
After Width: | Height: | Size: 373 KiB |
BIN
src/assets/media/desktop/kitchen@1x.webp
Normal file
|
After Width: | Height: | Size: 64 KiB |
BIN
src/assets/media/desktop/laundry.webp
Normal file
|
After Width: | Height: | Size: 1005 KiB |
BIN
src/assets/media/desktop/laundry@1x.webp
Normal file
|
After Width: | Height: | Size: 188 KiB |
BIN
src/assets/media/desktop/living_room_1.webp
Normal file
|
After Width: | Height: | Size: 538 KiB |
BIN
src/assets/media/desktop/living_room_1@1x.webp
Normal file
|
After Width: | Height: | Size: 113 KiB |
BIN
src/assets/media/desktop/living_room_2.webp
Normal file
|
After Width: | Height: | Size: 748 KiB |
BIN
src/assets/media/desktop/living_room_2@1x.webp
Normal file
|
After Width: | Height: | Size: 144 KiB |
BIN
src/assets/media/desktop/office_fitness_guest_1.webp
Normal file
|
After Width: | Height: | Size: 800 KiB |
BIN
src/assets/media/desktop/office_fitness_guest_1@1x.webp
Normal file
|
After Width: | Height: | Size: 129 KiB |
BIN
src/assets/media/desktop/office_fitness_guest_2.webp
Normal file
|
After Width: | Height: | Size: 770 KiB |
BIN
src/assets/media/desktop/office_fitness_guest_2@1x.webp
Normal file
|
After Width: | Height: | Size: 115 KiB |
BIN
src/assets/media/desktop/office_fitness_guest_3.webp
Normal file
|
After Width: | Height: | Size: 826 KiB |
BIN
src/assets/media/desktop/office_fitness_guest_3@1x.webp
Normal file
|
After Width: | Height: | Size: 126 KiB |
BIN
src/assets/media/desktop/office_fitness_guest_4.webp
Normal file
|
After Width: | Height: | Size: 688 KiB |
BIN
src/assets/media/desktop/office_fitness_guest_4@1x.webp
Normal file
|
After Width: | Height: | Size: 97 KiB |
BIN
src/assets/media/desktop/onsuite_1.webp
Normal file
|
After Width: | Height: | Size: 423 KiB |
BIN
src/assets/media/desktop/onsuite_1@1x.webp
Normal file
|
After Width: | Height: | Size: 72 KiB |
BIN
src/assets/media/desktop/onsuite_2.webp
Normal file
|
After Width: | Height: | Size: 176 KiB |
BIN
src/assets/media/desktop/onsuite_2@1x.webp
Normal file
|
After Width: | Height: | Size: 35 KiB |
BIN
src/assets/media/desktop/tour_still.webp
Normal file
|
After Width: | Height: | Size: 127 KiB |
BIN
src/assets/media/desktop/tour_still@1x.webp
Normal file
|
After Width: | Height: | Size: 59 KiB |
BIN
src/assets/media/mobile/backyard_parking.webp
Normal file
|
After Width: | Height: | Size: 96 KiB |
BIN
src/assets/media/mobile/backyard_parking@1x.webp
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
src/assets/media/mobile/backyard_parking_mobile.webp
Normal file
|
After Width: | Height: | Size: 137 KiB |
BIN
src/assets/media/mobile/bedroom_suite_1.webp
Normal file
|
After Width: | Height: | Size: 37 KiB |
BIN
src/assets/media/mobile/bedroom_suite_1@1x.webp
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
src/assets/media/mobile/bedroom_suite_1_mobile.webp
Normal file
|
After Width: | Height: | Size: 51 KiB |
BIN
src/assets/media/mobile/bedroom_suite_2.webp
Normal file
|
After Width: | Height: | Size: 37 KiB |
BIN
src/assets/media/mobile/bedroom_suite_2@1x.webp
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
src/assets/media/mobile/bedroom_suite_2_mobile.webp
Normal file
|
After Width: | Height: | Size: 52 KiB |
BIN
src/assets/media/mobile/bedroom_suite_3.webp
Normal file
|
After Width: | Height: | Size: 32 KiB |
BIN
src/assets/media/mobile/bedroom_suite_3@1x.webp
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
src/assets/media/mobile/bedroom_suite_3_mobile.webp
Normal file
|
After Width: | Height: | Size: 42 KiB |
BIN
src/assets/media/mobile/coat_closet.webp
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
src/assets/media/mobile/coat_closet@1x.webp
Normal file
|
After Width: | Height: | Size: 9.6 KiB |
BIN
src/assets/media/mobile/coat_closet_mobile.webp
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
src/assets/media/mobile/deck_1.webp
Normal file
|
After Width: | Height: | Size: 43 KiB |
BIN
src/assets/media/mobile/deck_1@1x.webp
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
src/assets/media/mobile/deck_1_mobile.webp
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
src/assets/media/mobile/deck_2.webp
Normal file
|
After Width: | Height: | Size: 54 KiB |
BIN
src/assets/media/mobile/deck_2@1x.webp
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
src/assets/media/mobile/deck_2_mobile.webp
Normal file
|
After Width: | Height: | Size: 74 KiB |
BIN
src/assets/media/mobile/exterior.webp
Normal file
|
After Width: | Height: | Size: 59 KiB |
BIN
src/assets/media/mobile/exterior@1x.webp
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
src/assets/media/mobile/exterior_mobile.webp
Normal file
|
After Width: | Height: | Size: 80 KiB |
BIN
src/assets/media/mobile/guest_bath.webp
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
src/assets/media/mobile/guest_bath@1x.webp
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
src/assets/media/mobile/guest_bath_mobile.webp
Normal file
|
After Width: | Height: | Size: 21 KiB |
BIN
src/assets/media/mobile/kitchen.webp
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
src/assets/media/mobile/kitchen@1x.webp
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
src/assets/media/mobile/kitchen_mobile.webp
Normal file
|
After Width: | Height: | Size: 34 KiB |
BIN
src/assets/media/mobile/laundry.webp
Normal file
|
After Width: | Height: | Size: 56 KiB |
BIN
src/assets/media/mobile/laundry@1x.webp
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
src/assets/media/mobile/laundry_mobile.webp
Normal file
|
After Width: | Height: | Size: 39 KiB |
BIN
src/assets/media/mobile/living_room_1.webp
Normal file
|
After Width: | Height: | Size: 40 KiB |
BIN
src/assets/media/mobile/living_room_1@1x.webp
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
src/assets/media/mobile/living_room_1_mobile.webp
Normal file
|
After Width: | Height: | Size: 54 KiB |
BIN
src/assets/media/mobile/living_room_2.webp
Normal file
|
After Width: | Height: | Size: 45 KiB |
BIN
src/assets/media/mobile/living_room_2@1x.webp
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
src/assets/media/mobile/living_room_2_mobile.webp
Normal file
|
After Width: | Height: | Size: 60 KiB |
BIN
src/assets/media/mobile/office_fitness_guest_1.webp
Normal file
|
After Width: | Height: | Size: 39 KiB |
BIN
src/assets/media/mobile/office_fitness_guest_1@1x.webp
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
src/assets/media/mobile/office_fitness_guest_1_mobile.webp
Normal file
|
After Width: | Height: | Size: 51 KiB |
BIN
src/assets/media/mobile/office_fitness_guest_2.webp
Normal file
|
After Width: | Height: | Size: 38 KiB |
BIN
src/assets/media/mobile/office_fitness_guest_2@1x.webp
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
src/assets/media/mobile/office_fitness_guest_2_mobile.webp
Normal file
|
After Width: | Height: | Size: 50 KiB |
BIN
src/assets/media/mobile/office_fitness_guest_3.webp
Normal file
|
After Width: | Height: | Size: 38 KiB |
BIN
src/assets/media/mobile/office_fitness_guest_3@1x.webp
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
src/assets/media/mobile/office_fitness_guest_3_mobile.webp
Normal file
|
After Width: | Height: | Size: 51 KiB |
BIN
src/assets/media/mobile/office_fitness_guest_4.webp
Normal file
|
After Width: | Height: | Size: 31 KiB |
BIN
src/assets/media/mobile/office_fitness_guest_4@1x.webp
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
src/assets/media/mobile/office_fitness_guest_4_mobile.webp
Normal file
|
After Width: | Height: | Size: 43 KiB |
BIN
src/assets/media/mobile/onsuite_1.webp
Normal file
|
After Width: | Height: | Size: 25 KiB |
BIN
src/assets/media/mobile/onsuite_1@1x.webp
Normal file
|
After Width: | Height: | Size: 8.6 KiB |
BIN
src/assets/media/mobile/onsuite_1_mobile.webp
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
src/assets/media/mobile/onsuite_2.webp
Normal file
|
After Width: | Height: | Size: 14 KiB |