🚧 Use PageTransition as a div and switch
- use a page classed div for PageTransition which avoids to make global style for the page - fix the loading spinner that was too short and would come and go before arriving on the page, now fades out when changing page as pageLoading is defined on the PageTransition afterUpdate
This commit is contained in:
@@ -1,18 +1,26 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { page } from '$app/stores'
|
import { page } from '$app/stores'
|
||||||
|
import { afterUpdate } from 'svelte'
|
||||||
import { fade } from 'svelte/transition'
|
import { fade } from 'svelte/transition'
|
||||||
|
import { pageLoading } from '$utils/stores'
|
||||||
import { scrollToTop } from '$utils/functions'
|
import { scrollToTop } from '$utils/functions'
|
||||||
import { DURATION } from '$utils/contants'
|
import { DURATION } from '$utils/contants'
|
||||||
|
|
||||||
export let name: string
|
let loadingTimeout: ReturnType<typeof setTimeout> | number = null
|
||||||
|
|
||||||
$: doNotScroll = !$page.url.searchParams.get('country') && !$page.url.pathname.includes('/shop/')
|
$: doNotScroll = !$page.url.searchParams.get('country') && !$page.url.pathname.includes('/shop/')
|
||||||
|
|
||||||
|
afterUpdate(() => {
|
||||||
|
// Turn page loading on page mount
|
||||||
|
clearTimeout(loadingTimeout)
|
||||||
|
loadingTimeout = setTimeout(() => $pageLoading = false, DURATION.PAGE_IN)
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<main class={name}
|
<div class="page"
|
||||||
in:fade={{ duration: DURATION.PAGE_IN, delay: DURATION.PAGE_DELAY }}
|
in:fade={{ duration: DURATION.PAGE_IN, delay: DURATION.PAGE_DELAY }}
|
||||||
out:fade={{ duration: DURATION.PAGE_OUT }}
|
out:fade={{ duration: DURATION.PAGE_OUT }}
|
||||||
on:outroend={() => doNotScroll && scrollToTop()}
|
on:outroend={() => doNotScroll && scrollToTop()}
|
||||||
>
|
>
|
||||||
<slot />
|
<slot />
|
||||||
</main>
|
</div>
|
||||||
@@ -34,49 +34,51 @@
|
|||||||
title="{errors[$page.status].title} – Houses Of"
|
title="{errors[$page.status].title} – Houses Of"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<PageTransition name="page-error">
|
<PageTransition>
|
||||||
<div class="page-error__top">
|
<main class="page-error">
|
||||||
<Heading
|
<div class="page-error__top">
|
||||||
text="{$page.error.message ?? errors[$page.status].message} <br>{defaultMessage}"
|
<Heading
|
||||||
/>
|
text="{$page.error.message ?? errors[$page.status].message} <br>{defaultMessage}"
|
||||||
|
/>
|
||||||
|
|
||||||
<ListCTAs>
|
<ListCTAs>
|
||||||
<li>
|
<li>
|
||||||
<BoxCTA
|
<BoxCTA
|
||||||
url="/photos"
|
url="/photos"
|
||||||
icon="photos"
|
icon="photos"
|
||||||
label="Browse all photos"
|
label="Browse all photos"
|
||||||
alt="Photos"
|
alt="Photos"
|
||||||
/>
|
/>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<BoxCTA
|
<BoxCTA
|
||||||
url="/shop"
|
url="/shop"
|
||||||
icon="bag"
|
icon="bag"
|
||||||
label="Shop our products"
|
label="Shop our products"
|
||||||
alt="Shopping bag"
|
alt="Shopping bag"
|
||||||
/>
|
/>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<BoxCTA
|
<BoxCTA
|
||||||
url="/about"
|
url="/about"
|
||||||
icon="compass"
|
icon="compass"
|
||||||
label="Learn about the project"
|
label="Learn about the project"
|
||||||
alt="Compass"
|
alt="Compass"
|
||||||
/>
|
/>
|
||||||
</li>
|
</li>
|
||||||
</ListCTAs>
|
</ListCTAs>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<InteractiveGlobe />
|
<InteractiveGlobe />
|
||||||
<Locations {locations} />
|
<Locations {locations} />
|
||||||
|
|
||||||
<div class="grid-modules">
|
<div class="grid-modules">
|
||||||
<div class="container grid">
|
<div class="container grid">
|
||||||
<div class="wrap">
|
<div class="wrap">
|
||||||
<ShopModule />
|
<ShopModule />
|
||||||
<NewsletterModule />
|
<NewsletterModule />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</main>
|
||||||
</PageTransition>
|
</PageTransition>
|
||||||
@@ -7,7 +7,6 @@
|
|||||||
import type { PageData } from './$types'
|
import type { PageData } from './$types'
|
||||||
import { onMount, setContext } from 'svelte'
|
import { onMount, setContext } from 'svelte'
|
||||||
import { pageLoading, previousPage } from '$utils/stores'
|
import { pageLoading, previousPage } from '$utils/stores'
|
||||||
import { DURATION } from '$utils/contants'
|
|
||||||
import '$utils/polyfills'
|
import '$utils/polyfills'
|
||||||
import { PUBLIC_ANALYTICS_KEY, PUBLIC_ANALYTICS_URL } from '$env/static/public'
|
import { PUBLIC_ANALYTICS_KEY, PUBLIC_ANALYTICS_URL } from '$env/static/public'
|
||||||
// Components
|
// Components
|
||||||
@@ -46,14 +45,7 @@
|
|||||||
|
|
||||||
// Define page loading from navigating store
|
// Define page loading from navigating store
|
||||||
navigating.subscribe((store: any) => {
|
navigating.subscribe((store: any) => {
|
||||||
if (store) {
|
store && ($pageLoading = true)
|
||||||
$pageLoading = true
|
|
||||||
|
|
||||||
// Turn page loading when changing page
|
|
||||||
setTimeout(() => {
|
|
||||||
$pageLoading = false
|
|
||||||
}, DURATION.PAGE_IN * 1.25)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
|
|||||||
@@ -82,87 +82,89 @@
|
|||||||
/>
|
/>
|
||||||
<!-- image={getAssetUrlKey(settings.seo_image.id, 'share-image')} -->
|
<!-- image={getAssetUrlKey(settings.seo_image.id, 'share-image')} -->
|
||||||
|
|
||||||
<PageTransition name="homepage">
|
<PageTransition>
|
||||||
<section class="homepage__intro"
|
<main class="homepage">
|
||||||
use:reveal={{
|
<section class="homepage__intro"
|
||||||
animation: { opacity: [0, 1] },
|
use:reveal={{
|
||||||
options: {
|
animation: { opacity: [0, 1] },
|
||||||
duration: 1,
|
options: {
|
||||||
},
|
duration: 1,
|
||||||
}}
|
},
|
||||||
>
|
}}
|
||||||
<ScrollingTitle
|
|
||||||
tag="h1"
|
|
||||||
class="title-houses"
|
|
||||||
label="Houses of the World"
|
|
||||||
offsetStart={-300}
|
|
||||||
offsetEnd={400}
|
|
||||||
>
|
>
|
||||||
<SplitText text="Houses" mode="chars" />
|
<ScrollingTitle
|
||||||
</ScrollingTitle>
|
tag="h1"
|
||||||
|
class="title-houses"
|
||||||
|
label="Houses of the World"
|
||||||
|
offsetStart={-300}
|
||||||
|
offsetEnd={400}
|
||||||
|
>
|
||||||
|
<SplitText text="Houses" mode="chars" />
|
||||||
|
</ScrollingTitle>
|
||||||
|
|
||||||
<div class="homepage__headline">
|
<div class="homepage__headline">
|
||||||
<p class="text-medium">
|
<p class="text-medium">
|
||||||
{settings.description}
|
{settings.description}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<Button url="#locations" text="Explore locations" on:click={() => $smoothScroll.scrollTo('#locations', { duration: 2 })}>
|
<Button url="#locations" text="Explore locations" on:click={() => $smoothScroll.scrollTo('#locations', { duration: 2 })}>
|
||||||
<IconEarth animate={true} />
|
<IconEarth animate={true} />
|
||||||
</Button>
|
</Button>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="homepage__photos">
|
||||||
|
<Collage {photos} />
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<div class="homepage__ctas">
|
||||||
|
<DiscoverText />
|
||||||
|
|
||||||
|
<ListCTAs>
|
||||||
|
<li>
|
||||||
|
<BoxCTA
|
||||||
|
url="/photos"
|
||||||
|
icon="photos"
|
||||||
|
label="Browse all photos"
|
||||||
|
alt="Photos"
|
||||||
|
/>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<BoxCTA
|
||||||
|
url="/shop"
|
||||||
|
icon="bag"
|
||||||
|
label="Shop our products"
|
||||||
|
alt="Shopping bag"
|
||||||
|
/>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<BoxCTA
|
||||||
|
url="/about"
|
||||||
|
icon="compass"
|
||||||
|
label="Learn about the project"
|
||||||
|
alt="Compass"
|
||||||
|
/>
|
||||||
|
</li>
|
||||||
|
</ListCTAs>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="homepage__photos">
|
<section class="homepage__locations" id="locations">
|
||||||
<Collage {photos} />
|
<InteractiveGlobe />
|
||||||
</section>
|
|
||||||
|
|
||||||
<div class="homepage__ctas">
|
<ScrollingTitle tag="p" class="title-world mask">
|
||||||
<DiscoverText />
|
<SplitText text="World" mode="chars" />
|
||||||
|
</ScrollingTitle>
|
||||||
|
|
||||||
<ListCTAs>
|
<Locations {locations} />
|
||||||
<li>
|
</section>
|
||||||
<BoxCTA
|
|
||||||
url="/photos"
|
|
||||||
icon="photos"
|
|
||||||
label="Browse all photos"
|
|
||||||
alt="Photos"
|
|
||||||
/>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<BoxCTA
|
|
||||||
url="/shop"
|
|
||||||
icon="bag"
|
|
||||||
label="Shop our products"
|
|
||||||
alt="Shopping bag"
|
|
||||||
/>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<BoxCTA
|
|
||||||
url="/about"
|
|
||||||
icon="compass"
|
|
||||||
label="Learn about the project"
|
|
||||||
alt="Compass"
|
|
||||||
/>
|
|
||||||
</li>
|
|
||||||
</ListCTAs>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<section class="homepage__locations" id="locations">
|
<div class="grid-modules">
|
||||||
<InteractiveGlobe />
|
<div class="container grid">
|
||||||
|
<div class="wrap">
|
||||||
<ScrollingTitle tag="p" class="title-world mask">
|
<ShopModule />
|
||||||
<SplitText text="World" mode="chars" />
|
<NewsletterModule />
|
||||||
</ScrollingTitle>
|
</div>
|
||||||
|
|
||||||
<Locations {locations} />
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<div class="grid-modules">
|
|
||||||
<div class="container grid">
|
|
||||||
<div class="wrap">
|
|
||||||
<ShopModule />
|
|
||||||
<NewsletterModule />
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</main>
|
||||||
</PageTransition>
|
</PageTransition>
|
||||||
@@ -218,148 +218,149 @@
|
|||||||
|
|
||||||
<svelte:window bind:scrollY />
|
<svelte:window bind:scrollY />
|
||||||
|
|
||||||
|
<PageTransition>
|
||||||
|
<main class="location-page">
|
||||||
|
<section class="location-page__intro grid" bind:this={introEl}>
|
||||||
|
<h1 class="title" class:is-short={location.name.length <= 4}>
|
||||||
|
<span class="housesof mask">
|
||||||
|
<strong class="word">Houses</strong>
|
||||||
|
<span class="of">of</span>
|
||||||
|
</span>
|
||||||
|
<strong class="city mask">
|
||||||
|
<span class="word">{location.name}</span>
|
||||||
|
</strong>
|
||||||
|
</h1>
|
||||||
|
|
||||||
<PageTransition name="location-page">
|
<div class="location-page__description grid">
|
||||||
<section class="location-page__intro grid" bind:this={introEl}>
|
<div class="wrap">
|
||||||
<h1 class="title" class:is-short={location.name.length <= 4}>
|
<div class="text-medium">
|
||||||
<span class="housesof mask">
|
Houses of {location.name} {location.description ?? 'has no description yet'}
|
||||||
<strong class="word">Houses</strong>
|
</div>
|
||||||
<span class="of">of</span>
|
<div class="info">
|
||||||
</span>
|
<p class="text-label">
|
||||||
<strong class="city mask">
|
Photos by
|
||||||
<span class="word">{location.name}</span>
|
{#each location.credits as { credit_id: { name, website }}}
|
||||||
</strong>
|
{#if website}
|
||||||
</h1>
|
<a href={website} target="_blank" rel="noopener external">
|
||||||
|
{name}
|
||||||
<div class="location-page__description grid">
|
</a>
|
||||||
<div class="wrap">
|
{:else}
|
||||||
<div class="text-medium">
|
<span>{name}</span>
|
||||||
Houses of {location.name} {location.description ?? 'has no description yet'}
|
{/if}
|
||||||
</div>
|
{/each}
|
||||||
<div class="info">
|
|
||||||
<p class="text-label">
|
|
||||||
Photos by
|
|
||||||
{#each location.credits as { credit_id: { name, website }}}
|
|
||||||
{#if website}
|
|
||||||
<a href={website} target="_blank" rel="noopener external">
|
|
||||||
{name}
|
|
||||||
</a>
|
|
||||||
{:else}
|
|
||||||
<span>{name}</span>
|
|
||||||
{/if}
|
|
||||||
{/each}
|
|
||||||
</p>
|
|
||||||
{#if latestPhoto}
|
|
||||||
·
|
|
||||||
<p class="text-label" title={dayjs(latestPhoto.date_created).format('DD/MM/YYYY, hh:mm')}>
|
|
||||||
Updated <time datetime={dayjs(latestPhoto.date_created).format('YYYY-MM-DD')}>
|
|
||||||
{dayjs().to(dayjs(latestPhoto.date_created))}
|
|
||||||
</time>
|
|
||||||
</p>
|
</p>
|
||||||
{/if}
|
{#if latestPhoto}
|
||||||
</div>
|
·
|
||||||
|
<p class="text-label" title={dayjs(latestPhoto.date_created).format('DD/MM/YYYY, hh:mm')}>
|
||||||
|
Updated <time datetime={dayjs(latestPhoto.date_created).format('YYYY-MM-DD')}>
|
||||||
|
{dayjs().to(dayjs(latestPhoto.date_created))}
|
||||||
|
</time>
|
||||||
|
</p>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="ctas">
|
<div class="ctas">
|
||||||
<Button url="/locations" text="Change location" class="shadow-small">
|
<Button url="/locations" text="Change location" class="shadow-small">
|
||||||
<IconEarth />
|
<IconEarth />
|
||||||
</Button>
|
|
||||||
|
|
||||||
{#if location.has_poster}
|
|
||||||
<Button url="/shop/poster-{location.slug}" text="Buy the poster" color="pinklight" class="shadow-small">
|
|
||||||
<!-- <IconEarth /> -->
|
|
||||||
</Button>
|
</Button>
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{#if hasIllustration}
|
{#if location.has_poster}
|
||||||
<picture class="location-page__illustration" style:--parallax-y="{illustrationOffsetY}px">
|
<Button url="/shop/poster-{location.slug}" text="Buy the poster" color="pinklight" class="shadow-small">
|
||||||
<source media="(min-width: 1200px)" srcset={getAssetUrlKey(location.illustration_desktop_2x.id, 'illustration-desktop-2x')}>
|
<!-- <IconEarth /> -->
|
||||||
<source media="(min-width: 768px)" srcset={getAssetUrlKey(location.illustration_desktop.id, 'illustration-desktop-1x')}>
|
</Button>
|
||||||
<img
|
{/if}
|
||||||
src={getAssetUrlKey(location.illustration_mobile.id, 'illustration-mobile')}
|
|
||||||
width={320}
|
|
||||||
height={824}
|
|
||||||
alt="Illustration for {location.name}"
|
|
||||||
decoding="async"
|
|
||||||
/>
|
|
||||||
</picture>
|
|
||||||
{/if}
|
|
||||||
</section>
|
|
||||||
|
|
||||||
{#if photos.length}
|
|
||||||
<section class="location-page__houses" bind:this={photosListEl} data-sveltekit-noscroll>
|
|
||||||
{#each photos as { title, image: { id, title: alt, width, height }, slug, city, date_taken }, index}
|
|
||||||
<House
|
|
||||||
{title}
|
|
||||||
photoId={id}
|
|
||||||
photoAlt={alt}
|
|
||||||
url="/{params.country}/{params.location}/{slug}"
|
|
||||||
{city}
|
|
||||||
location={location.name}
|
|
||||||
ratio={width / height}
|
|
||||||
date={date_taken}
|
|
||||||
index={(totalPhotos - index < 10) ? '0' : ''}{totalPhotos - index}
|
|
||||||
/>
|
|
||||||
{/each}
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="location-page__next container">
|
|
||||||
<Pagination
|
|
||||||
ended={ended}
|
|
||||||
current={currentPhotosAmount}
|
|
||||||
total={totalPhotos}
|
|
||||||
on:click={!ended && loadMorePhotos}
|
|
||||||
>
|
|
||||||
{#if !ended}
|
|
||||||
<p class="more">See more photos</p>
|
|
||||||
{:else}
|
|
||||||
<p>You've seen it all!</p>
|
|
||||||
{/if}
|
|
||||||
</Pagination>
|
|
||||||
|
|
||||||
{#if ended}
|
|
||||||
<div class="grid-modules">
|
|
||||||
<div class="container grid">
|
|
||||||
<div class="wrap">
|
|
||||||
{#if location.has_poster}
|
|
||||||
<ShopModule
|
|
||||||
title="Poster available"
|
|
||||||
text="Houses of {location.name} is available as a poster on our shop."
|
|
||||||
images={product.photos_product}
|
|
||||||
textBottom={null}
|
|
||||||
buttonText="Buy"
|
|
||||||
url="/shop/poster-{location.slug}"
|
|
||||||
/>
|
|
||||||
{:else}
|
|
||||||
<ShopModule />
|
|
||||||
{/if}
|
|
||||||
<NewsletterModule theme="light" />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
</div>
|
||||||
|
|
||||||
{#if location.acknowledgement}
|
{#if hasIllustration}
|
||||||
<div class="acknowledgement">
|
<picture class="location-page__illustration" style:--parallax-y="{illustrationOffsetY}px">
|
||||||
<Image
|
<source media="(min-width: 1200px)" srcset={getAssetUrlKey(location.illustration_desktop_2x.id, 'illustration-desktop-2x')}>
|
||||||
class="flag"
|
<source media="(min-width: 768px)" srcset={getAssetUrlKey(location.illustration_desktop.id, 'illustration-desktop-1x')}>
|
||||||
id={location.country.flag.id}
|
<img
|
||||||
sizeKey="square-small"
|
src={getAssetUrlKey(location.illustration_mobile.id, 'illustration-mobile')}
|
||||||
width={32} height={32}
|
width={320}
|
||||||
alt="Flag of {location.country.name}"
|
height={824}
|
||||||
|
alt="Illustration for {location.name}"
|
||||||
|
decoding="async"
|
||||||
/>
|
/>
|
||||||
<p>{location.acknowledgement}</p>
|
</picture>
|
||||||
</div>
|
|
||||||
{/if}
|
{/if}
|
||||||
</section>
|
</section>
|
||||||
{:else}
|
|
||||||
<div class="location-page__message">
|
{#if photos.length}
|
||||||
<p>
|
<section class="location-page__houses" bind:this={photosListEl} data-sveltekit-noscroll>
|
||||||
No photos available for {location.name}.<br>
|
{#each photos as { title, image: { id, title: alt, width, height }, slug, city, date_taken }, index}
|
||||||
Come back later!
|
<House
|
||||||
</p>
|
{title}
|
||||||
</div>
|
photoId={id}
|
||||||
{/if}
|
photoAlt={alt}
|
||||||
|
url="/{params.country}/{params.location}/{slug}"
|
||||||
|
{city}
|
||||||
|
location={location.name}
|
||||||
|
ratio={width / height}
|
||||||
|
date={date_taken}
|
||||||
|
index={(totalPhotos - index < 10) ? '0' : ''}{totalPhotos - index}
|
||||||
|
/>
|
||||||
|
{/each}
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="location-page__next container">
|
||||||
|
<Pagination
|
||||||
|
ended={ended}
|
||||||
|
current={currentPhotosAmount}
|
||||||
|
total={totalPhotos}
|
||||||
|
on:click={!ended && loadMorePhotos}
|
||||||
|
>
|
||||||
|
{#if !ended}
|
||||||
|
<p class="more">See more photos</p>
|
||||||
|
{:else}
|
||||||
|
<p>You've seen it all!</p>
|
||||||
|
{/if}
|
||||||
|
</Pagination>
|
||||||
|
|
||||||
|
{#if ended}
|
||||||
|
<div class="grid-modules">
|
||||||
|
<div class="container grid">
|
||||||
|
<div class="wrap">
|
||||||
|
{#if location.has_poster}
|
||||||
|
<ShopModule
|
||||||
|
title="Poster available"
|
||||||
|
text="Houses of {location.name} is available as a poster on our shop."
|
||||||
|
images={product.photos_product}
|
||||||
|
textBottom={null}
|
||||||
|
buttonText="Buy"
|
||||||
|
url="/shop/poster-{location.slug}"
|
||||||
|
/>
|
||||||
|
{:else}
|
||||||
|
<ShopModule />
|
||||||
|
{/if}
|
||||||
|
<NewsletterModule theme="light" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{#if location.acknowledgement}
|
||||||
|
<div class="acknowledgement">
|
||||||
|
<Image
|
||||||
|
class="flag"
|
||||||
|
id={location.country.flag.id}
|
||||||
|
sizeKey="square-small"
|
||||||
|
width={32} height={32}
|
||||||
|
alt="Flag of {location.country.name}"
|
||||||
|
/>
|
||||||
|
<p>{location.acknowledgement}</p>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</section>
|
||||||
|
{:else}
|
||||||
|
<div class="location-page__message">
|
||||||
|
<p>
|
||||||
|
No photos available for {location.name}.<br>
|
||||||
|
Come back later!
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</main>
|
||||||
</PageTransition>
|
</PageTransition>
|
||||||
@@ -305,98 +305,100 @@
|
|||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
|
||||||
<PageTransition name="photo-page">
|
<PageTransition>
|
||||||
<div class="container grid">
|
<main class="photo-page">
|
||||||
<p class="photo-page__notice text-label">Tap for fullscreen</p>
|
<div class="container grid">
|
||||||
|
<p class="photo-page__notice text-label">Tap for fullscreen</p>
|
||||||
|
|
||||||
<ButtonCircle
|
<ButtonCircle
|
||||||
tag="a"
|
tag="a"
|
||||||
url={previousUrl}
|
url={previousUrl}
|
||||||
color="purple"
|
color="purple"
|
||||||
class="close shadow-box-dark"
|
class="close shadow-box-dark"
|
||||||
label="Close"
|
label="Close"
|
||||||
>
|
>
|
||||||
<svg width="12" height="12">
|
<svg width="12" height="12">
|
||||||
<use xlink:href="#cross">
|
<use xlink:href="#cross">
|
||||||
</svg>
|
</svg>
|
||||||
</ButtonCircle>
|
</ButtonCircle>
|
||||||
|
|
||||||
<div class="photo-page__carousel">
|
<div class="photo-page__carousel">
|
||||||
<div class="photo-page__images" use:swipe on:swipe={handleSwipe} on:tap={toggleFullscreen}>
|
<div class="photo-page__images" use:swipe on:swipe={handleSwipe} on:tap={toggleFullscreen}>
|
||||||
{#each visiblePhotos as { id, image, title }, index (id)}
|
{#each visiblePhotos as { id, image, title }, index (id)}
|
||||||
<div class="photo-page__picture is-{currentIndex === 0 ? index + 1 : index}">
|
<div class="photo-page__picture is-{currentIndex === 0 ? index + 1 : index}">
|
||||||
<Image
|
<Image
|
||||||
class="photo {image.width / image.height < 1.475 ? 'not-landscape' : ''}"
|
class="photo {image.width / image.height < 1.475 ? 'not-landscape' : ''}"
|
||||||
id={image.id}
|
id={image.id}
|
||||||
alt={title}
|
alt={title}
|
||||||
sizeKey="photo-list"
|
sizeKey="photo-list"
|
||||||
sizes={{
|
sizes={{
|
||||||
small: { width: 500 },
|
small: { width: 500 },
|
||||||
medium: { width: 850 },
|
medium: { width: 850 },
|
||||||
large: { width: 1280 },
|
large: { width: 1280 },
|
||||||
}}
|
}}
|
||||||
ratio={1.5}
|
ratio={1.5}
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
|
||||||
|
<div class="photo-page__controls">
|
||||||
|
<ButtonCircle class="prev shadow-box-dark" label="Previous" disabled={!canGoNext} clone={true} on:click={goToPrevious}>
|
||||||
|
<IconArrow color="pink" flip={true} />
|
||||||
|
</ButtonCircle>
|
||||||
|
<ButtonCircle class="next shadow-box-dark" label="Next" disabled={!canGoPrev} clone={true} on:click={goToNext}>
|
||||||
|
<IconArrow color="pink" />
|
||||||
|
</ButtonCircle>
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
|
||||||
|
|
||||||
<div class="photo-page__controls">
|
|
||||||
<ButtonCircle class="prev shadow-box-dark" label="Previous" disabled={!canGoNext} clone={true} on:click={goToPrevious}>
|
<div class="photo-page__index title-index">
|
||||||
<IconArrow color="pink" flip={true} />
|
<SplitText text="{(currentPhotoIndex < 10) ? '0' : ''}{currentPhotoIndex}" mode="chars" />
|
||||||
</ButtonCircle>
|
</div>
|
||||||
<ButtonCircle class="next shadow-box-dark" label="Next" disabled={!canGoPrev} clone={true} on:click={goToNext}>
|
|
||||||
<IconArrow color="pink" />
|
|
||||||
</ButtonCircle>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="photo-page__info">
|
||||||
|
<h1 class="title-medium">{currentPhoto.title}</h1>
|
||||||
|
|
||||||
<div class="photo-page__index title-index">
|
<div class="detail text-info">
|
||||||
<SplitText text="{(currentPhotoIndex < 10) ? '0' : ''}{currentPhotoIndex}" mode="chars" />
|
<a href="/{location.country.slug}/{location.slug}" data-sveltekit-prefetch data-sveltekit-noscroll>
|
||||||
</div>
|
<Icon class="icon" icon="map-pin" label="Map pin" />
|
||||||
</div>
|
<span>
|
||||||
|
{#if currentPhoto.city}
|
||||||
<div class="photo-page__info">
|
{currentPhoto.city}, {location.name}, {location.country.name}
|
||||||
<h1 class="title-medium">{currentPhoto.title}</h1>
|
{:else}
|
||||||
|
{location.name}, {location.country.name}
|
||||||
<div class="detail text-info">
|
{/if}
|
||||||
<a href="/{location.country.slug}/{location.slug}" data-sveltekit-prefetch data-sveltekit-noscroll>
|
</span>
|
||||||
<Icon class="icon" icon="map-pin" label="Map pin" />
|
</a>
|
||||||
<span>
|
{#if currentPhoto.date_taken}
|
||||||
{#if currentPhoto.city}
|
<span class="sep">·</span>
|
||||||
{currentPhoto.city}, {location.name}, {location.country.name}
|
<time datetime={dayjs(currentPhoto.date_taken).format('YYYY-MM-DD')}>{dayjs(currentPhoto.date_taken).format('MMMM YYYY')}</time>
|
||||||
{:else}
|
{/if}
|
||||||
{location.name}, {location.country.name}
|
</div>
|
||||||
{/if}
|
|
||||||
</span>
|
|
||||||
</a>
|
|
||||||
{#if currentPhoto.date_taken}
|
|
||||||
<span class="sep">·</span>
|
|
||||||
<time datetime={dayjs(currentPhoto.date_taken).format('YYYY-MM-DD')}>{dayjs(currentPhoto.date_taken).format('MMMM YYYY')}</time>
|
|
||||||
{/if}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
{#if isFullscreen}
|
{#if isFullscreen}
|
||||||
<div class="photo-page__fullscreen" bind:this={fullscreenEl} on:click={toggleFullscreen}
|
<div class="photo-page__fullscreen" bind:this={fullscreenEl} on:click={toggleFullscreen}
|
||||||
in:fade={{ easing: quartOut, duration: 1000 }}
|
in:fade={{ easing: quartOut, duration: 1000 }}
|
||||||
out:fade={{ easing: quartOut, duration: 1000, delay: 300 }}
|
out:fade={{ easing: quartOut, duration: 1000, delay: 300 }}
|
||||||
>
|
>
|
||||||
<div class="inner" transition:scale={{ easing: quartOut, start: 1.1, duration: 1000 }}>
|
<div class="inner" transition:scale={{ easing: quartOut, start: 1.1, duration: 1000 }}>
|
||||||
<Image
|
<Image
|
||||||
id={currentPhoto.image.id}
|
id={currentPhoto.image.id}
|
||||||
sizeKey="photo-grid-large"
|
sizeKey="photo-grid-large"
|
||||||
width={1266}
|
width={1266}
|
||||||
height={844}
|
height={844}
|
||||||
alt={currentPhoto.title}
|
alt={currentPhoto.title}
|
||||||
/>
|
/>
|
||||||
<ButtonCircle color="gray-medium" class="close">
|
<ButtonCircle color="gray-medium" class="close">
|
||||||
<svg width="18" height="18" viewBox="0 0 18 18" fill="#fff" xmlns="http://www.w3.org/2000/svg">
|
<svg width="18" height="18" viewBox="0 0 18 18" fill="#fff" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.751 0c4.274 0 7.752 3.477 7.752 7.751 0 1.846-.65 3.543-1.73 4.875l3.99 3.991a.81.81 0 1 1-1.146 1.146l-3.99-3.991a7.714 7.714 0 0 1-4.876 1.73C3.477 15.503 0 12.027 0 7.753 0 3.476 3.477 0 7.751 0Zm0 1.62a6.138 6.138 0 0 0-6.13 6.131 6.138 6.138 0 0 0 6.13 6.132 6.138 6.138 0 0 0 6.131-6.132c0-3.38-2.75-6.13-6.13-6.13Zm2.38 5.321a.81.81 0 1 1 0 1.62h-4.76a.81.81 0 1 1 0-1.62h4.76Z" />
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.751 0c4.274 0 7.752 3.477 7.752 7.751 0 1.846-.65 3.543-1.73 4.875l3.99 3.991a.81.81 0 1 1-1.146 1.146l-3.99-3.991a7.714 7.714 0 0 1-4.876 1.73C3.477 15.503 0 12.027 0 7.753 0 3.476 3.477 0 7.751 0Zm0 1.62a6.138 6.138 0 0 0-6.13 6.131 6.138 6.138 0 0 0 6.13 6.132 6.138 6.138 0 0 0 6.131-6.132c0-3.38-2.75-6.13-6.13-6.13Zm2.38 5.321a.81.81 0 1 1 0 1.62h-4.76a.81.81 0 1 1 0-1.62h4.76Z" />
|
||||||
</svg>
|
</svg>
|
||||||
</ButtonCircle>
|
</ButtonCircle>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{/if}
|
||||||
{/if}
|
</main>
|
||||||
</PageTransition>
|
</PageTransition>
|
||||||
@@ -180,215 +180,216 @@
|
|||||||
image={about.seo_image ? getAssetUrlKey(about.seo_image.id, 'share-image') : null}
|
image={about.seo_image ? getAssetUrlKey(about.seo_image.id, 'share-image') : null}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<PageTransition>
|
||||||
|
<main class="about">
|
||||||
|
<Banner
|
||||||
|
title="About"
|
||||||
|
image={{
|
||||||
|
id: '699b4050-6bbf-4a40-be53-d84aca484f9d',
|
||||||
|
alt: 'Photo caption',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
<PageTransition name="about">
|
<section class="about__introduction">
|
||||||
<Banner
|
<div class="container grid">
|
||||||
title="About"
|
<h2 class="title-small">{about.intro_title}</h2>
|
||||||
image={{
|
<div class="heading text-big">
|
||||||
id: '699b4050-6bbf-4a40-be53-d84aca484f9d',
|
{@html about.intro_heading}
|
||||||
alt: 'Photo caption',
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<section class="about__introduction">
|
|
||||||
<div class="container grid">
|
|
||||||
<h2 class="title-small">{about.intro_title}</h2>
|
|
||||||
<div class="heading text-big">
|
|
||||||
{@html about.intro_heading}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="text text-small">
|
|
||||||
{@html about.intro_text}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="about__creation">
|
|
||||||
<div class="container grid">
|
|
||||||
<figure class="first-photo">
|
|
||||||
<Image
|
|
||||||
class="picture shadow-box-dark"
|
|
||||||
id={about.intro_firstphoto.id}
|
|
||||||
alt={about.intro_firstphoto.title}
|
|
||||||
sizeKey="photo-list"
|
|
||||||
sizes={{
|
|
||||||
small: { width: 400 },
|
|
||||||
medium: { width: 600 },
|
|
||||||
large: { width: 800 },
|
|
||||||
}}
|
|
||||||
ratio={1.5}
|
|
||||||
/>
|
|
||||||
<figcaption class="text-info">
|
|
||||||
{about.intro_firstphoto_caption}<br>
|
|
||||||
in
|
|
||||||
<a href="/{about.intro_firstlocation.country.slug}/{about.intro_firstlocation.slug}" data-sveltekit-noscroll data-sveltekit-prefetch>
|
|
||||||
<img src="{getAssetUrlKey(about.intro_firstlocation.country.flag.id, 'square-small-jpg')}" width="32" height="32" alt="{about.intro_firstlocation.country.flag.title}">
|
|
||||||
<span>Naarm Australia (Melbourne)</span>
|
|
||||||
</a>
|
|
||||||
</figcaption>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
<h2 class="title-small" data-reveal>{about.creation_title}</h2>
|
|
||||||
<div class="heading text-huge" data-reveal>
|
|
||||||
{@html about.creation_heading}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="text text-small" data-reveal>
|
|
||||||
{@html about.creation_text}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<figure class="picture portrait-photo" data-reveal-image>
|
|
||||||
<Image
|
|
||||||
class="shadow-box-dark"
|
|
||||||
id={about.creation_portrait.id}
|
|
||||||
alt={about.creation_portrait.title}
|
|
||||||
sizeKey="photo-list"
|
|
||||||
sizes={{
|
|
||||||
small: { width: 400 },
|
|
||||||
medium: { width: 750 },
|
|
||||||
}}
|
|
||||||
ratio={1.425}
|
|
||||||
/>
|
|
||||||
</figure>
|
|
||||||
<span class="portrait-photo__caption text-info">
|
|
||||||
{about.creation_portrait_caption}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="about__present">
|
|
||||||
<div class="container grid">
|
|
||||||
<figure class="picture" data-reveal-image>
|
|
||||||
<Image
|
|
||||||
class="shadow-box-dark"
|
|
||||||
id={about.present_image.id}
|
|
||||||
alt={about.present_image.title}
|
|
||||||
sizeKey="photo-list"
|
|
||||||
sizes={{
|
|
||||||
small: { width: 400 },
|
|
||||||
medium: { width: 600 },
|
|
||||||
large: { width: 800 },
|
|
||||||
}}
|
|
||||||
ratio={1.5}
|
|
||||||
/>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
<h2 class="title-small" data-reveal>{about.present_title}</h2>
|
|
||||||
<div class="text text-small" data-reveal>
|
|
||||||
<p>{about.present_text}</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="heading text-big" data-reveal>
|
|
||||||
{@html about.present_heading}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="conclusion text-small" data-reveal>
|
|
||||||
<p>{about.present_conclusion}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
{#if about.image_showcase}
|
|
||||||
<div class="about__showcase container grid">
|
|
||||||
<Image
|
|
||||||
id={about.image_showcase.id}
|
|
||||||
alt={about.image_showcase.title}
|
|
||||||
sizeKey="showcase"
|
|
||||||
sizes={{
|
|
||||||
small: { width: 400 },
|
|
||||||
medium: { width: 1000 },
|
|
||||||
large: { width: 1800 },
|
|
||||||
}}
|
|
||||||
ratio={1.2}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
<section class="about__process">
|
|
||||||
<div class="container grid">
|
|
||||||
<aside>
|
|
||||||
<div class="heading">
|
|
||||||
<h2 class="title-medium">{about.process_title}</h2>
|
|
||||||
<p class="text-xsmall">{about.process_subtitle}</p>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ol>
|
<div class="text text-small">
|
||||||
{#each about.process_steps as { title }, index}
|
{@html about.intro_text}
|
||||||
<li class:is-active={index === currentStep}>
|
</div>
|
||||||
<a href="#step-{index + 1}" class="title-big">
|
|
||||||
<span>{title}</span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
{/each}
|
|
||||||
</ol>
|
|
||||||
</aside>
|
|
||||||
|
|
||||||
<div class="steps">
|
|
||||||
{#each about.process_steps as { text, image, video_mp4, video_webm }, index}
|
|
||||||
<ProcessStep
|
|
||||||
{index} {text}
|
|
||||||
image={image ?? undefined}
|
|
||||||
video={video_mp4 && video_webm ? {
|
|
||||||
mp4: video_mp4.id,
|
|
||||||
webm: video_webm.id
|
|
||||||
} : undefined}
|
|
||||||
visible={index === currentStep}
|
|
||||||
/>
|
|
||||||
{/each}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</section>
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="about__photos" bind:this={photosGridEl}>
|
<section class="about__creation">
|
||||||
<div class="container-wide">
|
<div class="container grid">
|
||||||
<div class="photos-grid" style:--parallax-y="{parallaxPhotos}px">
|
<figure class="first-photo">
|
||||||
{#each photos as { image: { id }, title }, index}
|
<Image
|
||||||
<AboutGridPhoto class="grid-photo"
|
class="picture shadow-box-dark"
|
||||||
{id}
|
id={about.intro_firstphoto.id}
|
||||||
alt={title}
|
alt={about.intro_firstphoto.title}
|
||||||
disabled={fadedPhotosIndexes.includes(index)}
|
sizeKey="photo-list"
|
||||||
|
sizes={{
|
||||||
|
small: { width: 400 },
|
||||||
|
medium: { width: 600 },
|
||||||
|
large: { width: 800 },
|
||||||
|
}}
|
||||||
|
ratio={1.5}
|
||||||
/>
|
/>
|
||||||
{/each}
|
<figcaption class="text-info">
|
||||||
</div>
|
{about.intro_firstphoto_caption}<br>
|
||||||
</div>
|
in
|
||||||
</section>
|
<a href="/{about.intro_firstlocation.country.slug}/{about.intro_firstlocation.slug}" data-sveltekit-noscroll data-sveltekit-prefetch>
|
||||||
|
<img src="{getAssetUrlKey(about.intro_firstlocation.country.flag.id, 'square-small-jpg')}" width="32" height="32" alt="{about.intro_firstlocation.country.flag.title}">
|
||||||
|
<span>Naarm Australia (Melbourne)</span>
|
||||||
|
</a>
|
||||||
|
</figcaption>
|
||||||
|
</figure>
|
||||||
|
|
||||||
<section class="about__interest container grid">
|
<h2 class="title-small" data-reveal>{about.creation_title}</h2>
|
||||||
<div class="container grid">
|
<div class="heading text-huge" data-reveal>
|
||||||
<h2 class="title-xl">{about.contact_title}</h2>
|
{@html about.creation_heading}
|
||||||
<div class="blocks">
|
</div>
|
||||||
{#each about.contact_blocks as { title, text, link, button }}
|
|
||||||
<div class="block">
|
<div class="text text-small" data-reveal>
|
||||||
<h3 class="text-label">{title}</h3>
|
{@html about.creation_text}
|
||||||
<div class="text text-normal">
|
</div>
|
||||||
{@html text}
|
|
||||||
</div>
|
<figure class="picture portrait-photo" data-reveal-image>
|
||||||
<div class="button-container">
|
<Image
|
||||||
{#if link}
|
class="shadow-box-dark"
|
||||||
{#key emailCopied === link}
|
id={about.creation_portrait.id}
|
||||||
<div class="wrap"
|
alt={about.creation_portrait.title}
|
||||||
in:fly={{ y: 4, duration: 325, easing: quartOutSvelte, delay: 250 }}
|
sizeKey="photo-list"
|
||||||
out:fade={{ duration: 250, easing: quartOutSvelte }}
|
sizes={{
|
||||||
use:mailtoClipboard
|
small: { width: 400 },
|
||||||
on:copied={({ detail }) => {
|
medium: { width: 750 },
|
||||||
emailCopied = detail.email
|
}}
|
||||||
// Clear timeout and add timeout to hide message
|
ratio={1.425}
|
||||||
clearTimeout(emailCopiedTimeout)
|
/>
|
||||||
emailCopiedTimeout = setTimeout(() => emailCopied = null, 2500)
|
</figure>
|
||||||
}}
|
<span class="portrait-photo__caption text-info">
|
||||||
>
|
{about.creation_portrait_caption}
|
||||||
{#if emailCopied !== link}
|
</span>
|
||||||
<Button size="small" url="mailto:{link}" text={button} />
|
</div>
|
||||||
{:else}
|
</section>
|
||||||
<span class="clipboard">Email copied in clipboard</span>
|
|
||||||
{/if}
|
<section class="about__present">
|
||||||
</div>
|
<div class="container grid">
|
||||||
{/key}
|
<figure class="picture" data-reveal-image>
|
||||||
{/if}
|
<Image
|
||||||
</div>
|
class="shadow-box-dark"
|
||||||
|
id={about.present_image.id}
|
||||||
|
alt={about.present_image.title}
|
||||||
|
sizeKey="photo-list"
|
||||||
|
sizes={{
|
||||||
|
small: { width: 400 },
|
||||||
|
medium: { width: 600 },
|
||||||
|
large: { width: 800 },
|
||||||
|
}}
|
||||||
|
ratio={1.5}
|
||||||
|
/>
|
||||||
|
</figure>
|
||||||
|
|
||||||
|
<h2 class="title-small" data-reveal>{about.present_title}</h2>
|
||||||
|
<div class="text text-small" data-reveal>
|
||||||
|
<p>{about.present_text}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="heading text-big" data-reveal>
|
||||||
|
{@html about.present_heading}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="conclusion text-small" data-reveal>
|
||||||
|
<p>{about.present_conclusion}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{#if about.image_showcase}
|
||||||
|
<div class="about__showcase container grid">
|
||||||
|
<Image
|
||||||
|
id={about.image_showcase.id}
|
||||||
|
alt={about.image_showcase.title}
|
||||||
|
sizeKey="showcase"
|
||||||
|
sizes={{
|
||||||
|
small: { width: 400 },
|
||||||
|
medium: { width: 1000 },
|
||||||
|
large: { width: 1800 },
|
||||||
|
}}
|
||||||
|
ratio={1.2}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<section class="about__process">
|
||||||
|
<div class="container grid">
|
||||||
|
<aside>
|
||||||
|
<div class="heading">
|
||||||
|
<h2 class="title-medium">{about.process_title}</h2>
|
||||||
|
<p class="text-xsmall">{about.process_subtitle}</p>
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
|
||||||
|
<ol>
|
||||||
|
{#each about.process_steps as { title }, index}
|
||||||
|
<li class:is-active={index === currentStep}>
|
||||||
|
<a href="#step-{index + 1}" class="title-big">
|
||||||
|
<span>{title}</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{/each}
|
||||||
|
</ol>
|
||||||
|
</aside>
|
||||||
|
|
||||||
|
<div class="steps">
|
||||||
|
{#each about.process_steps as { text, image, video_mp4, video_webm }, index}
|
||||||
|
<ProcessStep
|
||||||
|
{index} {text}
|
||||||
|
image={image ?? undefined}
|
||||||
|
video={video_mp4 && video_webm ? {
|
||||||
|
mp4: video_mp4.id,
|
||||||
|
webm: video_webm.id
|
||||||
|
} : undefined}
|
||||||
|
visible={index === currentStep}
|
||||||
|
/>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</section>
|
||||||
</section>
|
|
||||||
|
<section class="about__photos" bind:this={photosGridEl}>
|
||||||
|
<div class="container-wide">
|
||||||
|
<div class="photos-grid" style:--parallax-y="{parallaxPhotos}px">
|
||||||
|
{#each photos as { image: { id }, title }, index}
|
||||||
|
<AboutGridPhoto class="grid-photo"
|
||||||
|
{id}
|
||||||
|
alt={title}
|
||||||
|
disabled={fadedPhotosIndexes.includes(index)}
|
||||||
|
/>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="about__interest container grid">
|
||||||
|
<div class="container grid">
|
||||||
|
<h2 class="title-xl">{about.contact_title}</h2>
|
||||||
|
<div class="blocks">
|
||||||
|
{#each about.contact_blocks as { title, text, link, button }}
|
||||||
|
<div class="block">
|
||||||
|
<h3 class="text-label">{title}</h3>
|
||||||
|
<div class="text text-normal">
|
||||||
|
{@html text}
|
||||||
|
</div>
|
||||||
|
<div class="button-container">
|
||||||
|
{#if link}
|
||||||
|
{#key emailCopied === link}
|
||||||
|
<div class="wrap"
|
||||||
|
in:fly={{ y: 4, duration: 325, easing: quartOutSvelte, delay: 250 }}
|
||||||
|
out:fade={{ duration: 250, easing: quartOutSvelte }}
|
||||||
|
use:mailtoClipboard
|
||||||
|
on:copied={({ detail }) => {
|
||||||
|
emailCopied = detail.email
|
||||||
|
// Clear timeout and add timeout to hide message
|
||||||
|
clearTimeout(emailCopiedTimeout)
|
||||||
|
emailCopiedTimeout = setTimeout(() => emailCopied = null, 2500)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{#if emailCopied !== link}
|
||||||
|
<Button size="small" url="mailto:{link}" text={button} />
|
||||||
|
{:else}
|
||||||
|
<span class="clipboard">Email copied in clipboard</span>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
{/key}
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
</PageTransition>
|
</PageTransition>
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
import InteractiveGlobe from '$components/organisms/InteractiveGlobe.svelte'
|
import InteractiveGlobe from '$components/organisms/InteractiveGlobe.svelte'
|
||||||
|
|
||||||
export let data: PageData
|
export let data: PageData
|
||||||
const { credits, credit } = data
|
const { credit } = data
|
||||||
|
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
@@ -63,22 +63,47 @@
|
|||||||
|
|
||||||
<Metas
|
<Metas
|
||||||
title="Credits – Houses Of"
|
title="Credits – Houses Of"
|
||||||
description={credits.text}
|
description={data.credits.text}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<PageTransition>
|
||||||
|
<main class="credits">
|
||||||
|
<Heading
|
||||||
|
text={data.credits.text}
|
||||||
|
/>
|
||||||
|
|
||||||
<PageTransition name="credits">
|
<section class="credits__list">
|
||||||
<Heading
|
<div class="grid container">
|
||||||
text={credits.text}
|
{#each data.credits.list as { title, credits }}
|
||||||
/>
|
<div class="credits__category grid">
|
||||||
|
<h2 class="title-small">{title}</h2>
|
||||||
|
<ul>
|
||||||
|
{#each credits as { name, role, website }}
|
||||||
|
<li>
|
||||||
|
<dl>
|
||||||
|
<dt>
|
||||||
|
{#if website}
|
||||||
|
<h3>
|
||||||
|
<a href={website} rel="noopener external" target="_blank" tabindex="0">{name}</a>
|
||||||
|
</h3>
|
||||||
|
{:else}
|
||||||
|
<h3>{name}</h3>
|
||||||
|
{/if}
|
||||||
|
</dt>
|
||||||
|
<dd>
|
||||||
|
{role}
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
</li>
|
||||||
|
{/each}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
|
||||||
<section class="credits__list">
|
|
||||||
<div class="grid container">
|
|
||||||
{#each credits.list as { title, credits }}
|
|
||||||
<div class="credits__category grid">
|
<div class="credits__category grid">
|
||||||
<h2 class="title-small">{title}</h2>
|
<h2 class="title-small">Photography</h2>
|
||||||
<ul>
|
<ul>
|
||||||
{#each credits as { name, role, website }}
|
{#each credit as { name, website, location }}
|
||||||
<li>
|
<li>
|
||||||
<dl>
|
<dl>
|
||||||
<dt>
|
<dt>
|
||||||
@@ -91,57 +116,33 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</dt>
|
</dt>
|
||||||
<dd>
|
<dd>
|
||||||
{role}
|
<ul data-sveltekit-noscroll>
|
||||||
|
{#each location as loc}
|
||||||
|
{#if loc.location_id}
|
||||||
|
<li>
|
||||||
|
<a href="/{loc.location_id.country.slug}/{loc.location_id.slug}" tabindex="0">
|
||||||
|
<Image
|
||||||
|
id={loc.location_id.country.flag.id}
|
||||||
|
sizeKey="square-small"
|
||||||
|
width={16}
|
||||||
|
height={16}
|
||||||
|
alt="Flag of {loc.location_id.country.slug}"
|
||||||
|
/>
|
||||||
|
<span>{loc.location_id.name}</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{/if}
|
||||||
|
{/each}
|
||||||
|
</ul>
|
||||||
</dd>
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
</li>
|
</li>
|
||||||
{/each}
|
{/each}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
|
||||||
|
|
||||||
<div class="credits__category grid">
|
|
||||||
<h2 class="title-small">Photography</h2>
|
|
||||||
<ul>
|
|
||||||
{#each credit as { name, website, location }}
|
|
||||||
<li>
|
|
||||||
<dl>
|
|
||||||
<dt>
|
|
||||||
{#if website}
|
|
||||||
<h3>
|
|
||||||
<a href={website} rel="noopener external" target="_blank" tabindex="0">{name}</a>
|
|
||||||
</h3>
|
|
||||||
{:else}
|
|
||||||
<h3>{name}</h3>
|
|
||||||
{/if}
|
|
||||||
</dt>
|
|
||||||
<dd>
|
|
||||||
<ul data-sveltekit-noscroll>
|
|
||||||
{#each location as loc}
|
|
||||||
{#if loc.location_id}
|
|
||||||
<li>
|
|
||||||
<a href="/{loc.location_id.country.slug}/{loc.location_id.slug}" tabindex="0">
|
|
||||||
<Image
|
|
||||||
id={loc.location_id.country.flag.id}
|
|
||||||
sizeKey="square-small"
|
|
||||||
width={16}
|
|
||||||
height={16}
|
|
||||||
alt="Flag of {loc.location_id.country.slug}"
|
|
||||||
/>
|
|
||||||
<span>{loc.location_id.name}</span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
{/if}
|
|
||||||
{/each}
|
|
||||||
</ul>
|
|
||||||
</dd>
|
|
||||||
</dl>
|
|
||||||
</li>
|
|
||||||
{/each}
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</section>
|
||||||
</section>
|
|
||||||
|
|
||||||
<InteractiveGlobe type="cropped" />
|
<InteractiveGlobe type="cropped" />
|
||||||
|
</main>
|
||||||
</PageTransition>
|
</PageTransition>
|
||||||
@@ -23,18 +23,20 @@
|
|||||||
image=""
|
image=""
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<PageTransition name="explore">
|
<PageTransition>
|
||||||
<Heading {text} />
|
<main class="explore">
|
||||||
|
<Heading {text} />
|
||||||
|
|
||||||
<section class="explore__locations">
|
<section class="explore__locations">
|
||||||
<InteractiveGlobe />
|
<InteractiveGlobe />
|
||||||
<Locations {locations} />
|
<Locations {locations} />
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="grid-modules is-spaced grid">
|
<section class="grid-modules is-spaced grid">
|
||||||
<div class="wrap">
|
<div class="wrap">
|
||||||
<ShopModule />
|
<ShopModule />
|
||||||
<NewsletterModule />
|
<NewsletterModule />
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
</main>
|
||||||
</PageTransition>
|
</PageTransition>
|
||||||
@@ -336,162 +336,164 @@
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
||||||
<PageTransition name="photos-page">
|
<PageTransition>
|
||||||
<section class="photos-page__intro"
|
<main class="photos-page">
|
||||||
class:is-passed={scrolledPastIntro}
|
<section class="photos-page__intro"
|
||||||
>
|
class:is-passed={scrolledPastIntro}
|
||||||
<ScrollingTitle tag="h1" text="Houses">
|
|
||||||
<SplitText text="Houses" mode="chars" />
|
|
||||||
</ScrollingTitle>
|
|
||||||
|
|
||||||
<DiscoverText />
|
|
||||||
|
|
||||||
<div class="filters"
|
|
||||||
class:is-over={filtersOver}
|
|
||||||
class:is-transitioning={filtersTransitioning}
|
|
||||||
class:is-visible={filtersVisible}
|
|
||||||
>
|
>
|
||||||
<div class="filters__bar">
|
<ScrollingTitle tag="h1" text="Houses">
|
||||||
<span class="text-label filters__label">Filter photos</span>
|
<SplitText text="Houses" mode="chars" />
|
||||||
<ul>
|
</ScrollingTitle>
|
||||||
<li>
|
|
||||||
<Select
|
|
||||||
name="country" id="filter_country"
|
|
||||||
options={[
|
|
||||||
{
|
|
||||||
value: defaultCountry,
|
|
||||||
name: 'Worldwide',
|
|
||||||
default: true,
|
|
||||||
selected: filterCountry === defaultCountry,
|
|
||||||
},
|
|
||||||
...countries.map(({ slug, name }) => ({
|
|
||||||
value: slug,
|
|
||||||
name,
|
|
||||||
selected: filterCountry === slug,
|
|
||||||
}))
|
|
||||||
]}
|
|
||||||
on:change={handleCountryChange}
|
|
||||||
value={filterCountry}
|
|
||||||
>
|
|
||||||
{#if countryFlagId}
|
|
||||||
<Image
|
|
||||||
class="icon"
|
|
||||||
id={countryFlagId}
|
|
||||||
sizeKey="square-small"
|
|
||||||
width={26} height={26}
|
|
||||||
alt="{filterCountry} flag"
|
|
||||||
/>
|
|
||||||
{:else}
|
|
||||||
<IconEarth class="icon" />
|
|
||||||
{/if}
|
|
||||||
</Select>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<Select
|
|
||||||
name="sort" id="filter_sort"
|
|
||||||
options={[
|
|
||||||
{
|
|
||||||
value: 'latest',
|
|
||||||
name: 'Latest',
|
|
||||||
default: true,
|
|
||||||
selected: filterSort === defaultSort
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 'oldest',
|
|
||||||
name: 'Oldest',
|
|
||||||
selected: filterSort === 'oldest'
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
on:change={handleSortChange}
|
|
||||||
value={filterSort}
|
|
||||||
>
|
|
||||||
<svg class="icon" width="24" height="24" viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg" aria-label="Sort icon">
|
|
||||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M15.878 15.93h-4.172c-.638 0-1.153.516-1.153 1.154 0 .639.515 1.154 1.153 1.154h4.172c.638 0 1.153-.515 1.153-1.154a1.152 1.152 0 0 0-1.153-1.153Zm3.244-5.396h-7.405c-.639 0-1.154.515-1.154 1.153 0 .639.515 1.154 1.154 1.154h7.405c.639 0 1.154-.515 1.154-1.154a1.145 1.145 0 0 0-1.154-1.153Zm3.244-5.408h-10.65c-.638 0-1.153.515-1.153 1.154 0 .639.515 1.154 1.154 1.154h10.65c.638 0 1.153-.515 1.153-1.154 0-.639-.515-1.154-1.154-1.154ZM7.37 20.679V3.376c0-.145-.03-.289-.082-.433a1.189 1.189 0 0 0-.628-.618 1.197 1.197 0 0 0-.886 0 1.045 1.045 0 0 0-.36.237c-.01 0-.01 0-.021.01L.82 7.145a1.156 1.156 0 0 0 0 1.638 1.156 1.156 0 0 0 1.637 0l2.596-2.596v11.7l-2.596-2.595a1.156 1.156 0 0 0-1.637 0 1.156 1.156 0 0 0 0 1.638l4.573 4.573c.103.103.237.185.37.247.135.062.289.082.433.082h.02c.145 0 .3-.03.433-.093a1.14 1.14 0 0 0 .629-.628.987.987 0 0 0 .092-.432Z" />
|
|
||||||
</svg>
|
|
||||||
</Select>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<div class="filters__actions">
|
<DiscoverText />
|
||||||
{#if filtered}
|
|
||||||
<button class="reset button-link"
|
|
||||||
on:click={resetFiltered}
|
|
||||||
transition:fly={{ y: 4, duration: 600, easing: quartOutSvelte }}
|
|
||||||
>
|
|
||||||
Reset
|
|
||||||
</button>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="photos-page__content" bind:this={photosContentEl} style:--margin-sides="{sideMargins}px">
|
<div class="filters"
|
||||||
<div class="grid container">
|
class:is-over={filtersOver}
|
||||||
{#if photos}
|
class:is-transitioning={filtersTransitioning}
|
||||||
<div class="photos-page__grid" bind:this={photosGridEl} data-sveltekit-noscroll data-sveltekit-prefetch>
|
class:is-visible={filtersVisible}
|
||||||
{#each photos as { id, image, slug, location, title, city }, index (id)}
|
>
|
||||||
<figure class="photo shadow-photo">
|
<div class="filters__bar">
|
||||||
<a href="/{location.country.slug}/{location.slug}/{slug}" tabindex="0">
|
<span class="text-label filters__label">Filter photos</span>
|
||||||
<Image
|
<ul>
|
||||||
id={image.id}
|
<li>
|
||||||
sizeKey="photo-grid"
|
<Select
|
||||||
sizes={{
|
name="country" id="filter_country"
|
||||||
small: { width: 500 },
|
options={[
|
||||||
medium: { width: 900 },
|
{
|
||||||
large: { width: 1440 },
|
value: defaultCountry,
|
||||||
}}
|
name: 'Worldwide',
|
||||||
ratio={1.5}
|
default: true,
|
||||||
alt={image.title}
|
selected: filterCountry === defaultCountry,
|
||||||
/>
|
},
|
||||||
</a>
|
...countries.map(({ slug, name }) => ({
|
||||||
<figcaption>
|
value: slug,
|
||||||
<PostCard
|
name,
|
||||||
street={title}
|
selected: filterCountry === slug,
|
||||||
location={city ? `${city}, ${location.name}` : location.name}
|
}))
|
||||||
region={location.region}
|
]}
|
||||||
country={location.country.name}
|
on:change={handleCountryChange}
|
||||||
flagId={location.country.flag.id}
|
value={filterCountry}
|
||||||
size={isSmall(index) ? 'small' : null}
|
>
|
||||||
/>
|
{#if countryFlagId}
|
||||||
</figcaption>
|
<Image
|
||||||
</figure>
|
class="icon"
|
||||||
{/each}
|
id={countryFlagId}
|
||||||
</div>
|
sizeKey="square-small"
|
||||||
|
width={26} height={26}
|
||||||
|
alt="{filterCountry} flag"
|
||||||
|
/>
|
||||||
|
{:else}
|
||||||
|
<IconEarth class="icon" />
|
||||||
|
{/if}
|
||||||
|
</Select>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<Select
|
||||||
|
name="sort" id="filter_sort"
|
||||||
|
options={[
|
||||||
|
{
|
||||||
|
value: 'latest',
|
||||||
|
name: 'Latest',
|
||||||
|
default: true,
|
||||||
|
selected: filterSort === defaultSort
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'oldest',
|
||||||
|
name: 'Oldest',
|
||||||
|
selected: filterSort === 'oldest'
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
on:change={handleSortChange}
|
||||||
|
value={filterSort}
|
||||||
|
>
|
||||||
|
<svg class="icon" width="24" height="24" viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg" aria-label="Sort icon">
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M15.878 15.93h-4.172c-.638 0-1.153.516-1.153 1.154 0 .639.515 1.154 1.153 1.154h4.172c.638 0 1.153-.515 1.153-1.154a1.152 1.152 0 0 0-1.153-1.153Zm3.244-5.396h-7.405c-.639 0-1.154.515-1.154 1.153 0 .639.515 1.154 1.154 1.154h7.405c.639 0 1.154-.515 1.154-1.154a1.145 1.145 0 0 0-1.154-1.153Zm3.244-5.408h-10.65c-.638 0-1.153.515-1.153 1.154 0 .639.515 1.154 1.154 1.154h10.65c.638 0 1.153-.515 1.153-1.154 0-.639-.515-1.154-1.154-1.154ZM7.37 20.679V3.376c0-.145-.03-.289-.082-.433a1.189 1.189 0 0 0-.628-.618 1.197 1.197 0 0 0-.886 0 1.045 1.045 0 0 0-.36.237c-.01 0-.01 0-.021.01L.82 7.145a1.156 1.156 0 0 0 0 1.638 1.156 1.156 0 0 0 1.637 0l2.596-2.596v11.7l-2.596-2.595a1.156 1.156 0 0 0-1.637 0 1.156 1.156 0 0 0 0 1.638l4.573 4.573c.103.103.237.185.37.247.135.062.289.082.433.082h.02c.145 0 .3-.03.433-.093a1.14 1.14 0 0 0 .629-.628.987.987 0 0 0 .092-.432Z" />
|
||||||
|
</svg>
|
||||||
|
</Select>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
<div class="controls grid">
|
<div class="filters__actions">
|
||||||
<p class="controls__date" title={dayjs(latestPhoto.date_created).format('DD/MM/YYYY, hh:mm')}>
|
{#if filtered}
|
||||||
Last updated: <time datetime={dayjs(latestPhoto.date_created).format('YYYY-MM-DD')}>{dayjs().to(dayjs(latestPhoto.date_created))}</time>
|
<button class="reset button-link"
|
||||||
</p>
|
on:click={resetFiltered}
|
||||||
|
transition:fly={{ y: 4, duration: 600, easing: quartOutSvelte }}
|
||||||
<Button
|
>
|
||||||
tag="button"
|
Reset
|
||||||
text={!ended ? 'See more photos' : "You've seen it all!"}
|
</button>
|
||||||
size="large" color="beige"
|
{/if}
|
||||||
on:click={loadMorePhotos}
|
|
||||||
disabled={ended}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div class="controls__count">
|
|
||||||
<span class="current">{currentPhotosAmount}</span>
|
|
||||||
<span>/</span>
|
|
||||||
<span class="total">{totalPhotos}</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{:else if !filteredCountryExists}
|
</div>
|
||||||
<div class="photos-page__message">
|
</section>
|
||||||
<p>
|
|
||||||
<strong>{$page.url.searchParams.get('country').replace(/(^|\s)\S/g, letter => letter.toUpperCase())}</strong> is not available… yet 👀
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
<div class="grid-modules">
|
<section class="photos-page__content" bind:this={photosContentEl} style:--margin-sides="{sideMargins}px">
|
||||||
<div class="wrap">
|
<div class="grid container">
|
||||||
<ShopModule />
|
{#if photos}
|
||||||
<NewsletterModule theme="light" />
|
<div class="photos-page__grid" bind:this={photosGridEl} data-sveltekit-noscroll data-sveltekit-prefetch>
|
||||||
|
{#each photos as { id, image, slug, location, title, city }, index (id)}
|
||||||
|
<figure class="photo shadow-photo">
|
||||||
|
<a href="/{location.country.slug}/{location.slug}/{slug}" tabindex="0">
|
||||||
|
<Image
|
||||||
|
id={image.id}
|
||||||
|
sizeKey="photo-grid"
|
||||||
|
sizes={{
|
||||||
|
small: { width: 500 },
|
||||||
|
medium: { width: 900 },
|
||||||
|
large: { width: 1440 },
|
||||||
|
}}
|
||||||
|
ratio={1.5}
|
||||||
|
alt={image.title}
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
<figcaption>
|
||||||
|
<PostCard
|
||||||
|
street={title}
|
||||||
|
location={city ? `${city}, ${location.name}` : location.name}
|
||||||
|
region={location.region}
|
||||||
|
country={location.country.name}
|
||||||
|
flagId={location.country.flag.id}
|
||||||
|
size={isSmall(index) ? 'small' : null}
|
||||||
|
/>
|
||||||
|
</figcaption>
|
||||||
|
</figure>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="controls grid">
|
||||||
|
<p class="controls__date" title={dayjs(latestPhoto.date_created).format('DD/MM/YYYY, hh:mm')}>
|
||||||
|
Last updated: <time datetime={dayjs(latestPhoto.date_created).format('YYYY-MM-DD')}>{dayjs().to(dayjs(latestPhoto.date_created))}</time>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
tag="button"
|
||||||
|
text={!ended ? 'See more photos' : "You've seen it all!"}
|
||||||
|
size="large" color="beige"
|
||||||
|
on:click={loadMorePhotos}
|
||||||
|
disabled={ended}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div class="controls__count">
|
||||||
|
<span class="current">{currentPhotosAmount}</span>
|
||||||
|
<span>/</span>
|
||||||
|
<span class="total">{totalPhotos}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{:else if !filteredCountryExists}
|
||||||
|
<div class="photos-page__message">
|
||||||
|
<p>
|
||||||
|
<strong>{$page.url.searchParams.get('country').replace(/(^|\s)\S/g, letter => letter.toUpperCase())}</strong> is not available… yet 👀
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<div class="grid-modules">
|
||||||
|
<div class="wrap">
|
||||||
|
<ShopModule />
|
||||||
|
<NewsletterModule theme="light" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</section>
|
||||||
</section>
|
</main>
|
||||||
</PageTransition>
|
</PageTransition>
|
||||||
@@ -25,17 +25,19 @@
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
||||||
<PageTransition name="shop-page">
|
<PageTransition>
|
||||||
<ShopHeader />
|
<main class="shop-page">
|
||||||
|
<ShopHeader />
|
||||||
|
|
||||||
<section class="shop-page__error">
|
<section class="shop-page__error">
|
||||||
<div class="container grid">
|
<div class="container grid">
|
||||||
<div class="inner">
|
<div class="inner">
|
||||||
<h2 class="title-big">Uh oh!</h2>
|
<h2 class="title-big">Uh oh!</h2>
|
||||||
<p class="text-medium">{errors[$page.status].message}</p>
|
<p class="text-medium">{errors[$page.status].message}</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</section>
|
||||||
</section>
|
|
||||||
|
|
||||||
<PostersGrid {posters} />
|
<PostersGrid {posters} />
|
||||||
|
</main>
|
||||||
</PageTransition>
|
</PageTransition>
|
||||||
@@ -26,13 +26,15 @@
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
||||||
<PageTransition name="shop-page">
|
<PageTransition>
|
||||||
<ShopHeader {product} />
|
<main class="shop-page">
|
||||||
|
<ShopHeader {product} />
|
||||||
|
|
||||||
<PosterLayout
|
<PosterLayout
|
||||||
product={product}
|
product={product}
|
||||||
shopProduct={shopProduct}
|
shopProduct={shopProduct}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<PostersGrid {posters} />
|
<PostersGrid {posters} />
|
||||||
|
</main>
|
||||||
</PageTransition>
|
</PageTransition>
|
||||||
@@ -24,13 +24,15 @@
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
||||||
<PageTransition name="shop-page">
|
<PageTransition>
|
||||||
<ShopHeader product={data.product} />
|
<main class="shop-page">
|
||||||
|
<ShopHeader product={data.product} />
|
||||||
|
|
||||||
<PosterLayout
|
<PosterLayout
|
||||||
product={data.product}
|
product={data.product}
|
||||||
shopProduct={data.shopProduct}
|
shopProduct={data.shopProduct}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<PostersGrid {posters} />
|
<PostersGrid {posters} />
|
||||||
|
</main>
|
||||||
</PageTransition>
|
</PageTransition>
|
||||||
@@ -65,32 +65,34 @@
|
|||||||
description="Subscribe to the Houses Of newsletter to be notified when new photos or locations are added to the site and when more prints are available on our shop"
|
description="Subscribe to the Houses Of newsletter to be notified when new photos or locations are added to the site and when more prints are available on our shop"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<PageTransition name="subscribe">
|
<PageTransition>
|
||||||
<div class="subscribe__top">
|
<main class="subscribe">
|
||||||
<Heading
|
<div class="subscribe__top">
|
||||||
text={data.newsletter_page_text}
|
<Heading
|
||||||
/>
|
text={data.newsletter_page_text}
|
||||||
|
/>
|
||||||
|
|
||||||
<EmailForm />
|
<EmailForm />
|
||||||
</div>
|
|
||||||
|
|
||||||
<section class="subscribe__issues">
|
|
||||||
<h2 class="title-small">Latest Issue</h2>
|
|
||||||
<div class="issue-container">
|
|
||||||
<NewsletterIssue size="large" date={latestIssue.date_sent} {...latestIssue} />
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if issues.length > 1}
|
<section class="subscribe__issues">
|
||||||
<h2 class="title-small">Past Issues</h2>
|
<h2 class="title-small">Latest Issue</h2>
|
||||||
<ul>
|
<div class="issue-container">
|
||||||
{#each issues.slice(1) as { issue, title, date_sent: date, link, thumbnail }}
|
<NewsletterIssue size="large" date={latestIssue.date_sent} {...latestIssue} />
|
||||||
<li class="issue-container">
|
</div>
|
||||||
<NewsletterIssue {issue} {title} {link} {thumbnail} {date} />
|
|
||||||
</li>
|
|
||||||
{/each}
|
|
||||||
</ul>
|
|
||||||
{/if}
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<InteractiveGlobe type="cropped" />
|
{#if issues.length > 1}
|
||||||
|
<h2 class="title-small">Past Issues</h2>
|
||||||
|
<ul>
|
||||||
|
{#each issues.slice(1) as { issue, title, date_sent: date, link, thumbnail }}
|
||||||
|
<li class="issue-container">
|
||||||
|
<NewsletterIssue {issue} {title} {link} {thumbnail} {date} />
|
||||||
|
</li>
|
||||||
|
{/each}
|
||||||
|
</ul>
|
||||||
|
{/if}
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<InteractiveGlobe type="cropped" />
|
||||||
|
</main>
|
||||||
</PageTransition>
|
</PageTransition>
|
||||||
@@ -23,25 +23,27 @@
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
||||||
<PageTransition name="terms">
|
<PageTransition>
|
||||||
<Heading text="Everything you need to know about using our website or buying our products" />
|
<main class="terms">
|
||||||
|
<Heading text="Everything you need to know about using our website or buying our products" />
|
||||||
|
|
||||||
<section class="terms__categories">
|
<section class="terms__categories">
|
||||||
<div class="container grid">
|
<div class="container grid">
|
||||||
{#each legal.terms as { title, text }, index}
|
{#each legal.terms as { title, text }, index}
|
||||||
<article class="terms__section grid">
|
<article class="terms__section grid">
|
||||||
<h2 class="title-small">{index + 1}. {title}</h2>
|
<h2 class="title-small">{index + 1}. {title}</h2>
|
||||||
<div class="text text-info">
|
<div class="text text-info">
|
||||||
{@html text}
|
{@html text}
|
||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
{/each}
|
{/each}
|
||||||
|
|
||||||
<footer>
|
<footer>
|
||||||
<p class="text-info">
|
<p class="text-info">
|
||||||
Updated: <time datetime={dayjs(legal.date_updated).format('YYYY-MM-DD')}>{dayjs().to(dayjs(legal.date_updated))}</time>
|
Updated: <time datetime={dayjs(legal.date_updated).format('YYYY-MM-DD')}>{dayjs().to(dayjs(legal.date_updated))}</time>
|
||||||
</p>
|
</p>
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
</main>
|
||||||
</PageTransition>
|
</PageTransition>
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
:global(.about) {
|
.about {
|
||||||
:global(.picture) {
|
:global(.picture) {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background: $color-primary-tertiary20;
|
background: $color-primary-tertiary20;
|
||||||
@@ -9,9 +9,7 @@
|
|||||||
border-radius: 16px;
|
border-radius: 16px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.about {
|
|
||||||
/*
|
/*
|
||||||
** Introduction
|
** Introduction
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -23,9 +23,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
:global(.page-error) {
|
|
||||||
// Globe
|
// Globe
|
||||||
:global(.globe) {
|
:global(.globe) {
|
||||||
margin-top: 96px;
|
margin-top: 96px;
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
// Explore Page
|
// Explore Page
|
||||||
:global(.explore) {
|
.explore {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
|
||||||
:global(.explore__locations) {
|
&__locations {
|
||||||
@include bp (sm, max) {
|
@include bp (sm, max) {
|
||||||
margin-top: 72px;
|
margin-top: 72px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,7 @@
|
|||||||
:global(.homepage) {
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Homepage
|
// Homepage
|
||||||
.homepage {
|
.homepage {
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
// Intro Section
|
// Intro Section
|
||||||
&__intro {
|
&__intro {
|
||||||
padding-bottom: calc(96px + 20vw);
|
padding-bottom: calc(96px + 20vw);
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
:global(.location-page) {
|
|
||||||
background: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Location Page
|
// Location Page
|
||||||
.location-page {
|
.location-page {
|
||||||
|
background: #fff;
|
||||||
|
|
||||||
// Intro
|
// Intro
|
||||||
&__intro {
|
&__intro {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|||||||
@@ -1,5 +1,34 @@
|
|||||||
:global(.shop-page) {
|
.shop-page {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
|
// Error
|
||||||
|
&__error {
|
||||||
|
padding: 64px 0;
|
||||||
|
background: $color-cream;
|
||||||
|
color: $color-text;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
@include bp (sm) {
|
||||||
|
padding: clamp(64px, 12vw, 160px) 0;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(.inner) {
|
||||||
|
grid-column: 1 / span 8;
|
||||||
|
|
||||||
|
@include bp (sm) {
|
||||||
|
grid-column: 3 / span 12;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
:global(h2) {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
color: $color-secondary;
|
||||||
|
|
||||||
|
@include bp (sm) {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Nav
|
// Nav
|
||||||
@@ -21,40 +50,11 @@
|
|||||||
--inset: 32px;
|
--inset: 32px;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// Visible state
|
// Visible state
|
||||||
:global(.shop-location.is-visible) {
|
&.is-visible {
|
||||||
transform: translate3d(0,0,0);
|
transform: translate3d(0,0,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Error
|
|
||||||
:global(.shop-page__error) {
|
|
||||||
padding: 64px 0;
|
|
||||||
background: $color-cream;
|
|
||||||
color: $color-text;
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
@include bp (sm) {
|
|
||||||
padding: clamp(64px, 12vw, 160px) 0;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
:global(.inner) {
|
|
||||||
grid-column: 1 / span 8;
|
|
||||||
|
|
||||||
@include bp (sm) {
|
|
||||||
grid-column: 3 / span 12;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
:global(h2) {
|
|
||||||
margin-bottom: 8px;
|
|
||||||
color: $color-secondary;
|
|
||||||
|
|
||||||
@include bp (sm) {
|
|
||||||
margin-bottom: 16px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notifications
|
// Notifications
|
||||||
|
|||||||
@@ -22,12 +22,13 @@
|
|||||||
|
|
||||||
// Past Issues
|
// Past Issues
|
||||||
&__issues {
|
&__issues {
|
||||||
margin: 64px auto 0;
|
margin: 64px auto 96px;
|
||||||
padding: 0 20px;
|
padding: 0 20px;
|
||||||
|
|
||||||
@include bp (sm) {
|
@include bp (sm) {
|
||||||
max-width: 800px;
|
max-width: 800px;
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
|
margin-bottom: 156px;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Title
|
// Title
|
||||||
@@ -62,13 +63,4 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Globe
|
|
||||||
:global(.subscribe .globe) {
|
|
||||||
margin-top: 96px;
|
|
||||||
|
|
||||||
@include bp (sm) {
|
|
||||||
margin-top: 156px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
:global(.photo-page) {
|
.photo-page {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
height: var(--vh);
|
height: var(--vh);
|
||||||
@@ -16,420 +16,418 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.photo-page {
|
// Carousel
|
||||||
// Carousel
|
&__carousel {
|
||||||
&__carousel {
|
position: absolute;
|
||||||
position: absolute;
|
top: 0;
|
||||||
top: 0;
|
left: 50%;
|
||||||
left: 50%;
|
transform: translate3d(-50%, 0, 0);
|
||||||
transform: translate3d(-50%, 0, 0);
|
grid-column: 1 / -1;
|
||||||
grid-column: 1 / -1;
|
display: grid;
|
||||||
display: grid;
|
grid-row-gap: 20px;
|
||||||
grid-row-gap: 20px;
|
width: calc(100% - 40px);
|
||||||
width: calc(100% - 40px);
|
height: 100%;
|
||||||
height: 100%;
|
max-width: 720px;
|
||||||
max-width: 720px;
|
position: relative;
|
||||||
|
|
||||||
|
@include bp (md) {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
max-width: none;
|
||||||
@include bp (md) {
|
margin: auto 0;
|
||||||
position: relative;
|
grid-column: 2 / span 17;
|
||||||
max-width: none;
|
grid-row-gap: 40px;
|
||||||
margin: auto 0;
|
transform: translate3d(-50%, 2.5%, 0);
|
||||||
grid-column: 2 / span 17;
|
|
||||||
grid-row-gap: 40px;
|
|
||||||
transform: translate3d(-50%, 2.5%, 0);
|
|
||||||
}
|
|
||||||
@include bp (sd) {
|
|
||||||
grid-column: 3 / span 16;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@include bp (sd) {
|
||||||
// Images
|
grid-column: 3 / span 16;
|
||||||
&__images {
|
|
||||||
position: relative;
|
|
||||||
width: 100%;
|
|
||||||
margin: auto auto 0;
|
|
||||||
padding-top: 66.66%;
|
|
||||||
touch-action: none;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&__picture {
|
// Images
|
||||||
--opacity: 1;
|
&__images {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
margin: auto auto 0;
|
||||||
|
padding-top: 66.66%;
|
||||||
|
touch-action: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__picture {
|
||||||
|
--opacity: 1;
|
||||||
|
--scale: 0.6;
|
||||||
|
--rotate: 0deg;
|
||||||
|
--offset-x: 0%;
|
||||||
|
--offset-y: 0%;
|
||||||
|
position: absolute;
|
||||||
|
z-index: 8;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
transform: translateZ(0);
|
||||||
|
will-change: transform, opacity;
|
||||||
|
|
||||||
|
@include bp (md) {
|
||||||
--scale: 0.6;
|
--scale: 0.6;
|
||||||
--rotate: 0deg;
|
--rotate: 5deg;
|
||||||
--offset-x: 0%;
|
--offset-x: 28.5%;
|
||||||
--offset-y: 0%;
|
--offset-y: 0%;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
transform-origin: bottom right;
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(.photo) {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 8;
|
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
transform: translateZ(0);
|
transform: translate3d(var(--offset-x), var(--offset-y), 0) scale(var(--scale)) rotate(var(--rotate));
|
||||||
will-change: transform, opacity;
|
transition: opacity 1s var(--ease-quart), transform 1s var(--ease-quart);
|
||||||
|
will-change: transform;
|
||||||
|
box-shadow:
|
||||||
|
0 12px 12px rgba(#000, 0.15),
|
||||||
|
0 20px 20px rgba(#000, 0.15),
|
||||||
|
0 48px 48px rgba(#000, 0.15);
|
||||||
|
|
||||||
@include bp (md) {
|
:global(picture) {
|
||||||
--scale: 0.6;
|
|
||||||
--rotate: 5deg;
|
|
||||||
--offset-x: 28.5%;
|
|
||||||
--offset-y: 0%;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
transform-origin: bottom right;
|
|
||||||
}
|
|
||||||
|
|
||||||
:global(.photo) {
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
transform: translate3d(var(--offset-x), var(--offset-y), 0) scale(var(--scale)) rotate(var(--rotate));
|
overflow: hidden;
|
||||||
transition: opacity 1s var(--ease-quart), transform 1s var(--ease-quart);
|
background: $color-primary;
|
||||||
will-change: transform;
|
cursor: default;
|
||||||
box-shadow:
|
|
||||||
0 12px 12px rgba(#000, 0.15),
|
|
||||||
0 20px 20px rgba(#000, 0.15),
|
|
||||||
0 48px 48px rgba(#000, 0.15);
|
|
||||||
|
|
||||||
:global(picture) {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
overflow: hidden;
|
|
||||||
background: $color-primary;
|
|
||||||
cursor: default;
|
|
||||||
}
|
|
||||||
:global(img) {
|
|
||||||
display: block;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
object-fit: cover;
|
|
||||||
opacity: var(--opacity);
|
|
||||||
transform: translateZ(0);
|
|
||||||
pointer-events: none;
|
|
||||||
user-select: none;
|
|
||||||
transition: opacity 1s var(--ease-quart);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
:global(img) {
|
||||||
// Ratio is not landscape
|
display: block;
|
||||||
:global(.not-landscape) {
|
width: 100%;
|
||||||
:global(img) {
|
height: 100%;
|
||||||
object-fit: contain;
|
object-fit: cover;
|
||||||
}
|
opacity: var(--opacity);
|
||||||
}
|
transform: translateZ(0);
|
||||||
|
|
||||||
// Hidden photo over
|
|
||||||
&.is-0 {
|
|
||||||
--scale: 1.03;
|
|
||||||
--rotate: 0deg;
|
|
||||||
--offset-x: 0%;
|
|
||||||
--offset-y: -7%;
|
|
||||||
z-index: 9;
|
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
|
user-select: none;
|
||||||
:global(.photo) {
|
transition: opacity 1s var(--ease-quart);
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@include bp (md) {
|
|
||||||
--scale: 1.075;
|
|
||||||
--rotate: -1deg;
|
|
||||||
--offset-x: -9%;
|
|
||||||
--offset-y: 0%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// First visible photo
|
|
||||||
&.is-1 {
|
|
||||||
--scale: 1;
|
|
||||||
--rotate: 0deg;
|
|
||||||
--offset-y: 0%;
|
|
||||||
|
|
||||||
@include bp (md) {
|
|
||||||
--offset-x: 0%;
|
|
||||||
--offset-y: 0%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&.is-2 {
|
|
||||||
--scale: 0.9;
|
|
||||||
--opacity: 0.75;
|
|
||||||
--offset-y: 12%;
|
|
||||||
z-index: 7;
|
|
||||||
|
|
||||||
@include bp (md) {
|
|
||||||
--scale: 0.9;
|
|
||||||
--rotate: 1deg;
|
|
||||||
--offset-x: 9.5%;
|
|
||||||
--offset-y: 0%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&.is-3 {
|
|
||||||
--scale: 0.83;
|
|
||||||
--opacity: 0.55;
|
|
||||||
--offset-y: 20%;
|
|
||||||
z-index: 6;
|
|
||||||
|
|
||||||
@include bp (md) {
|
|
||||||
--scale: 0.83;
|
|
||||||
--rotate: 2deg;
|
|
||||||
--offset-x: 16.25%;
|
|
||||||
--offset-y: 0%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&.is-4 {
|
|
||||||
--scale: 0.75;
|
|
||||||
--opacity: 0.45;
|
|
||||||
--offset-y: 27.5%;
|
|
||||||
z-index: 5;
|
|
||||||
|
|
||||||
@include bp (md) {
|
|
||||||
--scale: 0.75;
|
|
||||||
--rotate: 3deg;
|
|
||||||
--offset-x: 22%;
|
|
||||||
--offset-y: 0%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&.is-5 {
|
|
||||||
--scale: 0.68;
|
|
||||||
--opacity: 0.25;
|
|
||||||
--offset-y: 33%;
|
|
||||||
z-index: 4;
|
|
||||||
|
|
||||||
@include bp (md) {
|
|
||||||
--scale: 0.68;
|
|
||||||
--rotate: 4deg;
|
|
||||||
--offset-x: 27%;
|
|
||||||
--offset-y: 0%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&.is-6 {
|
|
||||||
--opacity: 0.25;
|
|
||||||
z-index: 3;
|
|
||||||
|
|
||||||
:global(.photo) {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&.is-7 {
|
|
||||||
:global(.photo) {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Infos
|
// Ratio is not landscape
|
||||||
&__info {
|
:global(.not-landscape) {
|
||||||
bottom: 0;
|
:global(img) {
|
||||||
margin-top: auto;
|
object-fit: contain;
|
||||||
margin-bottom: 40px;
|
|
||||||
padding: 0 20px;
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
@include bp (md) {
|
|
||||||
position: static;
|
|
||||||
margin-top: 0;
|
|
||||||
padding: 0;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
@include bp (lg) {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 50% 50%;
|
|
||||||
align-items: baseline;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
color: $color-secondary;
|
|
||||||
font-size: clamp(#{rem(18px)}, 5.5vw, #{rem(28px)});
|
|
||||||
line-height: 1.1;
|
|
||||||
|
|
||||||
@include bp (md) {
|
|
||||||
font-size: rem(32px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Details
|
|
||||||
.detail {
|
|
||||||
display: inline-block;
|
|
||||||
align-items: center;
|
|
||||||
color: rgba($color-tertiary, 0.7);
|
|
||||||
line-height: 1.5;
|
|
||||||
|
|
||||||
@include bp (lg) {
|
|
||||||
margin-left: auto;
|
|
||||||
text-align: right;
|
|
||||||
padding-left: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: inherit;
|
|
||||||
text-decoration: none;
|
|
||||||
transition: color 0.3s;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: $color-tertiary;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Icon
|
|
||||||
:global(.icon) {
|
|
||||||
display: inline-block;
|
|
||||||
width: 17px;
|
|
||||||
height: 17px;
|
|
||||||
margin-top: -5px;
|
|
||||||
margin-right: 4px;
|
|
||||||
}
|
|
||||||
// Separator
|
|
||||||
.sep {
|
|
||||||
display: inline-block;
|
|
||||||
margin: 0 4px;
|
|
||||||
line-height: 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Index
|
// Hidden photo over
|
||||||
&__index {
|
&.is-0 {
|
||||||
position: absolute;
|
--scale: 1.03;
|
||||||
z-index: 1;
|
--rotate: 0deg;
|
||||||
left: 50%;
|
--offset-x: 0%;
|
||||||
bottom: calc(91% + 1vw);
|
--offset-y: -7%;
|
||||||
display: block;
|
z-index: 9;
|
||||||
line-height: 1;
|
|
||||||
color: rgba($color-tertiary, 0.4);
|
|
||||||
transform: translate3d(-50%, 0, 0);
|
|
||||||
white-space: nowrap;
|
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
user-select: none;
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
@include bp (md, max) {
|
:global(.photo) {
|
||||||
font-size: clamp(#{rem(80px)}, 24vw, #{rem(120px)});
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@include bp (md) {
|
@include bp (md) {
|
||||||
top: 50%;
|
--scale: 1.075;
|
||||||
left: auto;
|
--rotate: -1deg;
|
||||||
right: calc(-1 * min(30vw, 400px));
|
--offset-x: -9%;
|
||||||
width: 350px;
|
--offset-y: 0%;
|
||||||
text-align: center;
|
|
||||||
bottom: auto;
|
|
||||||
transform: translate3d(0, -50%, 0);
|
|
||||||
}
|
}
|
||||||
@include bp (lg) {
|
}
|
||||||
right: calc(-1 * min(25vw, 460px));
|
// First visible photo
|
||||||
|
&.is-1 {
|
||||||
|
--scale: 1;
|
||||||
|
--rotate: 0deg;
|
||||||
|
--offset-y: 0%;
|
||||||
|
|
||||||
|
@include bp (md) {
|
||||||
|
--offset-x: 0%;
|
||||||
|
--offset-y: 0%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.is-2 {
|
||||||
|
--scale: 0.9;
|
||||||
|
--opacity: 0.75;
|
||||||
|
--offset-y: 12%;
|
||||||
|
z-index: 7;
|
||||||
|
|
||||||
|
@include bp (md) {
|
||||||
|
--scale: 0.9;
|
||||||
|
--rotate: 1deg;
|
||||||
|
--offset-x: 9.5%;
|
||||||
|
--offset-y: 0%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.is-3 {
|
||||||
|
--scale: 0.83;
|
||||||
|
--opacity: 0.55;
|
||||||
|
--offset-y: 20%;
|
||||||
|
z-index: 6;
|
||||||
|
|
||||||
|
@include bp (md) {
|
||||||
|
--scale: 0.83;
|
||||||
|
--rotate: 2deg;
|
||||||
|
--offset-x: 16.25%;
|
||||||
|
--offset-y: 0%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.is-4 {
|
||||||
|
--scale: 0.75;
|
||||||
|
--opacity: 0.45;
|
||||||
|
--offset-y: 27.5%;
|
||||||
|
z-index: 5;
|
||||||
|
|
||||||
|
@include bp (md) {
|
||||||
|
--scale: 0.75;
|
||||||
|
--rotate: 3deg;
|
||||||
|
--offset-x: 22%;
|
||||||
|
--offset-y: 0%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.is-5 {
|
||||||
|
--scale: 0.68;
|
||||||
|
--opacity: 0.25;
|
||||||
|
--offset-y: 33%;
|
||||||
|
z-index: 4;
|
||||||
|
|
||||||
|
@include bp (md) {
|
||||||
|
--scale: 0.68;
|
||||||
|
--rotate: 4deg;
|
||||||
|
--offset-x: 27%;
|
||||||
|
--offset-y: 0%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.is-6 {
|
||||||
|
--opacity: 0.25;
|
||||||
|
z-index: 3;
|
||||||
|
|
||||||
|
:global(.photo) {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.is-7 {
|
||||||
|
:global(.photo) {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Infos
|
||||||
|
&__info {
|
||||||
|
bottom: 0;
|
||||||
|
margin-top: auto;
|
||||||
|
margin-bottom: 40px;
|
||||||
|
padding: 0 20px;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
@include bp (md) {
|
||||||
|
position: static;
|
||||||
|
margin-top: 0;
|
||||||
|
padding: 0;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
@include bp (lg) {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 50% 50%;
|
||||||
|
align-items: baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
color: $color-secondary;
|
||||||
|
font-size: clamp(#{rem(18px)}, 5.5vw, #{rem(28px)});
|
||||||
|
line-height: 1.1;
|
||||||
|
|
||||||
|
@include bp (md) {
|
||||||
|
font-size: rem(32px);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Controls
|
// Details
|
||||||
&__controls {
|
.detail {
|
||||||
display: none;
|
display: inline-block;
|
||||||
|
align-items: center;
|
||||||
|
color: rgba($color-tertiary, 0.7);
|
||||||
|
line-height: 1.5;
|
||||||
|
|
||||||
@include bp (md) {
|
@include bp (lg) {
|
||||||
position: absolute;
|
margin-left: auto;
|
||||||
z-index: 20;
|
text-align: right;
|
||||||
display: flex;
|
padding-left: 12px;
|
||||||
left: -28px;
|
|
||||||
right: -28px;
|
|
||||||
top: 50%;
|
|
||||||
transform: translateY(-50%);
|
|
||||||
justify-content: space-between;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(button) {
|
a {
|
||||||
pointer-events: auto;
|
color: inherit;
|
||||||
|
text-decoration: none;
|
||||||
|
transition: color 0.3s;
|
||||||
|
|
||||||
// Prev button
|
&:hover {
|
||||||
&:first-child {
|
color: $color-tertiary;
|
||||||
& > :global(*:nth-child(2)) {
|
}
|
||||||
transform: translate3d(100%, -50%, 0) rotate(180deg);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Hover
|
// Icon
|
||||||
&:not([disabled]):hover {
|
:global(.icon) {
|
||||||
& > :global(*:nth-child(1)) {
|
display: inline-block;
|
||||||
transform: translate3d(-20%, 0, 0) rotate(180deg);
|
width: 17px;
|
||||||
}
|
height: 17px;
|
||||||
& > :global(*:nth-child(2)) {
|
margin-top: -5px;
|
||||||
transform: translate3d(-50%, -50%, 0) rotate(180deg);
|
margin-right: 4px;
|
||||||
}
|
}
|
||||||
}
|
// Separator
|
||||||
|
.sep {
|
||||||
|
display: inline-block;
|
||||||
|
margin: 0 4px;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Index
|
||||||
|
&__index {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 1;
|
||||||
|
left: 50%;
|
||||||
|
bottom: calc(91% + 1vw);
|
||||||
|
display: block;
|
||||||
|
line-height: 1;
|
||||||
|
color: rgba($color-tertiary, 0.4);
|
||||||
|
transform: translate3d(-50%, 0, 0);
|
||||||
|
white-space: nowrap;
|
||||||
|
pointer-events: none;
|
||||||
|
user-select: none;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
@include bp (md, max) {
|
||||||
|
font-size: clamp(#{rem(80px)}, 24vw, #{rem(120px)});
|
||||||
|
}
|
||||||
|
@include bp (md) {
|
||||||
|
top: 50%;
|
||||||
|
left: auto;
|
||||||
|
right: calc(-1 * min(30vw, 400px));
|
||||||
|
width: 350px;
|
||||||
|
text-align: center;
|
||||||
|
bottom: auto;
|
||||||
|
transform: translate3d(0, -50%, 0);
|
||||||
|
}
|
||||||
|
@include bp (lg) {
|
||||||
|
right: calc(-1 * min(25vw, 460px));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Controls
|
||||||
|
&__controls {
|
||||||
|
display: none;
|
||||||
|
|
||||||
|
@include bp (md) {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 20;
|
||||||
|
display: flex;
|
||||||
|
left: -28px;
|
||||||
|
right: -28px;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
justify-content: space-between;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(button) {
|
||||||
|
pointer-events: auto;
|
||||||
|
|
||||||
|
// Prev button
|
||||||
|
&:first-child {
|
||||||
|
& > :global(*:nth-child(2)) {
|
||||||
|
transform: translate3d(100%, -50%, 0) rotate(180deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hover
|
// Hover
|
||||||
&:not([disabled]):hover {
|
&:not([disabled]):hover {
|
||||||
background-color: $color-secondary;
|
& > :global(*:nth-child(1)) {
|
||||||
color: #fff;
|
transform: translate3d(-20%, 0, 0) rotate(180deg);
|
||||||
|
}
|
||||||
:global(svg:nth-child(2)) {
|
& > :global(*:nth-child(2)) {
|
||||||
color: #fff;
|
transform: translate3d(-50%, -50%, 0) rotate(180deg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Fullscreen viewer
|
// Hover
|
||||||
&__fullscreen {
|
&:not([disabled]):hover {
|
||||||
position: absolute;
|
background-color: $color-secondary;
|
||||||
z-index: 102;
|
color: #fff;
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
background: $color-primary-darker;
|
|
||||||
|
|
||||||
.inner {
|
:global(svg:nth-child(2)) {
|
||||||
width: 100%;
|
color: #fff;
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Photo
|
|
||||||
:global(picture) {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
overflow: auto;
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
:global(img) {
|
|
||||||
display: block;
|
|
||||||
width: auto;
|
|
||||||
height: 100%;
|
|
||||||
object-fit: contain;
|
|
||||||
pointer-events: none;
|
|
||||||
user-select: none;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Close
|
// Fullscreen viewer
|
||||||
:global(.close) {
|
&__fullscreen {
|
||||||
$color-shadow: rgba(#000, 0.15);
|
position: absolute;
|
||||||
position: absolute;
|
z-index: 102;
|
||||||
z-index: 2;
|
top: 0;
|
||||||
bottom: 24px;
|
left: 0;
|
||||||
left: 50%;
|
width: 100%;
|
||||||
transform: translateX(-50%);
|
height: 100%;
|
||||||
box-shadow:
|
background: $color-primary-darker;
|
||||||
0 6px 6px $color-shadow,
|
|
||||||
0 12px 12px $color-shadow,
|
.inner {
|
||||||
0 24px 24px $color-shadow;
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Photo
|
||||||
|
:global(picture) {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
:global(img) {
|
||||||
|
display: block;
|
||||||
|
width: auto;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: contain;
|
||||||
|
pointer-events: none;
|
||||||
|
user-select: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notice
|
// Close
|
||||||
&__notice {
|
:global(.close) {
|
||||||
|
$color-shadow: rgba(#000, 0.15);
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 16px;
|
z-index: 2;
|
||||||
left: 20px;
|
bottom: 24px;
|
||||||
line-height: 44px;
|
left: 50%;
|
||||||
color: rgba($color-tertiary, 0.5);
|
transform: translateX(-50%);
|
||||||
|
box-shadow:
|
||||||
|
0 6px 6px $color-shadow,
|
||||||
|
0 12px 12px $color-shadow,
|
||||||
|
0 24px 24px $color-shadow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@include bp (md) {
|
// Notice
|
||||||
display: none;
|
&__notice {
|
||||||
}
|
position: absolute;
|
||||||
|
top: 16px;
|
||||||
|
left: 20px;
|
||||||
|
line-height: 44px;
|
||||||
|
color: rgba($color-tertiary, 0.5);
|
||||||
|
|
||||||
|
@include bp (md) {
|
||||||
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user