diff --git a/src/components/projects/ProjectDetail.vue b/src/components/projects/ProjectDetail.vue new file mode 100644 index 0000000..b5ffd19 --- /dev/null +++ b/src/components/projects/ProjectDetail.vue @@ -0,0 +1,87 @@ + + + diff --git a/src/components/projects/ProjectImage.vue b/src/components/projects/ProjectImage.vue new file mode 100644 index 0000000..b47bebf --- /dev/null +++ b/src/components/projects/ProjectImage.vue @@ -0,0 +1,38 @@ + + + diff --git a/src/data/projects.ts b/src/data/projects.ts new file mode 100644 index 0000000..f33eff6 --- /dev/null +++ b/src/data/projects.ts @@ -0,0 +1,155 @@ +export type ImageOrientation = 'landscape' | 'portrait' + +export interface ProjectImage { + src: string + alt: string + orientation: ImageOrientation + /** Tag controlling layout slot in ProjectDetail's editorial scroll. */ + feature?: 'hero' | 'wide' | 'narrow' | 'paired' +} + +export interface Project { + slug: 'boulder' | 'asheville' + name: string + eyebrow: string + intro: string + cover: string + coverAlt: string + images: ProjectImage[] +} + +export const boulder: Project = { + slug: 'boulder', + name: 'Boulder', + eyebrow: 'Light-filled organic', + intro: + 'A mid-century ranch reimagined around warm woods, reclaimed barnwood walls, ' + + 'live-edge counters, and emerald glazed tile. The palette stays in conversation ' + + 'with the trees outside — sunlight does most of the work.', + cover: '/images/boulder/05.jpg', + coverAlt: 'Walnut kitchen with white embossed tile and warm pendant light', + images: [ + { + src: '/images/boulder/03.jpg', + alt: 'Kitchen with reclaimed barnwood walls and live-edge bar top', + orientation: 'landscape', + feature: 'hero', + }, + { + src: '/images/boulder/01.jpg', + alt: 'Oil-rubbed bronze faucet over a quartz counter, reclaimed wood backsplash', + orientation: 'portrait', + feature: 'narrow', + }, + { + src: '/images/boulder/07.jpg', + alt: 'Kitchen alternate angle showing live-edge counter and Asian carving', + orientation: 'landscape', + feature: 'wide', + }, + { + src: '/images/boulder/02.jpg', + alt: 'Dining room with reclaimed barnwood feature wall and rush-seat chairs', + orientation: 'landscape', + feature: 'wide', + }, + { + src: '/images/boulder/08.jpg', + alt: 'Living room with mid-century sofa and emerald tile fireplace surround', + orientation: 'landscape', + feature: 'wide', + }, + { + src: '/images/boulder/05.jpg', + alt: 'Walnut cabinets with white embossed tile and glass pendant', + orientation: 'portrait', + feature: 'narrow', + }, + { + src: '/images/boulder/09.jpg', + alt: 'Bathroom with emerald subway tile shower and walnut vanity', + orientation: 'portrait', + feature: 'paired', + }, + { + src: '/images/boulder/06.jpg', + alt: 'Emerald subway tile shower with bronze fittings and white niche', + orientation: 'landscape', + feature: 'paired', + }, + { + src: '/images/boulder/12.jpg', + alt: 'Walnut bath vanity with reclaimed wood mirror and white tile backsplash', + orientation: 'portrait', + feature: 'narrow', + }, + { + src: '/images/boulder/10.jpg', + alt: 'Rear deck and patio at golden hour with mountain view', + orientation: 'landscape', + feature: 'wide', + }, + { + src: '/images/boulder/11.jpg', + alt: 'Rear deck at dusk with warm lit windows', + orientation: 'landscape', + feature: 'wide', + }, + { + src: '/images/boulder/04.jpg', + alt: 'Front of the home under a winter moon at dusk', + orientation: 'landscape', + feature: 'wide', + }, + ], +} + +export const asheville: Project = { + slug: 'asheville', + name: 'Asheville', + eyebrow: 'Architectural and moody', + intro: + 'A counterpoint to Boulder — black vertical slats, matte black appliances, ' + + 'and large picture windows held in balance by warm wood floors and layered ' + + 'textiles. A space that is restrained but never cold.', + cover: '/images/asheville/01-living.jpg', + coverAlt: 'Living room with black vertical slat wall and picture window', + images: [ + { + src: '/images/asheville/01-living.jpg', + alt: 'Living room with black vertical slat wall and oversized window', + orientation: 'portrait', + feature: 'hero', + }, + { + src: '/images/asheville/02-kitchen.jpg', + alt: 'Galley kitchen with matte black appliances and layered Persian rug', + orientation: 'portrait', + feature: 'narrow', + }, + { + src: '/images/asheville/04-dining-wide.jpg', + alt: 'Dining nook with vertical slat wall and trailing monstera', + orientation: 'portrait', + feature: 'narrow', + }, + { + src: '/images/asheville/05-dining-detail.jpg', + alt: 'Dining table beneath a Nelson Saucer pendant against vertical slat wall', + orientation: 'portrait', + feature: 'narrow', + }, + { + src: '/images/asheville/03-bath.jpg', + alt: 'Powder bath with layered glazed tile and matte black accents', + orientation: 'portrait', + feature: 'narrow', + }, + ], +} + +export const projects: Project[] = [boulder, asheville] + +export function getProject(slug: string): Project | undefined { + return projects.find((p) => p.slug === slug) +} diff --git a/src/router/index.ts b/src/router/index.ts index 4f315f4..e30467c 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -6,11 +6,39 @@ const routes: RouteRecordRaw[] = [ name: 'home', component: () => import('@/views/HomeView.vue'), }, + { + path: '/portfolio', + name: 'portfolio', + component: () => import('@/views/PortfolioView.vue'), + }, + { + path: '/portfolio/boulder', + name: 'portfolio-boulder', + component: () => import('@/views/projects/BoulderView.vue'), + }, + { + path: '/portfolio/asheville', + name: 'portfolio-asheville', + component: () => import('@/views/projects/AshevilleView.vue'), + }, + { + path: '/contact', + name: 'contact', + component: () => import('@/views/ContactView.vue'), + }, + { + path: '/:pathMatch(.*)*', + redirect: '/', + }, ] const router = createRouter({ history: createWebHistory(import.meta.env.BASE_URL), routes, + scrollBehavior(_to, _from, saved) { + if (saved) return saved + return { top: 0 } + }, }) export default router diff --git a/src/views/ContactView.vue b/src/views/ContactView.vue new file mode 100644 index 0000000..7148aae --- /dev/null +++ b/src/views/ContactView.vue @@ -0,0 +1,11 @@ + + + diff --git a/src/views/PortfolioView.vue b/src/views/PortfolioView.vue new file mode 100644 index 0000000..5143a92 --- /dev/null +++ b/src/views/PortfolioView.vue @@ -0,0 +1,48 @@ + + + diff --git a/src/views/projects/AshevilleView.vue b/src/views/projects/AshevilleView.vue new file mode 100644 index 0000000..af54897 --- /dev/null +++ b/src/views/projects/AshevilleView.vue @@ -0,0 +1,8 @@ + + + diff --git a/src/views/projects/BoulderView.vue b/src/views/projects/BoulderView.vue new file mode 100644 index 0000000..d9bfa0d --- /dev/null +++ b/src/views/projects/BoulderView.vue @@ -0,0 +1,8 @@ + + +