Compare commits

18 Commits
dev ... main

Author SHA1 Message Date
cbd1062d82 refactor: use SASS @use over @import 2024-11-13 23:16:35 +01:00
ac3070b0b7 fix: exceeded effect on Photos page? 2024-11-12 15:12:06 +01:00
54682c6886 fix: move pages animation to onMount 2024-11-12 15:10:18 +01:00
d9708c5bfe fix: bring back updated data on Photos page 2024-11-12 15:03:18 +01:00
efd4a558af fix: replace stamp icon 2024-11-12 14:20:21 +01:00
d3a82f6cf5 fix: rename page stylesheets 2024-11-12 14:12:43 +01:00
9e46d79ba7 fix: SASS deprecated functions 2024-11-12 14:06:17 +01:00
9ed4f1dbd9 refactor: import using style src over @import 2024-11-12 14:05:59 +01:00
396eed0bcd chore: update deps 2024-11-12 14:05:11 +01:00
15364316e3 chore: update deps 2024-09-04 10:47:14 +02:00
79f58b5062 chore: update deps 2024-08-09 17:41:48 +02:00
3219cff2b9 fix: sort Credits locations alphabetically 2024-08-08 11:58:26 +02:00
a98bec7801 chore: update deps 2024-08-08 11:58:08 +02:00
8e5978e95f chore: update deps + Directus v11 2024-08-07 13:36:31 +02:00
77193c2920 chore: update deps 2024-08-05 23:27:54 +02:00
89fa888616 chore: add state and undefined to bindings 2024-08-05 23:27:46 +02:00
d3d7193663 fix: parallax values on About photos grid 2024-08-05 16:41:13 +02:00
d3482ceb54 Merge branch 'dev' 2024-08-05 16:28:18 +02:00
83 changed files with 279 additions and 319 deletions

View File

@@ -17,6 +17,6 @@
"dev": "directus-extension build -w --no-minify"
},
"devDependencies": {
"@directus/extensions-sdk": "11.0.9"
"@directus/extensions-sdk": "12.1.2"
}
}

View File

@@ -9,7 +9,7 @@
"start": "directus start"
},
"dependencies": {
"directus": "^10.13.1",
"directus": "^11.2.1",
"mysql": "^2.18.1"
}
}

View File

@@ -15,42 +15,42 @@
"lint": "eslint ."
},
"dependencies": {
"classix": "^2.1.38",
"dayjs": "^1.11.12",
"embla-carousel": "^8.1.8",
"focus-visible": "^5.2.0",
"lenis": "^1.1.9",
"motion": "^10.18.0",
"ogl": "^1.0.8",
"classix": "^2.2.0",
"dayjs": "^1.11.13",
"embla-carousel": "^8.3.1",
"focus-visible": "^5.2.1",
"lenis": "^1.1.16",
"motion": "^10",
"ogl": "^1.0.9",
"sanitize.css": "^13.0.0",
"swell-js": "^4.2.2",
"tweakpane": "^4.0.4",
"swell-js": "^4.2.4",
"tweakpane": "^4.0.5",
"utils": "workspace:*"
},
"devDependencies": {
"@sveltejs/adapter-auto": "^3.2.2",
"@sveltejs/adapter-cloudflare": "^4.7.0",
"@sveltejs/kit": "^2.5.20",
"@typescript-eslint/eslint-plugin": "^8.0.0",
"@typescript-eslint/parser": "^8.0.0",
"@sveltejs/adapter-auto": "^3.3.1",
"@sveltejs/adapter-cloudflare": "^4.7.4",
"@sveltejs/kit": "^2.8.1",
"@typescript-eslint/eslint-plugin": "^8.14.0",
"@typescript-eslint/parser": "^8.14.0",
"base-64": "^1.0.0",
"browserslist": "^4.23.3",
"browserslist": "^4.24.2",
"config": "workspace:*",
"cssnano": "^7.0.4",
"eslint": "^9.8.0",
"eslint-plugin-svelte": "^2.43.0",
"postcss": "^8.4.40",
"postcss-focus-visible": "^9.0.1",
"postcss-normalize": "^10.0.1",
"postcss-preset-env": "^9.6.0",
"cssnano": "^7.0.6",
"eslint": "^9.14.0",
"eslint-plugin-svelte": "^2.46.0",
"postcss": "^8.4.49",
"postcss-focus-visible": "^10.0.1",
"postcss-normalize": "^13.0.1",
"postcss-preset-env": "^10.1.0",
"postcss-sort-media-queries": "^5.2.0",
"sass": "^1.77.8",
"svelte": "^5.0.0-next.208",
"svelte-check": "^3.8.5",
"svelte-preprocess": "^6.0.2",
"tslib": "^2.6.3",
"typescript": "^5.5.4",
"vite": "5.3.5"
"sass": "^1.80.7",
"svelte": "^5.1.16",
"svelte-check": "^4.0.7",
"svelte-preprocess": "^6.0.3",
"tslib": "^2.8.1",
"typescript": "^5.6.3",
"vite": "5.4.11"
},
"type": "module",
"browserslist": [

View File

@@ -1,6 +1,4 @@
<style lang="scss">
@import "./BoxCTA";
</style>
<style lang="scss" src="./BoxCTA.scss"></style>
<script lang="ts">
import Icon from '$components/atoms/Icon.svelte'

View File

@@ -1,3 +1,5 @@
@use "sass:color";
.button {
display: inline-flex;
align-items: center;
@@ -116,7 +118,7 @@
// Hover
&:not([disabled]):hover {
color: $color-text;
background-color: darken($color-secondary, 7);
background-color: color.adjust($color-secondary, $lightness: -7%);
}
}
@@ -128,7 +130,7 @@
&[disabled] {
background: none;
border: 2px solid darken($color-button, 2);
border: 2px solid color.adjust($color-button, $lightness: -2%);
}
// Hover
@@ -138,7 +140,7 @@
}
}
&:not([disabled]):hover {
background: darken($color-button, 2.5);
background: color.adjust($color-button, $lightness: -2.5%);
}
}

View File

@@ -1,6 +1,4 @@
<style lang="scss">
@import "./Button";
</style>
<style lang="scss" src="./Button.scss"></style>
<script lang="ts">
import { cx } from 'classix'

View File

@@ -1,6 +1,4 @@
<style lang="scss">
@import "./ButtonCart";
</style>
<style lang="scss" src="./ButtonCart.scss"></style>
<script lang="ts">
import { scale } from 'svelte/transition'

View File

@@ -1,3 +1,5 @@
@use "sass:color";
.button-circle {
position: relative;
overflow: hidden;
@@ -97,7 +99,7 @@
background: $color-secondary;
&:hover {
background: darken($color-secondary, 7);
background: color.adjust($color-secondary, $lightness: -7%);
}
}

View File

@@ -1,6 +1,4 @@
<style lang="scss">
@import "./ButtonCircle";
</style>
<style lang="scss" src="./ButtonCircle.scss"></style>
<script lang="ts">
import { cx } from 'classix'

View File

@@ -35,7 +35,7 @@
let scrollY = $state<number>()
let innerWidth = $state<number>()
let innerHeight = $state<number>()
let titleEl: HTMLElement
let titleEl = $state<HTMLElement>(undefined)
// Check if title is larger than viewport to translate it
const isLarger = $derived<boolean>(titleEl && titleEl.offsetWidth >= innerWidth)

View File

@@ -1,6 +1,4 @@
<style lang="scss">
@import "./SiteTitle";
</style>
<style lang="scss" src="./SiteTitle.scss"></style>
<script lang="ts">
import SplitText from '$components/SplitText.svelte'

View File

@@ -1,6 +1,4 @@
<style lang="scss">
@import "./PosterLayout";
</style>
<style lang="scss" src="./PosterLayout.scss"></style>
<script lang="ts">
import { addToCart } from '$utils/functions/shop'

View File

@@ -1,6 +1,4 @@
<style lang="scss">
@import "./CartItem";
</style>
<style lang="scss" src="./CartItem.scss"></style>
<script lang="ts">
import ButtonCircle from '$components/atoms/ButtonCircle/ButtonCircle.svelte'

View File

@@ -1,6 +1,4 @@
<style lang="scss">
@import "./EmailForm";
</style>
<style lang="scss" src="./EmailForm.scss"></style>
<script lang="ts">
import { fly } from 'svelte/transition'

View File

@@ -1,6 +1,4 @@
<style lang="scss">
@import "./Heading";
</style>
<style lang="scss" src="./Heading.scss"></style>
<script lang="ts">
import SiteTitle from '$components/atoms/SiteTitle/SiteTitle.svelte'

View File

@@ -1,6 +1,4 @@
<style lang="scss">
@import "./House";
</style>
<style lang="scss" src="./House.scss"></style>
<script lang="ts">
import dayjs from 'dayjs'

View File

@@ -1,6 +1,4 @@
<style lang="scss">
@import "./Location";
</style>
<style lang="scss" src="./Location.scss"></style>
<script lang="ts">
import { PUBLIC_PREVIEW_COUNT } from '$env/static/public'
@@ -24,7 +22,7 @@
const { settings }: any = getContext('global')
let locationEl: HTMLElement
let locationEl = $state<HTMLElement>(undefined)
let photoIndex = $state(0)
// Location date limit

View File

@@ -1,6 +1,4 @@
<style lang="scss">
@import "./NewsletterIssue";
</style>
<style lang="scss" src="./NewsletterIssue.scss"></style>
<script lang="ts">
import dayjs from 'dayjs'

View File

@@ -1,6 +1,4 @@
<style lang="scss">
@import "./NotificationCart";
</style>
<style lang="scss" src="./NotificationCart.scss"></style>
<script lang="ts">
import { fly } from 'svelte/transition'

View File

@@ -1,6 +1,4 @@
<style lang="scss">
@import "./Pagination";
</style>
<style lang="scss" src="./Pagination.scss"></style>
<script lang="ts">
let {

View File

@@ -1,6 +1,4 @@
<style lang="scss">
@import "./PhotoCard";
</style>
<style lang="scss" src="./PhotoCard.scss"></style>
<script lang="ts">
import Image from '$components/atoms/Image.svelte'

View File

@@ -1,6 +1,4 @@
<style lang="scss">
@import "./PostCard";
</style>
<style lang="scss" src="./PostCard.scss"></style>
<script lang="ts">
import { cx } from 'classix'

View File

@@ -1,3 +1,5 @@
@use "sass:color";
.poster {
position: relative;
border-radius: 6px;
@@ -93,7 +95,7 @@
&:hover {
@include bp (md) {
background-color: darken($color-secondary, 7);
background-color: color.adjust($color-secondary, $lightness: -7%);
}
}
}

View File

@@ -1,6 +1,4 @@
<style lang="scss">
@import "./Poster";
</style>
<style lang="scss" src="./Poster.scss"></style>
<script lang="ts">
import { addToCart } from '$utils/functions/shop'

View File

@@ -1,6 +1,4 @@
<style lang="scss">
@import "./ProcessStep";
</style>
<style lang="scss" src="./ProcessStep.scss"></style>
<script lang="ts">
import { scale } from 'svelte/transition'

View File

@@ -1,6 +1,4 @@
<style lang="scss">
@import "./ShopLocationSwitcher";
</style>
<style lang="scss" src="./ShopLocationSwitcher.scss"></style>
<script lang="ts">
import { goto } from '$app/navigation'

View File

@@ -1,6 +1,4 @@
<style lang="scss">
@import "./Switcher";
</style>
<style lang="scss" src="./Switcher.scss"></style>
<script lang="ts">
import { page } from '$app/stores'
@@ -12,7 +10,7 @@
const { settings: { switcher_links } }: any = getContext('global')
let switcherEl: HTMLElement
let switcherEl = $state<HTMLElement>(undefined)
let isOpen = $state(false)

View File

@@ -1,6 +1,4 @@
<style lang="scss">
@import "./Toast";
</style>
<style lang="scss" src="./Toast.scss"></style>
<script lang="ts">
import { fade, fly } from 'svelte/transition'

View File

@@ -1,6 +1,4 @@
<style lang="scss">
@import "./Banner";
</style>
<style lang="scss" src="./Banner.scss"></style>
<script lang="ts">
// Components

View File

@@ -1,6 +1,4 @@
<style lang="scss">
@import "./Carousel";
</style>
<style lang="scss" src="./Carousel.scss"></style>
<script lang="ts">
import { writable } from 'svelte/store'
@@ -17,7 +15,7 @@
class?: string
} = $props()
let carouselEl = $state<HTMLElement>()
let carouselEl = $state<HTMLElement>(undefined)
let carousel: EmblaCarouselType
let currentSlide = $state(0)
let arrowDirection = $state<'next' | 'prev'>()

View File

@@ -1,6 +1,4 @@
<style lang="scss">
@import "./Cart";
</style>
<style lang="scss" src="./Cart.scss"></style>
<script lang="ts">
import { fade, fly } from 'svelte/transition'

View File

@@ -1,6 +1,4 @@
<style lang="scss">
@import "./Collage";
</style>
<style lang="scss" src="./Collage.scss"></style>
<script lang="ts">
import PhotoCard from '$components/molecules/PhotoCard/PhotoCard.svelte'

View File

@@ -1,6 +1,4 @@
<style lang="scss">
@import "./Footer";
</style>
<style lang="scss" src="./Footer.scss"></style>
<script lang="ts">
import { getContext } from 'svelte'

View File

@@ -1,6 +1,4 @@
<style lang="scss">
@import "./InteractiveGlobe";
</style>
<style lang="scss" src="./InteractiveGlobe.scss"></style>
<script lang="ts">
import { dev } from '$app/environment'
@@ -33,8 +31,8 @@
} = $props()
let innerWidth = $state<number>()
let globeParentEl: HTMLElement
let globeEl: HTMLElement
let globeParentEl = $state<HTMLElement>(undefined)
let globeEl = $state<HTMLElement>(undefined)
let globe = $state<any>()
let observer: IntersectionObserver
let animation = $state<number>()

View File

@@ -1,6 +1,4 @@
<style lang="scss">
@import "./Locations";
</style>
<style lang="scss" src="./Locations.scss"></style>
<script lang="ts">
import { getContext } from 'svelte'

View File

@@ -1,6 +1,4 @@
<style lang="scss">
@import "./NewsletterModule";
</style>
<style lang="scss" src="./NewsletterModule.scss"></style>
<script lang="ts">
import { getContext } from 'svelte'

View File

@@ -1,6 +1,4 @@
<style lang="scss">
@import "./PostersGrid";
</style>
<style lang="scss" src="./PostersGrid.scss"></style>
<script lang="ts">
import { getContext } from 'svelte'
@@ -16,7 +14,7 @@
} = $props()
let innerWidth = $state<number>()
let carouselEl = $state<HTMLElement>()
let carouselEl = $state<HTMLElement>(undefined)
let carousel = $state<EmblaCarouselType>()
let currentSlide = $state(0)
let carouselDots = $state([])

View File

@@ -1,10 +1,8 @@
<style lang="scss">
@import "./ShopBanner";
</style>
<style lang="scss" src="./ShopBanner.scss"></style>
<script lang="ts">
import { navigating } from '$app/stores'
import { getContext } from 'svelte'
import { getContext, onMount } from 'svelte'
import { stagger, timeline } from 'motion'
import { smoothScroll } from '$utils/stores'
import { cartOpen } from '$utils/stores/shop'
@@ -21,8 +19,8 @@
let innerWidth = $state<number>()
let navObserver: IntersectionObserver
let introEl: HTMLElement
let navChooseEl: HTMLElement
let introEl = $state<HTMLElement>(undefined)
let navChooseEl = $state<HTMLElement>(undefined)
let scrolledPastIntro = $state(false)
@@ -46,7 +44,14 @@
navChooseEl.scrollLeft = offsetLeft
}
// Destroy
return () => {
navObserver && navObserver.disconnect()
}
})
onMount(() => {
/**
* Animations
*/
@@ -97,12 +102,6 @@
// Run animation
requestAnimationFrame(animation.play)
// Destroy
return () => {
navObserver && navObserver.disconnect()
}
})
</script>

View File

@@ -1,6 +1,4 @@
<style lang="scss">
@import "./ShopModule";
</style>
<style lang="scss" src="./ShopModule.scss"></style>
<script lang="ts">
import { getContext } from 'svelte'

View File

@@ -1,6 +1,4 @@
<style lang="scss">
@import "../../../style/pages/shop";
</style>
<style lang="scss" src="../../../style/pages/shop.scss"></style>
<script lang="ts">
import { setContext } from 'svelte'

View File

@@ -1,10 +1,9 @@
<style lang="scss">
@import "../../../../style/pages/location";
</style>
<style lang="scss" src="../../../../style/pages/location.scss"></style>
<script lang="ts">
import { PUBLIC_LIST_INCREMENT } from '$env/static/public'
import { page, navigating } from '$app/stores'
import { onMount } from 'svelte'
import { scroll, stagger, timeline } from 'motion'
import dayjs from 'dayjs'
import relativeTime from 'dayjs/plugin/relativeTime'
@@ -35,8 +34,8 @@
dayjs.extend(relativeTime)
let introEl: HTMLElement
let photosListEl = $state<HTMLElement>()
let introEl = $state<HTMLElement>(undefined)
let photosListEl = $state<HTMLElement>(undefined)
let observerPhotos: IntersectionObserver
let mutationPhotos: MutationObserver
let currentPage = $state(1)
@@ -146,6 +145,15 @@
})
// Destroy
return () => {
observerPhotos && observerPhotos.disconnect()
mutationPhotos && mutationPhotos.disconnect()
}
})
onMount(() => {
/**
* Animations
*/
@@ -194,13 +202,6 @@
// Run animation
requestAnimationFrame(animation.play)
// Destroy
return () => {
observerPhotos && observerPhotos.disconnect()
mutationPhotos && mutationPhotos.disconnect()
}
})
</script>

View File

@@ -1,11 +1,9 @@
<style lang="scss">
@import "../../../../../style/pages/viewer";
</style>
<style lang="scss" src="../../../../../style/pages/viewer.scss"></style>
<script lang="ts">
import { page, navigating } from '$app/stores'
import { goto } from '$app/navigation'
import { tick } from 'svelte'
import { onMount, tick } from 'svelte'
import { fade, scale } from 'svelte/transition'
import { quartOut } from 'svelte/easing'
import dayjs from 'dayjs'
@@ -32,7 +30,7 @@
enum directions { PREV, NEXT }
let innerWidth = $state<number>()
let fullscreenEl = $state<HTMLElement>()
let fullscreenEl = $state<HTMLElement>(undefined)
let globalOffset = $state(data.offset)
let isLoading = $state(false)
let isFullscreen = $state(false)
@@ -218,7 +216,7 @@
}
$effect(() => {
onMount(() => {
/**
* Animations
*/

View File

@@ -1,6 +1,4 @@
<style lang="scss">
@import "../../../style/pages/about";
</style>
<style lang="scss" src="../../../style/pages/about.scss"></style>
<script lang="ts">
import { navigating } from '$app/stores'
@@ -20,11 +18,12 @@
import AboutGridPhoto from '$components/atoms/AboutGridPhoto.svelte'
import ProcessStep from '$components/molecules/ProcessStep/ProcessStep.svelte'
import Banner from '$components/organisms/Banner/Banner.svelte'
import { onMount } from 'svelte';
let { data } = $props()
let innerWidth = $state<number>()
let photosGridEl: HTMLElement
let photosGridEl = $state<HTMLElement>(undefined)
let photosGridParallax = $state<number>()
let currentStepIndex = $state(0)
const currentStep = $derived(data.about.process_steps[currentStepIndex])
@@ -40,71 +39,11 @@
$effect(() => {
// Add parallax to photos grid
scroll(({ y }) => photosGridParallax = lerp(-15, 10, y.progress), {
scroll(({ y }) => photosGridParallax = lerp(-10, 20, y.progress), {
target: photosGridEl,
offset: ['start end', 'end start']
})
/**
* Animations
*/
const animation = timeline([
// Banner
['.banner picture', {
scale: [1.06, 1],
opacity: [0, 1],
z: 0,
}, {
at: 0.4,
duration: 2.4,
}],
['.banner h1', {
y: [32, 0],
opacity: [0, 1],
}, {
at: 0.5,
}],
['.banner__top > *', {
y: [-100, 0],
opacity: [0, 1],
}, {
at: 0.4,
delay: stagger(0.25),
}],
// Intro elements
['.about__introduction .container > *', {
y: ['20%', 0],
opacity: [0, 1],
z: 0,
}, {
at: 0.75,
delay: stagger(0.25),
}],
['.first-photo', {
y: ['10%', 0],
opacity: [0, 1],
z: 0,
}, {
at: 1.2,
}],
['.first-photo img', {
scale: [1.06, 1],
opacity: [0, 1],
z: 0,
}, {
at: 1.5,
duration: 2.4,
}],
], {
delay: $navigating ? DELAY.PAGE_LOADING / 1000 : 0,
defaultOptions: {
duration: 1.6,
easing: quartOut,
},
})
animation.stop()
// Sections
inView('[data-reveal]', ({ target }) => {
animate(target, {
@@ -165,6 +104,69 @@
}, {
amount: 0.35,
})
})
onMount(() => {
/**
* Animations
*/
const animation = timeline([
// Banner
['.banner picture', {
scale: [1.06, 1],
opacity: [0, 1],
z: 0,
}, {
at: 0.4,
duration: 2.4,
}],
['.banner h1', {
y: [32, 0],
opacity: [0, 1],
}, {
at: 0.5,
}],
['.banner__top > *', {
y: [-100, 0],
opacity: [0, 1],
}, {
at: 0.4,
delay: stagger(0.25),
}],
// Intro elements
['.about__introduction .container > *', {
y: ['20%', 0],
opacity: [0, 1],
z: 0,
}, {
at: 0.75,
delay: stagger(0.25),
}],
['.first-photo', {
y: ['10%', 0],
opacity: [0, 1],
z: 0,
}, {
at: 1.2,
}],
['.first-photo img', {
scale: [1.06, 1],
opacity: [0, 1],
z: 0,
}, {
at: 1.5,
duration: 2.4,
}],
], {
delay: $navigating ? DELAY.PAGE_LOADING / 1000 : 0,
defaultOptions: {
duration: 1.6,
easing: quartOut,
},
})
animation.stop()
// Run animation
requestAnimationFrame(animation.play)

View File

@@ -13,8 +13,8 @@ export const load = async ({ setHeaders }) => {
credit (filter: { status: { _eq: "published" }}) {
name
website
location {
location_id (filter: { status: { _eq: "published" }}) {
location (sort: "location_id.slug") {
location_id (filter: { status: { _eq: "published" }}, sort: ["slug"]) {
name
slug
country {

View File

@@ -1,9 +1,8 @@
<style lang="scss">
@import "../../../style/pages/credits";
</style>
<style lang="scss" src="../../../style/pages/credits.scss"></style>
<script lang="ts">
import { navigating } from '$app/stores'
import { onMount } from 'svelte'
import { stagger, timeline } from 'motion'
import { DELAY } from '$utils/constants'
import { quartOut } from 'svelte/easing'
@@ -17,7 +16,7 @@
const { credit } = data
$effect(() => {
onMount(() => {
/**
* Animations
*/

View File

@@ -1,6 +1,4 @@
<style lang="scss">
@import "../../../style/pages/explore";
</style>
<style lang="scss" src="../../../style/pages/explore.scss"></style>
<script lang="ts">
import { getContext } from 'svelte'

View File

@@ -1,12 +1,10 @@
<style lang="scss">
@import "../../../style/pages/photos";
</style>
<style lang="scss" src="../../../style/pages/photos.scss"></style>
<script lang="ts">
import { PUBLIC_FILTERS_DEFAULT_COUNTRY, PUBLIC_FILTERS_DEFAULT_SORT, PUBLIC_GRID_INCREMENT } from '$env/static/public'
import { page, navigating } from '$app/stores'
import { goto } from '$app/navigation'
import { getContext } from 'svelte'
import { getContext, onMount } from 'svelte'
import { fly } from 'svelte/transition'
import { quartOut as quartOutSvelte } from 'svelte/easing'
import dayjs from 'dayjs'
@@ -31,14 +29,14 @@
let { data } = $props()
let photos = $state<any[]>(data.photos)
let photos = $state<any[]>([...data.photos])
const totalPhotos = $derived<number>(data.totalPhotos)
const { filteredCountryExists, settings }: { filteredCountryExists: boolean, settings: any } = data
const { filteredCountryExists, settings }: { filteredCountryExists: boolean, settings: any } = data
const { countries, locations }: any = getContext('global')
dayjs.extend(relativeTime)
let photosGridEl = $state<HTMLElement>()
let photosGridEl = $state<HTMLElement>(undefined)
let observerPhotos: IntersectionObserver
let mutationPhotos: MutationObserver
let scrollY = $state<number>()
@@ -75,15 +73,13 @@
/**
* Handle URL query params
*/
const countryFlagId = $derived(currentCountry ? currentCountry.flag.id : undefined)
// Update URL filtering params from filter values
const applyFilters = () => {
urlFiltersParams.set('country', filterCountry)
urlFiltersParams.set('sort', filterSort)
let path = `${$page.url.pathname}?${urlFiltersParams.toString()}`
goto(path, { replaceState: true, keepFocus: true, noScroll: true })
const path = `${$page.url.pathname}?${urlFiltersParams.toString()}`
goto(path, { keepFocus: true, replaceState: true, noScroll: true })
}
@@ -111,14 +107,14 @@
* Filters change events
*/
/** Country select */
const handleCountryChange = ({ detail: value }) => {
const handleCountryChange = (value: string) => {
filterCountry = value === defaultCountry ? defaultCountry : value
currentPage = 1
applyFilters()
}
/** Sort select */
const handleSortChange = ({ detail: value }) => {
const handleSortChange = (value: string) => {
filterSort = value === defaultSort ? defaultSort : value
currentPage = 1
applyFilters()
@@ -199,7 +195,15 @@
}
// Workaround: Reactive photos based on data
$effect(() => {
if (data.photos) {
photos = data.photos
}
})
onMount(() => {
/**
* Observers
*/
@@ -234,7 +238,6 @@
const existingPhotos = photosGridEl.querySelectorAll('.photo')
existingPhotos.forEach(el => observerPhotos.observe(el))
/**
* Animations
*/
@@ -259,7 +262,6 @@
// Run animation
requestAnimationFrame(animation.play)
// Destroy
return () => {
// Disconnect observers
@@ -309,10 +311,10 @@
onchange={handleCountryChange}
value={filterCountry}
>
{#if countryFlagId}
{#if currentCountry?.flag?.id}
<Image
class="icon"
id={countryFlagId}
id={currentCountry?.flag?.id}
sizeKey="square-small"
width={26} height={26}
alt="{filterCountry} flag"

View File

@@ -1,9 +1,8 @@
<style lang="scss">
@import "../../../style/pages/subscribe";
</style>
<style lang="scss" src="../../../style/pages/subscribe.scss"></style>
<script lang="ts">
import { navigating } from '$app/stores'
import { onMount } from 'svelte'
import { stagger, timeline } from 'motion'
import { DELAY } from '$utils/constants'
import { quartOut } from '$animations/easings'
@@ -19,7 +18,7 @@
const latestIssue = $derived(data.issues[0])
$effect(() => {
onMount(() => {
/**
* Animations
*/

View File

@@ -1,6 +1,4 @@
<style lang="scss">
@import "../../../style/pages/terms";
</style>
<style lang="scss" src="../../../style/pages/terms.scss"></style>
<script lang="ts">
import dayjs from 'dayjs'

View File

@@ -1,6 +1,4 @@
<style lang="scss">
@import "../style/pages/error";
</style>
<style lang="scss" src="../style/pages/error.scss"></style>
<script lang="ts">
import { getContext } from 'svelte'

View File

@@ -15,6 +15,7 @@
</style>
<script lang="ts">
import 'sanitize.css'
import '../style/global.scss'
import { PUBLIC_ANALYTICS_DOMAIN } from '$env/static/public'
@@ -94,7 +95,7 @@
<svelte:window bind:innerHeight />
<svelte:head>
<link rel="canonical" href={$page.url.href} />
<link rel="canonical" href={$page.url.href.split('#')[0]} />
{#each fonts as font}
<link rel="preload" href="/fonts/{font}.woff2" as="font" type="font/woff2" crossorigin="anonymous">

View File

@@ -1,10 +1,8 @@
<style lang="scss">
@import "../style/pages/homepage";
</style>
<style lang="scss" src="../style/pages/homepage.scss"></style>
<script lang="ts">
import { navigating } from '$app/stores'
import { getContext } from 'svelte'
import { getContext, onMount } from 'svelte'
import { timeline, stagger } from 'motion'
import { DELAY } from '$utils/constants'
import { smoothScroll } from '$utils/stores'
@@ -34,7 +32,7 @@
let innerHeight = $state<number>()
$effect(() => {
onMount(() => {
/**
* Animations
*/

View File

@@ -1,3 +1,6 @@
@use "imports" as *;
/*
** Earth icon
*/

View File

@@ -1,3 +1,6 @@
@use "../imports" as *;
.photo {
overflow: hidden;
background: $color-primary-tertiary20;

View File

@@ -1,3 +1,6 @@
@use "imports" as *;
html {
font: #{$base-font-size}/1.2 $font-sans;
font-weight: 400;

View File

@@ -1,3 +1,6 @@
@use "imports" as *;
/*
** Box shadows
*/

View File

@@ -1,3 +1,5 @@
@use "imports" as *;
/* Fonts list
========================================================================== */
@include font-face("Garnett", "G-Light", 200);

View File

@@ -1,25 +1,22 @@
@charset "UTF-8";
// Dependencies
@import "sanitize.css/sanitize";
// Tools
@import "tools/helpers";
@forward "tools/helpers";
// Base
@import "variables-css";
@import "base";
@import "fonts";
@import "typography";
@import "effects";
@forward "variables-css";
@forward "base";
@forward "fonts";
@forward "typography";
// Layout
@import "layout/grid";
@import "layout/modules";
@forward "layout/grid";
@forward "layout/modules";
// Misc
@import "animations";
@forward "animations";
@forward "effects";
// Components (Atomic Design System)
// Atoms
@import "atoms/photo";
@forward "atoms/photo";

View File

@@ -1,4 +1,3 @@
// Tools
@import "variables";
@import "tools/mixins";
@import "tools/functions";
@forward "variables";
@forward "tools/mixins";
@forward "tools/functions";

View File

@@ -1,3 +1,6 @@
@use "../imports" as *;
/*
** Grid
*/

View File

@@ -1,3 +1,6 @@
@use "../imports" as *;
.grid-modules {
padding-bottom: 40px;

View File

@@ -1,4 +1,7 @@
@use "sass:math";
@use "sass:color";
@use "../variables" as *;
/* PX to REM
========================================================================== */
@@ -39,5 +42,5 @@
/* HEX color to RGB
========================================================================== */
@function hexToRGB($color) {
@return red($color), green($color), blue($color);
@return color.channel($color, "red", $space: rgb), color.channel($color, "green", $space: rgb), color.channel($color, "blue", $space: rgb);
}

View File

@@ -1,3 +1,6 @@
@use "../imports" as *;
/* Classes
========================================================================== */
.clear {

View File

@@ -1,4 +1,7 @@
@use "sass:math";
@use "sass:map";
@use "../variables" as *;
// Hide text
%hide-text {
@@ -51,8 +54,8 @@
// Based on Width
@mixin bp ($size, $to: min, $sizes: $breakpoints) {
// Size is in map
@if map-has-key($sizes, $size) {
$size: map-get($sizes, $size);
@if map.has-key($sizes, $size) {
$size: map.get($sizes, $size);
@if ($to == max) {
@media (max-width: #{$size}) {

View File

@@ -1,3 +1,6 @@
@use "imports" as *;
/* ==========================================================================
TITLES
========================================================================== */

View File

@@ -1,3 +1,6 @@
@use "imports" as *;
:root {
// Sizes
--container-width: #{$container-width};

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

View File

@@ -1,18 +1,16 @@
import { sveltePreprocess } from 'svelte-preprocess'
import adapter from '@sveltejs/adapter-cloudflare'
import { fileURLToPath } from 'url'
import { dirname } from 'path'
import { sveltePreprocess } from 'svelte-preprocess'
import adapter from '@sveltejs/adapter-cloudflare'
const stylePath = `${dirname(fileURLToPath(import.meta.url))}/src/style`
export const scssImports = `@use "${stylePath}/imports.scss" as *;`
export const globalStyles = `@use "${dirname(fileURLToPath(import.meta.url))}/src/style/imports" as *;`
/** @type {import('@sveltejs/kit').Config} */
const config = {
// Preprocessors docs: https://github.com/sveltejs/svelte-preprocess
preprocess: sveltePreprocess({
scss: {
prependData: scssImports,
renderSync: true,
prependData: globalStyles,
}
}),

View File

@@ -1,15 +1,16 @@
import type { UserConfig } from 'vite'
import { defineConfig } from 'vite'
import { sveltekit } from '@sveltejs/kit/vite'
import { scssImports } from './svelte.config'
import { globalStyles } from './svelte.config'
const config: UserConfig = {
export default defineConfig({
plugins: [
sveltekit()
],
css: {
preprocessorOptions: {
scss: {
additionalData: scssImports,
additionalData: globalStyles,
api: 'modern',
}
}
},
@@ -18,6 +19,4 @@ const config: UserConfig = {
transformMixedEsModules: true,
}
},
}
export default config
})

BIN
bun.lockb

Binary file not shown.

View File

@@ -13,11 +13,11 @@
},
"devDependencies": {
"prettier": "^3.3.3",
"turbo": "^2.0.11"
"turbo": "^2.2.3"
},
"type": "module",
"engines": {
"node": ">=20.0.0"
},
"packageManager": "bun@1.1.21"
"packageManager": "bun@1.1.34"
}