☠️ RESET for v2
This commit is contained in:
@@ -1,3 +0,0 @@
|
|||||||
.git
|
|
||||||
*Dockerfile*
|
|
||||||
.env
|
|
||||||
149
.drone.yml
149
.drone.yml
@@ -1,149 +0,0 @@
|
|||||||
# DEPLOY
|
|
||||||
kind: pipeline
|
|
||||||
name: deploy
|
|
||||||
|
|
||||||
trigger:
|
|
||||||
status:
|
|
||||||
- success
|
|
||||||
event:
|
|
||||||
- push
|
|
||||||
|
|
||||||
steps:
|
|
||||||
#
|
|
||||||
# Restore cache (node_modules, build, etc)
|
|
||||||
#
|
|
||||||
- name: cache-restore
|
|
||||||
image: meltwater/drone-cache:dev
|
|
||||||
pull: true
|
|
||||||
volumes:
|
|
||||||
- name: cache
|
|
||||||
path: /tmp/cache
|
|
||||||
settings:
|
|
||||||
backend: "filesystem"
|
|
||||||
restore: true
|
|
||||||
cache_key: "volume"
|
|
||||||
archive_format: "gzip"
|
|
||||||
mount:
|
|
||||||
- "node_modules"
|
|
||||||
|
|
||||||
#
|
|
||||||
# Build Node.js app
|
|
||||||
#
|
|
||||||
- name: build-node
|
|
||||||
image: node:latest
|
|
||||||
commands:
|
|
||||||
- yarn
|
|
||||||
- yarn build
|
|
||||||
|
|
||||||
#
|
|
||||||
# Build the Docker image
|
|
||||||
#
|
|
||||||
# DEV
|
|
||||||
- name: build-docker-dev
|
|
||||||
image: docker:latest
|
|
||||||
volumes:
|
|
||||||
- name: docker_sock
|
|
||||||
path: /var/run/docker.sock
|
|
||||||
commands:
|
|
||||||
- docker build --pull --no-cache -t cetrucflotte/housesof:dev .
|
|
||||||
when:
|
|
||||||
branch:
|
|
||||||
- dev
|
|
||||||
|
|
||||||
# PROD
|
|
||||||
- name: build-docker-prod
|
|
||||||
image: docker:latest
|
|
||||||
volumes:
|
|
||||||
- name: docker_sock
|
|
||||||
path: /var/run/docker.sock
|
|
||||||
commands:
|
|
||||||
- docker build --pull --no-cache -t cetrucflotte/housesof:latest .
|
|
||||||
when:
|
|
||||||
branch:
|
|
||||||
- master
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# Restart container
|
|
||||||
#
|
|
||||||
# DEV
|
|
||||||
- name: restart-container-dev
|
|
||||||
image: appleboy/drone-ssh
|
|
||||||
settings:
|
|
||||||
host: flayks.com
|
|
||||||
username:
|
|
||||||
from_secret: ssh_user
|
|
||||||
key:
|
|
||||||
from_secret: ssh_key
|
|
||||||
script:
|
|
||||||
- cd /data/sites/housesof.world/test
|
|
||||||
- docker-compose down
|
|
||||||
- docker-compose up -d --remove-orphans
|
|
||||||
when:
|
|
||||||
branch:
|
|
||||||
- dev
|
|
||||||
|
|
||||||
# PROD
|
|
||||||
- name: restart-container-prod
|
|
||||||
image: appleboy/drone-ssh
|
|
||||||
settings:
|
|
||||||
host: flayks.com
|
|
||||||
username:
|
|
||||||
from_secret: ssh_user
|
|
||||||
key:
|
|
||||||
from_secret: ssh_key
|
|
||||||
script:
|
|
||||||
- cd /data/sites/housesof.world/www
|
|
||||||
- docker-compose down
|
|
||||||
- docker-compose up -d --remove-orphans
|
|
||||||
when:
|
|
||||||
branch:
|
|
||||||
- master
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# Rebuild cache
|
|
||||||
#
|
|
||||||
- name: cache-rebuild
|
|
||||||
image: meltwater/drone-cache:dev
|
|
||||||
pull: true
|
|
||||||
volumes:
|
|
||||||
- name: cache
|
|
||||||
path: /tmp/cache
|
|
||||||
settings:
|
|
||||||
backend: "filesystem"
|
|
||||||
rebuild: true
|
|
||||||
cache_key: "volume"
|
|
||||||
archive_format: "gzip"
|
|
||||||
mount:
|
|
||||||
- "node_modules"
|
|
||||||
|
|
||||||
#
|
|
||||||
# Notify (by Email)
|
|
||||||
#
|
|
||||||
- name: notify-email
|
|
||||||
image: drillster/drone-email
|
|
||||||
settings:
|
|
||||||
host:
|
|
||||||
from_secret: notify_email_server
|
|
||||||
from:
|
|
||||||
from_secret: notify_email_address
|
|
||||||
username:
|
|
||||||
from_secret: notify_email_address
|
|
||||||
password:
|
|
||||||
from_secret: notify_email_password
|
|
||||||
recipients:
|
|
||||||
- hello@flayks.com
|
|
||||||
recipients_only: true
|
|
||||||
|
|
||||||
|
|
||||||
# Mount cache volume
|
|
||||||
volumes:
|
|
||||||
- name: cache
|
|
||||||
host:
|
|
||||||
path: /var/lib/cache
|
|
||||||
- name: docker_sock
|
|
||||||
host:
|
|
||||||
path: /var/run/docker.sock
|
|
||||||
11
.env
11
.env
@@ -1,11 +0,0 @@
|
|||||||
# Website
|
|
||||||
PROD_URL="https://housesof.world"
|
|
||||||
HOME_PHOTOS_LIMIT=6
|
|
||||||
|
|
||||||
# API
|
|
||||||
API_TOKEN="NJk0urljsdSvApUDzWxGgoO6"
|
|
||||||
API_URL_DEV="http://api.housesof.localhost/how"
|
|
||||||
API_URL_PROD="https://api.housesof.world/how"
|
|
||||||
|
|
||||||
# Tracking
|
|
||||||
GA_TRACKER_ID="UA-4060922-27"
|
|
||||||
11
.env.local
Normal file
11
.env.local
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
# Options
|
||||||
|
# VITE_OPTION=true
|
||||||
|
|
||||||
|
# API related
|
||||||
|
VITE_API_GRAPHQL_URL_DEV="http://api.housesof.localhost:8055/graphql"
|
||||||
|
VITE_API_GRAPHQL_URL_PROD="https://api.housesof.world/graphql"
|
||||||
|
VITE_API_TOKEN="efa40490-152c-49d7-a75b-30a6427439b1"
|
||||||
|
|
||||||
|
# Analytics
|
||||||
|
VITE_ANALYTICS_KEY=""
|
||||||
|
VITE_ANALYTICS_URL="https://stats.flayks.com"
|
||||||
20
.eslintrc.cjs
Normal file
20
.eslintrc.cjs
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
module.exports = {
|
||||||
|
root: true,
|
||||||
|
parser: '@typescript-eslint/parser',
|
||||||
|
extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'],
|
||||||
|
plugins: ['svelte3', '@typescript-eslint'],
|
||||||
|
ignorePatterns: ['*.cjs'],
|
||||||
|
overrides: [{ files: ['*.svelte'], processor: 'svelte3/svelte3' }],
|
||||||
|
settings: {
|
||||||
|
'svelte3/typescript': () => require('typescript')
|
||||||
|
},
|
||||||
|
parserOptions: {
|
||||||
|
sourceType: 'module',
|
||||||
|
ecmaVersion: 2019
|
||||||
|
},
|
||||||
|
env: {
|
||||||
|
browser: true,
|
||||||
|
es2017: true,
|
||||||
|
node: true
|
||||||
|
}
|
||||||
|
}
|
||||||
22
.eslintrc.js
22
.eslintrc.js
@@ -1,22 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
extends: [
|
|
||||||
// 'eslint:recommended'
|
|
||||||
],
|
|
||||||
env: {
|
|
||||||
'browser': true,
|
|
||||||
'es6': true
|
|
||||||
},
|
|
||||||
plugins: ['svelte3'],
|
|
||||||
parserOptions: {
|
|
||||||
'ecmaVersion': 2019,
|
|
||||||
'sourceType': 'module'
|
|
||||||
},
|
|
||||||
overrides: [{
|
|
||||||
files: ['**/*.svelte'],
|
|
||||||
processor: 'svelte3/svelte3'
|
|
||||||
}],
|
|
||||||
rules: {
|
|
||||||
indent: [ 'error', 4 ],
|
|
||||||
'no-multiple-empty-lines': [ 1, { 'max': 5 } ]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -1,4 +1,5 @@
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
node_modules
|
node_modules
|
||||||
__sapper__
|
/build
|
||||||
/cypress/screenshots
|
/.svelte-kit
|
||||||
|
/package
|
||||||
|
|||||||
14
Dockerfile
14
Dockerfile
@@ -1,14 +0,0 @@
|
|||||||
FROM node:current-alpine
|
|
||||||
|
|
||||||
WORKDIR /var/www
|
|
||||||
|
|
||||||
# Copy build and modules
|
|
||||||
COPY . .
|
|
||||||
|
|
||||||
# Open port
|
|
||||||
EXPOSE 3000
|
|
||||||
|
|
||||||
# Serve
|
|
||||||
CMD node dist
|
|
||||||
|
|
||||||
VOLUME ["/var/www"]
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
presets: [
|
|
||||||
'@babel/preset-env'
|
|
||||||
],
|
|
||||||
plugins: [
|
|
||||||
'@babel/plugin-syntax-dynamic-import',
|
|
||||||
['@babel/plugin-transform-runtime', {
|
|
||||||
'useESModules': true
|
|
||||||
}]
|
|
||||||
]
|
|
||||||
}
|
|
||||||
79
package.json
79
package.json
@@ -1,61 +1,42 @@
|
|||||||
{
|
{
|
||||||
"name": "housesof",
|
"name": "housesof",
|
||||||
"version": "1.2.0",
|
"version": "2.0.0",
|
||||||
"description": "Houses Of website",
|
|
||||||
"author": {
|
|
||||||
"name": "Flayks",
|
|
||||||
"email": "hello@flayks.com",
|
|
||||||
"url": "http://flayks.com"
|
|
||||||
},
|
|
||||||
"private": true,
|
"private": true,
|
||||||
|
"author": {
|
||||||
|
"name": "Félix Péault",
|
||||||
|
"url": "https://flayks.com",
|
||||||
|
"email": "hello@flayks.com"
|
||||||
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "sapper dev --port 3000",
|
"dev": "svelte-kit dev",
|
||||||
"build": "sapper build dist --legacy",
|
"build": "svelte-kit build",
|
||||||
"export": "sapper export export --legacy",
|
"preview": "svelte-kit preview",
|
||||||
"start": "node dist"
|
"check": "svelte-check --tsconfig ./tsconfig.json",
|
||||||
|
"check:watch": "svelte-check --tsconfig ./tsconfig.json --watch",
|
||||||
|
"lint": "eslint --ignore-path .gitignore ."
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"animejs": "^3.2.1",
|
"focus-visible": "^5.2.0",
|
||||||
"compression": "^1.7.4",
|
"sanitize.css": "^12.0.1"
|
||||||
"imagesloaded": "^4.1.4",
|
|
||||||
"lazysizes": "^5.3.0",
|
|
||||||
"node-fetch": "^2.6.1",
|
|
||||||
"normalize.css": "^8.0.1",
|
|
||||||
"polka": "^1.0.0-next.11",
|
|
||||||
"rellax": "^1.12.1",
|
|
||||||
"scroll-out": "^2.2.12",
|
|
||||||
"sirv": "^1.0.10",
|
|
||||||
"svelte-lazy": "^1.0.8",
|
|
||||||
"swipe-listener": "^1.3.0"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.12.10",
|
"@sveltejs/adapter-node": "^1.0.0-next.46",
|
||||||
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
"@sveltejs/adapter-vercel": "^1.0.0-next.28",
|
||||||
"@babel/plugin-transform-runtime": "^7.12.10",
|
"@sveltejs/kit": "next",
|
||||||
"@babel/preset-env": "^7.12.11",
|
"@typescript-eslint/eslint-plugin": "^4.31.1",
|
||||||
"@babel/runtime": "^7.12.5",
|
"@typescript-eslint/parser": "^4.31.1",
|
||||||
"@rollup/plugin-alias": "^3.1.1",
|
"eslint": "^7.32.0",
|
||||||
"@rollup/plugin-babel": "^5.2.2",
|
"eslint-plugin-svelte3": "^3.2.1",
|
||||||
"@rollup/plugin-commonjs": "17.0.0",
|
"sass": "^1.40.1",
|
||||||
"@rollup/plugin-node-resolve": "^11.1.0",
|
"svelte": "^3.42.5",
|
||||||
"@rollup/plugin-replace": "^2.3.4",
|
"svelte-check": "^2.2.6",
|
||||||
"autoprefixer": "^10.2.1",
|
"svelte-preprocess": "^4.9.4",
|
||||||
"dotenv": "^8.2.0",
|
"tslib": "^2.3.1",
|
||||||
"node-sass": "^5.0.0",
|
"typescript": "^4.4.3"
|
||||||
"postcss": "^8.2.4",
|
|
||||||
"postcss-load-config": "^3.0.0",
|
|
||||||
"postcss-preset-env": "^6.7.0",
|
|
||||||
"rollup": "^2.36.2",
|
|
||||||
"rollup-plugin-glslify": "^1.2.0",
|
|
||||||
"rollup-plugin-svelte": "^7.0.0",
|
|
||||||
"rollup-plugin-terser": "^7.0.2",
|
|
||||||
"sapper": "^0.28.10",
|
|
||||||
"svelte": "^3.31.2",
|
|
||||||
"svelte-preprocess": "^4.6.1"
|
|
||||||
},
|
},
|
||||||
|
"type": "module",
|
||||||
"browserslist": [
|
"browserslist": [
|
||||||
"> 0.5%",
|
"last 3 versions",
|
||||||
"last 2 versions",
|
"> 0.3%"
|
||||||
"not dead"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
4945
pnpm-lock.yaml
generated
4945
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -1,30 +0,0 @@
|
|||||||
const pkg = require('./package.json')
|
|
||||||
const dev = process.env.NODE_ENV === 'development'
|
|
||||||
|
|
||||||
module.exports = () => ({
|
|
||||||
plugins: [
|
|
||||||
// Preset Env
|
|
||||||
require('postcss-preset-env')({}),
|
|
||||||
|
|
||||||
// Autoprefixer
|
|
||||||
require('autoprefixer')({}),
|
|
||||||
|
|
||||||
// Extract media queries
|
|
||||||
// require('postcss-combine-media-query')({}),
|
|
||||||
|
|
||||||
// CSS Nano
|
|
||||||
!dev && require('cssnano')({
|
|
||||||
preset: ['default', {
|
|
||||||
autoprefixer: true,
|
|
||||||
discardComments: { removeAll: true },
|
|
||||||
calc: { precision: 2 },
|
|
||||||
safe: true
|
|
||||||
}]
|
|
||||||
}),
|
|
||||||
|
|
||||||
// Banner
|
|
||||||
!dev && require('postcss-banner')({
|
|
||||||
banner: `${pkg.name} v${pkg.version} \nBy ${pkg.author.name} \n${pkg.author.url}`
|
|
||||||
})
|
|
||||||
]
|
|
||||||
})
|
|
||||||
152
rollup.config.js
152
rollup.config.js
@@ -1,152 +0,0 @@
|
|||||||
import path from 'path'
|
|
||||||
import resolve from '@rollup/plugin-node-resolve'
|
|
||||||
import alias from '@rollup/plugin-alias'
|
|
||||||
import replace from '@rollup/plugin-replace'
|
|
||||||
import commonjs from '@rollup/plugin-commonjs'
|
|
||||||
import babel from '@rollup/plugin-babel'
|
|
||||||
import svelte from 'rollup-plugin-svelte'
|
|
||||||
import autoPreprocess from 'svelte-preprocess'
|
|
||||||
import { terser } from 'rollup-plugin-terser'
|
|
||||||
import glslify from 'rollup-plugin-glslify'
|
|
||||||
import config from 'sapper/config/rollup'
|
|
||||||
import { config as dotenv } from 'dotenv'
|
|
||||||
import pkg from './package.json'
|
|
||||||
|
|
||||||
// Define environment and things
|
|
||||||
const mode = process.env.NODE_ENV
|
|
||||||
const dev = mode === 'development'
|
|
||||||
const legacy = !!process.env.SAPPER_LEGACY_BUILD
|
|
||||||
const replaceOptions = {
|
|
||||||
'process.env.NODE_ENV': JSON.stringify(mode),
|
|
||||||
'process.env.CONFIG': JSON.stringify(dotenv().parsed)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Svelte
|
|
||||||
const onwarn = (warning, onwarn) => (warning.code === 'MISSING_EXPORT' && /'preload'/.test(warning.message)) || (warning.code === 'CIRCULAR_DEPENDENCY' && /[/\\]@sapper[/\\]/.test(warning.message)) || onwarn(warning)
|
|
||||||
|
|
||||||
// Preprocessors
|
|
||||||
const preprocess = autoPreprocess({
|
|
||||||
scss: {
|
|
||||||
includePaths: ['src', 'node_modules'],
|
|
||||||
renderSync: true
|
|
||||||
},
|
|
||||||
postcss: true
|
|
||||||
})
|
|
||||||
|
|
||||||
// Resolve and Alias
|
|
||||||
const resolveExtensions = ['.mjs', '.js', '.svelte', '.scss', '.json', '.html']
|
|
||||||
const aliases = alias({
|
|
||||||
resolve: resolveExtensions,
|
|
||||||
entries: [
|
|
||||||
{ find: 'utils', replacement: path.resolve(__dirname, 'src/utils') },
|
|
||||||
{ find: 'animations', replacement: path.resolve(__dirname, 'src/animations') },
|
|
||||||
{ find: 'atoms', replacement: path.resolve(__dirname, 'src/atoms') },
|
|
||||||
{ find: 'molecules', replacement: path.resolve(__dirname, 'src/molecules') },
|
|
||||||
{ find: 'organisms', replacement: path.resolve(__dirname, 'src/organisms') },
|
|
||||||
{ find: 'globe', replacement: path.resolve(__dirname, 'src/globe') },
|
|
||||||
]
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
export default {
|
|
||||||
/*
|
|
||||||
** Client
|
|
||||||
*/
|
|
||||||
client: {
|
|
||||||
input: config.client.input(),
|
|
||||||
output: config.client.output(),
|
|
||||||
plugins: [
|
|
||||||
// Javascript
|
|
||||||
replace({
|
|
||||||
'process.browser': true,
|
|
||||||
...replaceOptions
|
|
||||||
}),
|
|
||||||
svelte({
|
|
||||||
preprocess,
|
|
||||||
emitCss: true,
|
|
||||||
compilerOptions: {
|
|
||||||
dev,
|
|
||||||
hydratable: true,
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
aliases,
|
|
||||||
glslify(),
|
|
||||||
resolve({
|
|
||||||
browser: true,
|
|
||||||
extensions: resolveExtensions,
|
|
||||||
dedupe: ['svelte']
|
|
||||||
}),
|
|
||||||
commonjs(),
|
|
||||||
legacy && babel({
|
|
||||||
extensions: resolveExtensions,
|
|
||||||
babelHelpers: 'runtime',
|
|
||||||
exclude: ['node_modules/@babel/**']
|
|
||||||
}),
|
|
||||||
|
|
||||||
// Compress Javascript
|
|
||||||
!dev && terser({
|
|
||||||
module: true
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
preserveEntrySignatures: false,
|
|
||||||
onwarn,
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Server
|
|
||||||
*/
|
|
||||||
server: {
|
|
||||||
input: config.server.input(),
|
|
||||||
output: config.server.output(),
|
|
||||||
plugins: [
|
|
||||||
replace({
|
|
||||||
'process.browser': false,
|
|
||||||
...replaceOptions
|
|
||||||
}),
|
|
||||||
svelte({
|
|
||||||
preprocess,
|
|
||||||
emitCss: false,
|
|
||||||
compilerOptions: {
|
|
||||||
generate: 'ssr',
|
|
||||||
hydratable: true,
|
|
||||||
dev,
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
aliases,
|
|
||||||
glslify(),
|
|
||||||
resolve({
|
|
||||||
extensions: resolveExtensions,
|
|
||||||
dedupe: ['svelte']
|
|
||||||
}),
|
|
||||||
commonjs()
|
|
||||||
],
|
|
||||||
external: Object.keys(pkg.dependencies).concat(require('module').builtinModules),
|
|
||||||
preserveEntrySignatures: 'strict',
|
|
||||||
onwarn,
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Service worker
|
|
||||||
*/
|
|
||||||
// ...(!dev && {
|
|
||||||
// serviceworker: {
|
|
||||||
// input: config.serviceworker.input(),
|
|
||||||
// output: config.serviceworker.output(),
|
|
||||||
// plugins: [
|
|
||||||
// resolve(),
|
|
||||||
// replace({
|
|
||||||
// 'process.browser': false,
|
|
||||||
// ...replaceOptions
|
|
||||||
// }),
|
|
||||||
// aliases,
|
|
||||||
// glslify(),
|
|
||||||
// commonjs(),
|
|
||||||
// !dev && terser()
|
|
||||||
// ],
|
|
||||||
// preserveEntrySignatures: false,
|
|
||||||
// onwarn,
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
}
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
import anime from 'animejs'
|
|
||||||
import ScrollOut from 'scroll-out'
|
|
||||||
import { animDuration, animDelay } from 'utils/store'
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Transition In
|
|
||||||
*/
|
|
||||||
export const animateIn = scope => {
|
|
||||||
const tl = anime.timeline({
|
|
||||||
easing: 'easeOutQuart',
|
|
||||||
duration: animDuration,
|
|
||||||
autoplay: false
|
|
||||||
})
|
|
||||||
|
|
||||||
// Carousel
|
|
||||||
tl.add({
|
|
||||||
targets: scope,
|
|
||||||
translateY: [window.innerWidth <= 768 ? 16 : 32, 0],
|
|
||||||
translateZ: [0, 0],
|
|
||||||
opacity: [0, 1],
|
|
||||||
complete: event => event.animatables[0].target.removeAttribute('style')
|
|
||||||
})
|
|
||||||
|
|
||||||
// Photo: Active
|
|
||||||
tl.add({
|
|
||||||
targets: scope.querySelector('.is-active picture'),
|
|
||||||
translateY: [8, 0],
|
|
||||||
translateZ: [0, 0],
|
|
||||||
complete: event => event.animatables[0].target.removeAttribute('style')
|
|
||||||
}, 100)
|
|
||||||
|
|
||||||
// Photo: Prev
|
|
||||||
tl.add({
|
|
||||||
targets: scope.querySelector('.is-prev picture'),
|
|
||||||
translateY: [8, 0],
|
|
||||||
translateX: [64, 0],
|
|
||||||
translateZ: [0, 0],
|
|
||||||
rotate: window.innerWidth >= 768 ? [-2, 0] : [0, 0],
|
|
||||||
complete: event => event.animatables[0].target.removeAttribute('style')
|
|
||||||
}, 100)
|
|
||||||
|
|
||||||
// Photo: Next
|
|
||||||
tl.add({
|
|
||||||
targets: scope.querySelector('.is-next picture'),
|
|
||||||
translateY: [8, 0],
|
|
||||||
translateX: [-48, 0],
|
|
||||||
translateZ: [0, 0],
|
|
||||||
rotate: window.innerWidth >= 768 ? [2, 0] : [0, 0],
|
|
||||||
complete: event => event.animatables[0].target.removeAttribute('style')
|
|
||||||
}, 100)
|
|
||||||
|
|
||||||
// Reveal on scroll
|
|
||||||
let visible = false
|
|
||||||
setTimeout(() => {
|
|
||||||
const carouselReveal = ScrollOut({
|
|
||||||
once: true,
|
|
||||||
targets: scope,
|
|
||||||
onChange: (el, ctx) => {
|
|
||||||
if (ctx.visible === 0) {
|
|
||||||
visible = true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onShown: (el, ctx) => {
|
|
||||||
// If revealed on scroll, no delay
|
|
||||||
if (visible) {
|
|
||||||
setTimeout(() => tl.restart(), 10)
|
|
||||||
}
|
|
||||||
// If revealed on load, add a delay
|
|
||||||
else {
|
|
||||||
setTimeout(() => tl.restart(), animDelay * 2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}, 10)
|
|
||||||
}
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
import anime from 'animejs'
|
|
||||||
import ScrollOut from 'scroll-out'
|
|
||||||
import { animDurationLong } from 'utils/store'
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Transition In
|
|
||||||
*/
|
|
||||||
export const animateIn = scope => {
|
|
||||||
let delay = 0
|
|
||||||
|
|
||||||
// Each location (reveal on scroll)
|
|
||||||
scope.querySelectorAll('.location').forEach(location => {
|
|
||||||
const tl = anime.timeline({
|
|
||||||
easing: 'easeOutQuart',
|
|
||||||
duration: 600,
|
|
||||||
autoplay: false,
|
|
||||||
delay,
|
|
||||||
complete: () => {
|
|
||||||
// Reset delay
|
|
||||||
delay = 0
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// Image
|
|
||||||
tl.add({
|
|
||||||
targets: location.querySelector('img'),
|
|
||||||
scale: [1.3, 1],
|
|
||||||
opacity: [0, 1],
|
|
||||||
translateZ: [0, 0],
|
|
||||||
duration: 1800
|
|
||||||
}, 100)
|
|
||||||
|
|
||||||
// Name
|
|
||||||
tl.add({
|
|
||||||
targets: location.querySelector('h3'),
|
|
||||||
translateY: ['100%', 0],
|
|
||||||
translateZ: [0, 0],
|
|
||||||
}, 150)
|
|
||||||
|
|
||||||
// Country
|
|
||||||
tl.add({
|
|
||||||
targets: location.querySelector('p'),
|
|
||||||
translateY: ['100%', 0],
|
|
||||||
translateZ: [0, 0]
|
|
||||||
}, 200)
|
|
||||||
|
|
||||||
// Increase delay between locations
|
|
||||||
delay += 65
|
|
||||||
|
|
||||||
// Scroll reveal
|
|
||||||
ScrollOut({
|
|
||||||
once: true,
|
|
||||||
targets: location,
|
|
||||||
onShown: () => tl.restart()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@@ -1,95 +0,0 @@
|
|||||||
import anime from 'animejs'
|
|
||||||
import ScrollOut from 'scroll-out'
|
|
||||||
import imagesLoaded from 'imagesloaded'
|
|
||||||
import { throttle, parallaxAnime } from 'utils/functions'
|
|
||||||
import { animDuration } from 'utils/store'
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Transition In
|
|
||||||
*/
|
|
||||||
export const animateIn = scope => {
|
|
||||||
const tlLocation = anime.timeline({
|
|
||||||
easing: 'easeOutQuart',
|
|
||||||
duration: 1000,
|
|
||||||
autoplay: false
|
|
||||||
})
|
|
||||||
// Title
|
|
||||||
tlLocation.add({
|
|
||||||
targets: scope.querySelectorAll('.photo__location .line span'),
|
|
||||||
translateY: ['120%', 0],
|
|
||||||
translateZ: [0, 0],
|
|
||||||
delay: anime.stagger(120)
|
|
||||||
}, 200)
|
|
||||||
// Description
|
|
||||||
tlLocation.add({
|
|
||||||
targets: scope.querySelectorAll('.photo__location p'),
|
|
||||||
opacity: [0, 1],
|
|
||||||
duration: animDuration
|
|
||||||
}, 400)
|
|
||||||
|
|
||||||
// Reveal on scroll
|
|
||||||
const locationScroll = ScrollOut({
|
|
||||||
once: true,
|
|
||||||
targets: scope,
|
|
||||||
onShown: () => tlLocation.restart()
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
// Image (reveal on scroll)
|
|
||||||
const photoImage = scope.querySelector('.photo__image')
|
|
||||||
const photoReveal = anime.timeline({
|
|
||||||
easing: 'easeOutQuart',
|
|
||||||
duration: 2000,
|
|
||||||
autoplay: false
|
|
||||||
})
|
|
||||||
photoReveal.add({
|
|
||||||
targets: scope.querySelector('.photo__picture'),
|
|
||||||
opacity: [0, 1]
|
|
||||||
}, 50)
|
|
||||||
photoReveal.add({
|
|
||||||
targets: scope.querySelector('.photo__picture img'),
|
|
||||||
scale: [1.12, 1],
|
|
||||||
translateZ: [0, 0]
|
|
||||||
}, 50)
|
|
||||||
|
|
||||||
// Show photo when image is loaded
|
|
||||||
imagesLoaded(photoImage, instance => {
|
|
||||||
const photoScroll = ScrollOut({
|
|
||||||
once: true,
|
|
||||||
targets: photoImage,
|
|
||||||
onShown: () => photoReveal.restart()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
// Number parallax on scroll
|
|
||||||
const media768 = window.matchMedia('(min-width: 768px)')
|
|
||||||
const number = scope.querySelector('.photo__number')
|
|
||||||
const numberPallax = anime({
|
|
||||||
targets: number.querySelector('span'),
|
|
||||||
translateY: (window.innerWidth <= 768) ? ['0%', '20%'] : ['-20%', '20%'],
|
|
||||||
easing: 'linear',
|
|
||||||
duration: 2000,
|
|
||||||
autoplay: false
|
|
||||||
})
|
|
||||||
const numberPallaxAnime = () => parallaxAnime(number, numberPallax)
|
|
||||||
const numberPallaxScroll = matchMedia => {
|
|
||||||
if (matchMedia.matches) {
|
|
||||||
const scroll = ScrollOut({
|
|
||||||
targets: scope,
|
|
||||||
onShown: () => {
|
|
||||||
window.addEventListener('scroll', throttle(numberPallaxAnime, 50))
|
|
||||||
requestAnimationFrame(numberPallaxAnime)
|
|
||||||
},
|
|
||||||
onHidden: () => {
|
|
||||||
if (parallaxAnime) window.removeEventListener('scroll', parallaxAnime)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Listen on screen size to run the function
|
|
||||||
media768.addListener(numberPallaxAnime)
|
|
||||||
numberPallaxScroll(media768)
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
import anime from 'animejs'
|
|
||||||
import ScrollOut from 'scroll-out'
|
|
||||||
import { firstLoad, animDurationLong, animDelay } from 'utils/store'
|
|
||||||
|
|
||||||
let firstLoadValue
|
|
||||||
firstLoad.subscribe(store => firstLoadValue = store)
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Transition In
|
|
||||||
*/
|
|
||||||
export const animateIn = (scope, init) => {
|
|
||||||
// Stagger each letters and words
|
|
||||||
const letters = anime({
|
|
||||||
targets: scope.querySelectorAll('span, em span'),
|
|
||||||
translateY: ['100%', 0],
|
|
||||||
translateZ: [0, 0],
|
|
||||||
easing: 'easeOutQuart',
|
|
||||||
duration: 1000,
|
|
||||||
delay: anime.stagger(40, { start: init ? 0 : (firstLoadValue) ? animDurationLong : animDelay }),
|
|
||||||
autoplay: false
|
|
||||||
})
|
|
||||||
|
|
||||||
// On scroll animation
|
|
||||||
requestAnimationFrame(() => {
|
|
||||||
const title = ScrollOut({
|
|
||||||
once: true,
|
|
||||||
targets: scope,
|
|
||||||
onShown: () => requestAnimationFrame(() => letters.restart())
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
import { quartInOut } from 'svelte/easing'
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Animation Out: Background
|
|
||||||
*/
|
|
||||||
export const panelBackgroundOut = (node, params) => {
|
|
||||||
return {
|
|
||||||
delay: params.delay || 0,
|
|
||||||
duration: params.duration || 400,
|
|
||||||
easing: params.easing || quartInOut,
|
|
||||||
css: (t, u) => `
|
|
||||||
transform: scaleY(${t})
|
|
||||||
`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
import { crossfade } from 'svelte/transition'
|
|
||||||
import { quartOut } from 'svelte/easing'
|
|
||||||
|
|
||||||
// Crossfade transition
|
|
||||||
export const [send, receive] = crossfade({
|
|
||||||
duration: d => Math.sqrt(d * 200),
|
|
||||||
fallback: (node, params) => {
|
|
||||||
const {
|
|
||||||
duration = 600,
|
|
||||||
easing = quartOut,
|
|
||||||
start = 0.85
|
|
||||||
} = params
|
|
||||||
const style = getComputedStyle(node)
|
|
||||||
const transform = style.transform === 'none' ? '' : style.transform
|
|
||||||
const sd = 1 - start
|
|
||||||
return {
|
|
||||||
duration,
|
|
||||||
easing,
|
|
||||||
css: (t, u) => `
|
|
||||||
transform: ${transform} scale(${1 - (sd * u)});
|
|
||||||
opacity: ${t}
|
|
||||||
`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
import anime from 'animejs'
|
|
||||||
import ScrollOut from 'scroll-out'
|
|
||||||
import { animDuration, animDelay } from 'utils/store'
|
|
||||||
import { throttle, parallaxAnime } from 'utils/functions'
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Transition In
|
|
||||||
*/
|
|
||||||
export const animateIn = () => {
|
|
||||||
// Title: Houses
|
|
||||||
const titleHouses = anime({
|
|
||||||
targets: document.querySelectorAll('#title-houses span'),
|
|
||||||
translateY: ['-70%', 0],
|
|
||||||
translateZ: [0, 0],
|
|
||||||
easing: 'easeOutQuart',
|
|
||||||
delay: anime.stagger(80, { start: animDelay }),
|
|
||||||
duration: animDuration
|
|
||||||
})
|
|
||||||
|
|
||||||
// Title: Parallax on scroll
|
|
||||||
const translate = anime({
|
|
||||||
targets: '#title-houses',
|
|
||||||
translateX: window.innerWidth <= 1920 ? ['25%', '-15%'] : ['7%', '-7%'],
|
|
||||||
translateZ: [0, 0],
|
|
||||||
easing: 'linear',
|
|
||||||
duration: animDuration,
|
|
||||||
autoplay: false
|
|
||||||
})
|
|
||||||
window.addEventListener('scroll', throttle(() => parallaxAnime(document.getElementById('title-houses'), translate), 5))
|
|
||||||
requestAnimationFrame(() => parallaxAnime(document.getElementById('title-houses'), translate))
|
|
||||||
|
|
||||||
// Intro: Description
|
|
||||||
const introDescription = anime({
|
|
||||||
targets: document.getElementById('intro-description').querySelectorAll('p, a'),
|
|
||||||
opacity: [0, 1],
|
|
||||||
translateY: [8, 0],
|
|
||||||
translateZ: [0, 0],
|
|
||||||
easing: 'easeOutQuart',
|
|
||||||
duration: animDuration,
|
|
||||||
delay: anime.stagger(200, { start: animDelay + 200 })
|
|
||||||
})
|
|
||||||
|
|
||||||
// Title: Of (reveal on scroll)
|
|
||||||
const titleOf = document.getElementById('title-of')
|
|
||||||
const titleOfReveal = anime({
|
|
||||||
targets: titleOf.querySelectorAll('span'),
|
|
||||||
translateY: ['100%', 0],
|
|
||||||
translateZ: [0, 0],
|
|
||||||
easing: 'easeOutQuart',
|
|
||||||
delay: anime.stagger(70),
|
|
||||||
duration: animDuration,
|
|
||||||
autoplay: false
|
|
||||||
})
|
|
||||||
const titleOfScroll = ScrollOut({
|
|
||||||
once: true,
|
|
||||||
targets: titleOf,
|
|
||||||
onShown: () => titleOfReveal.restart()
|
|
||||||
})
|
|
||||||
|
|
||||||
// Title: World (reveal on scroll)
|
|
||||||
const titleWorld = document.getElementById('title-world')
|
|
||||||
const titleWorldReveal = anime({
|
|
||||||
targets: titleWorld.querySelectorAll('span'),
|
|
||||||
translateY: ['100%', 0],
|
|
||||||
translateZ: [0, 0],
|
|
||||||
easing: 'easeOutQuart',
|
|
||||||
delay: anime.stagger(70),
|
|
||||||
duration: animDuration,
|
|
||||||
autoplay: false
|
|
||||||
})
|
|
||||||
const titleWorldParallax = anime({
|
|
||||||
targets: titleWorld,
|
|
||||||
translateX: ['5%', '-3%'],
|
|
||||||
translateZ: [0, 0],
|
|
||||||
easing: 'linear',
|
|
||||||
duration: animDuration,
|
|
||||||
autoplay: false
|
|
||||||
})
|
|
||||||
const titleWorldAnime = () => parallaxAnime(titleWorld, titleWorldParallax)
|
|
||||||
const titleWorldScroll = ScrollOut({
|
|
||||||
once: true,
|
|
||||||
targets: titleWorld,
|
|
||||||
onShown: () => {
|
|
||||||
titleWorldReveal.restart()
|
|
||||||
window.addEventListener('scroll', throttle(titleWorldAnime, 10))
|
|
||||||
requestAnimationFrame(titleWorldAnime)
|
|
||||||
},
|
|
||||||
onHidden: () => {
|
|
||||||
if (parallaxAnime) window.removeEventListener('scroll', parallaxAnime)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
import anime from 'animejs'
|
|
||||||
import { animDuration, animDelay } from 'utils/store'
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Transition In
|
|
||||||
*/
|
|
||||||
export const animateIn = () => {
|
|
||||||
const tl = anime.timeline({
|
|
||||||
easing: 'easeOutQuart',
|
|
||||||
duration: animDuration
|
|
||||||
})
|
|
||||||
|
|
||||||
// Simple slide and fade on each part of the page
|
|
||||||
tl.add({
|
|
||||||
targets: document.querySelectorAll('.page__part, .globe'),
|
|
||||||
opacity: [0, 1],
|
|
||||||
translateY: [8, 0],
|
|
||||||
translateZ: [0, 0],
|
|
||||||
delay: anime.stagger(200, { start: animDelay })
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
import anime from 'animejs'
|
|
||||||
import Rellax from 'rellax'
|
|
||||||
import { animDuration, animDelay } from 'utils/store'
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Transition In
|
|
||||||
*/
|
|
||||||
export const animateIn = () => {
|
|
||||||
const tl = anime.timeline({
|
|
||||||
duration: animDuration,
|
|
||||||
delay: animDelay, // Delay in AnimeJS waits to run but sets the starting style as opposed to a setTimeout
|
|
||||||
easing: 'easeOutQuart'
|
|
||||||
})
|
|
||||||
|
|
||||||
// Title: Houses
|
|
||||||
tl.add({
|
|
||||||
targets: '.place__title_houses',
|
|
||||||
translateY: ['150%', 0],
|
|
||||||
translateZ: [0, 0]
|
|
||||||
})
|
|
||||||
// Title: Of
|
|
||||||
tl.add({
|
|
||||||
targets: '.place__title_of',
|
|
||||||
opacity: [0, 1]
|
|
||||||
}, 600)
|
|
||||||
// Title: Place name
|
|
||||||
tl.add({
|
|
||||||
targets: '.place__title_name',
|
|
||||||
translateY: ['150%', 0],
|
|
||||||
translateZ: [0, 0]
|
|
||||||
}, 150)
|
|
||||||
|
|
||||||
// Switcher link
|
|
||||||
tl.add({
|
|
||||||
targets: '.place__title .button-control',
|
|
||||||
scale: [0.95, 1],
|
|
||||||
opacity: [0, 1]
|
|
||||||
}, 500)
|
|
||||||
|
|
||||||
// Illustration
|
|
||||||
tl.add({
|
|
||||||
targets: '.place__illustration',
|
|
||||||
scale: [1.05, 1],
|
|
||||||
translateZ: [0, 0],
|
|
||||||
opacity: [0, 1]
|
|
||||||
}, 0)
|
|
||||||
|
|
||||||
// Description
|
|
||||||
tl.add({
|
|
||||||
targets: '.place__description',
|
|
||||||
opacity: [0, 1],
|
|
||||||
translateY: [24, 0],
|
|
||||||
translateZ: [0, 0]
|
|
||||||
}, 450)
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Parallax
|
|
||||||
*/
|
|
||||||
const rellax = new Rellax('[data-rellax-speed]')
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
import anime from 'animejs'
|
|
||||||
import { animDuration, animDelay } from 'utils/store'
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Transition In
|
|
||||||
*/
|
|
||||||
export const animateIn = () => {
|
|
||||||
const viewer = document.querySelector('.viewer')
|
|
||||||
|
|
||||||
const tl = anime.timeline({
|
|
||||||
easing: 'easeOutQuart',
|
|
||||||
duration: animDuration,
|
|
||||||
delay: 1400
|
|
||||||
})
|
|
||||||
|
|
||||||
// Carousel: Number
|
|
||||||
tl.add({
|
|
||||||
targets: viewer.querySelector('.counter'),
|
|
||||||
opacity: [0, 1],
|
|
||||||
translateY: [window.innerWidth >= 768 ? -24 : 24, 0]
|
|
||||||
}, 0)
|
|
||||||
|
|
||||||
// Dots
|
|
||||||
tl.add({
|
|
||||||
targets: viewer.querySelectorAll('.carousel__dots'),
|
|
||||||
translateY: [16, 0],
|
|
||||||
translateZ: [0, 0],
|
|
||||||
opacity: [0, 1]
|
|
||||||
}, 150)
|
|
||||||
|
|
||||||
// Buttons
|
|
||||||
tl.add({
|
|
||||||
targets: viewer.querySelectorAll('.tip, .viewer__buttons a'),
|
|
||||||
translateY: [-32, 0],
|
|
||||||
translateZ: [0, 0],
|
|
||||||
opacity: [0, 1],
|
|
||||||
delay: anime.stagger(120),
|
|
||||||
}, 400)
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
<!doctype html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
@@ -8,16 +8,12 @@
|
|||||||
<link rel="manifest" href="/manifest.json">
|
<link rel="manifest" href="/manifest.json">
|
||||||
<link type="text/plain" rel="author" href="/humans.txt">
|
<link type="text/plain" rel="author" href="/humans.txt">
|
||||||
|
|
||||||
<link rel="icon" type="image/png" sizes="64x64" href="/img/favicon.png">
|
<link rel="icon" type="image/png" sizes="64x64" href="/images/favicon.png">
|
||||||
<link rel="apple-touch-icon" sizes="180x180" href="/img/siteicon.png">
|
<link rel="apple-touch-icon" sizes="180x180" href="/images/siteicon.png">
|
||||||
|
%svelte.head%
|
||||||
%sapper.base%
|
|
||||||
%sapper.head%
|
|
||||||
%sapper.scripts%
|
|
||||||
%sapper.styles%
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
%sapper.html%
|
<div id="housesof">%svelte.body%</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
<script>
|
|
||||||
// Props
|
|
||||||
export let text
|
|
||||||
export let size = 'small'
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div class="badge badge--{size}">
|
|
||||||
<span>{text}</span>
|
|
||||||
</div>
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
<script>
|
|
||||||
export let href = '#'
|
|
||||||
export let type = 'a'
|
|
||||||
export let text = ''
|
|
||||||
export let noScroll = undefined
|
|
||||||
</script>
|
|
||||||
|
|
||||||
{#if type === 'button'}
|
|
||||||
<button class={$$props.class ? $$props.class : 'button'} on:click>
|
|
||||||
<slot></slot>
|
|
||||||
<div class="text" data-text={text}>
|
|
||||||
<span>{text}</span>
|
|
||||||
</div>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
{:else}
|
|
||||||
<a {href} class={$$props.class ? $$props.class : 'button'} on:click sapper-noscroll={noScroll}>
|
|
||||||
<slot></slot>
|
|
||||||
<div class="text" data-text={text}>
|
|
||||||
<span>{text}</span>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
{/if}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
<script>
|
|
||||||
import { onMount } from 'svelte'
|
|
||||||
|
|
||||||
// Props
|
|
||||||
export let currentIndex = 0
|
|
||||||
export let className = null
|
|
||||||
|
|
||||||
// Variables
|
|
||||||
let counter
|
|
||||||
const numbers = [...Array(10).keys()]
|
|
||||||
|
|
||||||
// Reactive variables depending on currentIndex
|
|
||||||
$: actualIndex = currentIndex + 1
|
|
||||||
$: amount = String(actualIndex).length
|
|
||||||
$: index = (actualIndex < 10) ? String(actualIndex).padStart(2, '0') : String(actualIndex)
|
|
||||||
$: digits = index.split('')
|
|
||||||
|
|
||||||
|
|
||||||
// Set columns height
|
|
||||||
const setColumnHeight = () => {
|
|
||||||
// Set each digit column's height = its spans combined (in order to translate in tens of %)
|
|
||||||
counter.querySelectorAll('div').forEach(column => {
|
|
||||||
const spans = column.querySelectorAll('span')
|
|
||||||
column.style.height = spans[0].offsetHeight * spans.length + 'px'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Run code when mounted
|
|
||||||
*/
|
|
||||||
onMount(() => {
|
|
||||||
setColumnHeight()
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<svelte:window on:resize={setColumnHeight} />
|
|
||||||
|
|
||||||
<div class="counter {className}" bind:this={counter}>
|
|
||||||
{#each digits as digit}
|
|
||||||
<div class="counter__column" style="transform: translateY(-{digit}0%) translateZ(0);">
|
|
||||||
{#each numbers as number}
|
|
||||||
<span>{number}</span>
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
<script>
|
|
||||||
export let direction = 'left'
|
|
||||||
export let color = '#fff'
|
|
||||||
export let width = 20
|
|
||||||
export let hidden = undefined
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewbox="0 0 20 20"
|
|
||||||
width={width} height={width}
|
|
||||||
fill={color}
|
|
||||||
class={$$props.class}
|
|
||||||
aria-hidden={hidden}
|
|
||||||
data-width={width}
|
|
||||||
>
|
|
||||||
{#if direction === 'left'}
|
|
||||||
<path fill-rule="nonzero" d="M.26 10.85l-.06-.11-.08-.15-.05-.16-.04-.13a1.5 1.5 0 010-.6c0-.05.03-.09.04-.13l.05-.16.08-.15.06-.1c.06-.1.13-.17.2-.25L9.2.45c.61-.6 1.61-.6 2.23 0 .62.6.62 1.57 0 2.17L5.4 8.47h13.02c.87 0 1.58.68 1.58 1.53s-.7 1.53-1.58 1.53H5.4l6.03 5.85c.62.6.62 1.57 0 2.17-.3.3-.71.45-1.12.45-.4 0-.8-.15-1.11-.45L.46 11.08a1.5 1.5 0 01-.2-.23"/>
|
|
||||||
{:else if direction === 'right'}
|
|
||||||
<path fill-rule="nonzero" d="M19.74 10.85l.06-.11.08-.15.05-.16.04-.13c.04-.2.04-.4 0-.6 0-.05-.03-.09-.04-.13l-.05-.16-.08-.15-.06-.1a1.53 1.53 0 00-.2-.25L10.8.45c-.61-.6-1.61-.6-2.23 0a1.5 1.5 0 000 2.17l6.03 5.85H1.58C.71 8.47 0 9.15 0 10s.7 1.53 1.58 1.53H14.6l-6.03 5.85a1.5 1.5 0 000 2.17c.3.3.71.45 1.12.45.4 0 .8-.15 1.11-.45l8.74-8.47.2-.23"/>
|
|
||||||
{/if}
|
|
||||||
</svg>
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
<script>
|
|
||||||
export let width = 18
|
|
||||||
export let color = '#fff'
|
|
||||||
export let hidden = undefined
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 17 17" {width} fill={color} class={$$props.class} aria-hidden={hidden}>
|
|
||||||
<path fill-rule="nonzero" d="M16.63.37c.47.47.5 1.2.09 1.7l-.09.1-6.32 6.33 6.32 6.32a1.28 1.28 0 01-1.7 1.9l-.1-.09-6.33-6.32-6.32 6.32a1.28 1.28 0 01-1.9-1.7l.09-.1L6.69 8.5.37 2.18a1.28 1.28 0 011.7-1.9l.1.09L8.5 6.69 14.82.37c.5-.5 1.31-.5 1.81 0z"/>
|
|
||||||
</svg>
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
<script>
|
|
||||||
import { stores } from '@sapper/app'
|
|
||||||
import { randomString } from 'utils/functions'
|
|
||||||
|
|
||||||
// Props
|
|
||||||
export let width = 56
|
|
||||||
export let color = '#000'
|
|
||||||
export let animated = false
|
|
||||||
const { page } = stores()
|
|
||||||
|
|
||||||
// Generate a random ID for the mask
|
|
||||||
const randomId = randomString(6, 'A')
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.1"
|
|
||||||
width={width} viewBox="0 0 56 75"
|
|
||||||
fill={color}
|
|
||||||
class="icon-svg icon-globe" class:is-animated={animated}
|
|
||||||
>
|
|
||||||
<defs>
|
|
||||||
<clipPath id={randomId}>
|
|
||||||
<ellipse cx="31.5" cy="60.6" rx="24.5" ry="24.4"/>
|
|
||||||
</clipPath>
|
|
||||||
</defs>
|
|
||||||
<g transform="translate(0,-32)">
|
|
||||||
<g clip-path="url({$page.path}#{randomId})">
|
|
||||||
<g class="anim anim-spinGlobe">
|
|
||||||
<path d="M43 65.3c-2.2-.1-1.8.9-3.6-.7-1 .1-1.6-.3-2.6-.2-.4-.1-.5-.5-1.1-.3-.8 0-1.2 1-2.1.6-.2.3-.4.7-1 .8-.3 0-.8.3-1.2 0-.7-2.4-1.8.7-1.8-2h-.1c-2.4 4.5-4.8-4.2 1.2-1.7h.1v-.1c-1-1-.2-1.7 0-2.9-.7-.6.7-2.7 1.7-2.9.1.3.8-.3 1.1-.8-.2-.3-.2-.2-.9.2-1-.4-.3-1.3-1.6.2-.3-1.6 3.1-1.6 2.2-3-1.1-.1-1.5-.6-2.3-1.4-.8 1.7-4.6-2-2.7 1.9.5 4.3-.2.5-3.5 1.2-2.3-1.2 2.1-4.1.8-4.8-1-.7-.4 2.9-3.4-1-1 .9 2.2 2.7-.3 2.4-.4.9-1 .6-1.8.9-.2.4-.2.5-.8.6-1.5.1-3.6-.5-4.9 1v-.4c-1.8 1.9-9.1.6-6.1 5 0 .3 0 .2-.3.7.1.2.1.3.2.5.5.1 1.4-.2 1.9.3-.4.8.4.8.5 0 2.3-3.6 5.7-1.9 8.4.1.6 1.8 1.6 3.2 3.5 4.2.3.9 2.3 1.6.5-.1.3-1.4 2.9 2.9 5.1 1.7h.3c1.3-.1 3 1.1 4.3.7 1.2.7-.3 3 1.4 3.7 2.7 1.2 4 3.6 3.6 6.6.8 1.3.4 4 2.4 3.9 1.9-.3-2.2-3.1 1.2-5.5.5-2.3 1.7-4.1 2.4-6.4-.6-1.1.8-2.6-.7-3zM76.1 36.6c-.5-.9 6.3-5.7 5.5-3.8-.3.7-1.5 2.5-.1 2.8.8-.5.4-2.2 1.1-3 3.6-1.5 3.6-6-.8-3.7-7.1 1.4-4.2-1-8.6 2.6-2.1-1.5-3.4-.1-5.8.8-.9-.2 1.4-1 .2-1.6-3.2-.5-5.5 3-6.8 5.4-1.9-.8-1.5-1.1-2.4 1.1-.9.2-1.4.6-2 1.5-1.5-.1-3.5 4.7-4.3 2.1.4-.3.9-.1 1.3-.7-3.2-4.4-10.3 8.2-3.9 5.6-.8-1.3.5-5.3.7-1.8 2.3 2.8-3.9 3.2-3.9 5.8.6 1.6-.3 1.2-.9 2.1-.4 1.5 1.3 1.9 2.2.9.8-1.8 1.2-3.2 3.5-2.1-.4 1.2 1.2 0 0-.5-.8-.2-1.3-1.4.2-.6.5.2.8 1.1 1.3.8.7-1.1.8.1 1.8.1 3.3-1.1.7 2.2-1.2 1.7-.6.5-1.4 1-2.2.6-4.4-2.8-8.1 8-2.1 8.2 4-.8 2.9-2.7 5.7 1 1.1 4 5.1 9.1 6 2.2 0-1.2.9-2.4.3-3.6-1.7-2.3.5-3.7.2-5.5-1.4.9-4.9-1.7-5-2.9 1.4 0 3.4 2.9 4.3 2.3.5-.6 2.8-2.7 1.5-3.1-2.2 1.1-4.3-1.7-1-.6 6.1-1.4 4.9 2.4 7 2.1.1-1.5 1.1-5.8 2.7-2.5.6-1.3.9-.3 1.4.8 0 .5 1.6 1.3 1 .4-.1 0-.2 0-.4-.1-1.1-1.7 3.7.6.2-2.9 1.4-1.1 3.6-2.6 1.8-5 .4-.2.3-.9-.3-.4-1.5-1.2 1.3-.9 2.1-.4-1.1-2.2 2.9-3.4 1.2-6-.5-.5-.9.1-1.5-.1zM56.3 48.3c-.9.1-1.6.7-2.7.7-.4-.4.1-2.4 1-1.3.3-.3.1-.8.9-1 0 .1 0 .4.1.8.4.1.6 0 1.1.4-.2.1-.3.3-.4.4zm2.1-.8c-.9-.5-.9-1.2 0-1.9.8-.1.1.8.4 1.1 1.8.2.7 3.3-.4.8zM27.4 45c1.1.2 4.1-1.3 3.9 1.2.6-.7 2.1 0 .5.4.8.3.7.6 1 1.4 1.7 2.1 3.2 1.7 3.1-1 4-3.6 2.6-2.5 2.2-7.3 0-.6 1.2-1.1.5-1.6-.6-.1-1.1 1.1-1.8.3-3.7-.9-8.6 3.1-10.6 6.2-.1.9.6.2 1.2.4zM84.7 53.3c-.3-.2-.5-.7-1.2-.8 0 .5.2 2.1-.9 1.5-.3-1.4-1.6-1.1-1.7.2-2.6 2.4-3.6 2.8-1.3 5.8 1.1-.2 2.2-2.1 3.5-2 .8.5 1.6-.1 2.2.8 1 .3 2.6-.2 2.2-1.7.4-2.8-1.3-2.5-2.8-3.8z"/>
|
|
||||||
<path d="M21.5 45.8c.7.2 1.2-.3 2-.1 0 .1-.1.1-.2.4-.4.1-.1.6.4.3 2.1-.5 1.5-.5 2-2.3.8-.9 3.8-3.7.5-2.4-1.2.7-4.8 1.8-4.3 2.9-.3.4-1.6.9-.4 1.2zM29.9 49.1c1.1.2.7-1-.7-.8-.9-.9-2.4-1-3.7-.5-.4-.3-.6-.4-1 .1-.4-.8-1.4.4-.6 1 2.1.6 2.7-1.1 5 .8v.1c-1.2-.2-2.6 1.8-.6.6.5 0 1.3.7 1.9.2 0 0-.2-.3-.5-.4.1-.1.3-.2.4-.4-.1-.1-1.1-.9-.2-.7zM17.5 51.1c.3.1 1-.1 1 .6.7.1 2.2-.4 2.9-.9-.6-.1-1.5-1.9-1.9-1.3-.4 1.1-1.8.3-2 1.6zM81.5 50.9c-1.2-.5-1.8.4.2.5.5 0 .7.9 1.3.6.4-.8 3.8.1 1.6-.9-.7-.7-2.3-.9-3.1-.2zM76.2 50.4c-.2.6-1 1.4-1 2.1 1.5 1.4 2.4-.4 1.4-1.9-.1-.3-.3-.3-.4-.2zM62.4 60.2c-.5.2-.2.9-.2 1.5 1.8 3.5 2-1 .2-1.5zM56.7 37.4c-.7-1.2.1-1.8.9-2.7 1.5-.6 1.2-1.8-.5 0-1.1.3-2.5 3-.4 2.7zM16.4 51.5c.9-.8 1.7-2.2-.6-1.2-.5.4-.4 1.5.6 1.2zM45.4 46.8c-.9-.9-2.7 1.3-.6 1 .2-.2.8-.5.6-1zM41.5 45c-.4-.1-1.4.4-2 .7.5.7 2.4.5 2-.7zM45.1 48.4c0 .3.4.3.9.5 1.2-1-.3-1.6-.9-.5zM33.6 53.3c-.8.4 1.1 1.6 1.3.6-.1-.4-.9-.8-1.3-.6zM93.4 57.2c-.1 0-.1-.1-.2-.1-1.9 1.5-.2 3.2.2.1zM47.8 36.5c.7-.2.6-1.2-.4-.8-.5.3-.4.9.4.8zM45.8 37.7c.7-.2.5-1.2-.5-.7-.3.3-.2.9.5.7zM93.6 55.8c-.1-.5-1-.4-.4.2 0 .2.1.4.2.6-.1.3.7.8.4-.1l.3-.6c-.2 0-.3-.1-.5-.1zM44 48.3c-.2.3-.6 1 .3.8.5-.4.4-.6-.3-.8zM22.6 47.5c-.3 0-.3.6.1.4 1.1.3.8-1.3-.1-.4zM87.1 59.1c-.1.3-.2.4-.1.6.4.4 1-.2.1-.6zM50.1 51c-.2-.2-1 .1-.2.5.1-.2.1-.4.2-.5zM47.6 37.2c-.3 0-.5-.2-.6.3.2 0 .4.2.6-.3zM21.1 46.7v.1c.1 0 .5.1.6-.2-.2-.1-.3-.2-.6.1zM17.9 49.4c-.2-.1-.4-.2-.6.2.2.1.3.1.6-.2zM19.5 48.8v-.1c-.1.1-.4-.1-.5.2.2.1.4.1.5-.1zM21.3 49.8c-.2 0-.4-.2-.5.1.2.2.3.2.5-.1zM68.3 52.7c0 .2-.1.2-.1.3.2.3.7-.1.1-.3z"/>
|
|
||||||
<path d="M27.5 49.2c0-.1-.2-.1-.3-.1 0 .1-.2.3.2.4 0-.2.1-.3.1-.3zM26.1 47.1c-.2 0-.4.1-.5.1v.1c.3.1.3.1.5-.2zM53.9 50.7c-.1.1-.2.1-.3.2 0 0 0 .1.1.1s.2-.1.3-.1c0-.1-.1-.1-.1-.2zM48.1 46.8c0-.1.2-.1-.1-.3.1 0-.1.1.1.3zM26.6 51.7s0-.1-.2 0c.1 0 .1.2.2 0zM22 48.1s.1 0 0 0c.1-.1.1-.1 0 0zM14.6 52.9zM76.1 53.7c-.5-.1-1.1 0-1.6-.4-5.7-3.3-1.2 2.2 1.6.9.9 0 1-.8 0-.5zM26.9 51c-.2-.2-.1-.2-.8-.1-.2 0-.8-.3-.7.3-.3.1-.2.8.3.3.1 0 .2-.1.3-.1.1-.1.9.1.9-.4zM123.3 37c-2.2-.1-1.8.9-3.6-.7-1 .1-1.6-.3-2.6-.2-.4-.1-.5-.5-1.1-.3-.8 0-1.2 1-2.1.6-.2.3-.4.7-1 .8-.3 0-.8.3-1.2 0-.7-2.4-1.8.7-1.8-2h-.1c-2.4 4.5-4.8-4.2 1.2-1.7h.1v-.1c-1-1-.2-1.7 0-2.9-.7-.6.7-2.7 1.7-2.9.1.3.8-.3 1.1-.8-.2-.3-.2-.2-.9.2-1-.4-.3-1.3-1.6.2-.3-1.6 3.1-1.6 2.2-3-1.1-.1-1.5-.6-2.3-1.4-.8 1.7-4.6-2-2.7 1.9.5 4.3-.2.5-3.5 1.2-2.3-1.2 2.1-4.1.8-4.8-1-.7-.4 2.9-3.4-1-1 .9 2.2 2.7-.3 2.4-.4.9-1 .6-1.8.9-.2.4-.2.5-.8.6-1.5.1-3.6-.5-4.9 1v-.4c-1.8 1.9-9.1.6-6.1 5 0 .3 0 .2-.3.7.1.2.1.3.2.5.5.1 1.4-.2 1.9.3-.4.8.4.8.5 0 2.3-3.6 5.7-1.9 8.4.1.6 1.8 1.6 3.2 3.5 4.2.3.9 2.3 1.6.5-.1.3-1.4 2.9 2.9 5.1 1.7h.3c1.3-.1 3 1.1 4.3.7 1.2.7-.3 3 1.4 3.7 2.7 1.2 4 3.6 3.6 6.6.8 1.3.4 4 2.4 3.9 1.9-.3-2.2-3.1 1.2-5.5.5-2.3 1.7-4.1 2.4-6.4-.6-1 .8-2.6-.7-3zM156.4 8.3c-.5-.9 6.3-5.7 5.5-3.8-.3.7-1.5 2.5-.1 2.8.8-.5.4-2.2 1.1-3 3.6-1.5 3.6-6-.8-3.7-7.1 1.4-4.2-1-8.6 2.6-2.1-1.5-3.4-.1-5.8.8-.9-.2 1.4-1 .2-1.6-3.2-.5-5.5 3-6.8 5.4-1.9-.8-1.5-1.1-2.4 1.1-.9.2-1.4.6-2 1.5-1.5-.1-3.5 4.7-4.3 2.1.4-.3.9-.1 1.3-.7-3.2-4.4-10.3 8.2-3.9 5.6-.8-1.3.5-5.3.7-1.8 2.3 2.8-3.9 3.2-3.9 5.8.6 1.6-.3 1.2-.9 2.1-.4 1.5 1.3 1.9 2.2.9.8-1.8 1.2-3.2 3.5-2.1-.4 1.2 1.2 0 0-.5-.8-.2-1.3-1.4.2-.6.5.2.8 1.1 1.3.8.7-1.1.8.1 1.8.1 3.3-1.1.7 2.2-1.2 1.7-.6.5-1.4 1-2.2.6-4.4-2.8-8.1 8-2.1 8.2 4-.8 2.9-2.7 5.7 1 1.1 4 5.1 9.1 6 2.2 0-1.2.9-2.4.3-3.6-1.7-2.3.5-3.7.2-5.5-1.4.9-4.9-1.7-5-2.9 1.4 0 3.4 2.9 4.3 2.3.5-.6 2.8-2.7 1.5-3.1-2.2 1.1-4.3-1.7-1-.6 6.1-1.4 4.9 2.4 7 2.1.1-1.5 1.1-5.8 2.7-2.5.6-1.3.9-.3 1.4.8 0 .5 1.6 1.3 1 .4-.1 0-.2 0-.4-.1-1.1-1.7 3.7.6.2-2.9 1.4-1.1 3.6-2.6 1.8-5 .4-.2.3-.9-.3-.4-1.5-1.2 1.3-.9 2.1-.4-1.1-2.2 2.9-3.4 1.2-6-.5-.4-.8.1-1.5-.1zM136.6 20c-.9.1-1.6.7-2.7.7-.4-.4.1-2.4 1-1.3.3-.3.1-.8.9-1 0 .1 0 .4.1.8.4.1.6 0 1.1.4-.2.1-.3.3-.4.4zm2.1-.8c-.9-.5-.9-1.2 0-1.9.8-.1.1.8.4 1.1 1.8.3.7 3.4-.4.8zM107.7 16.7c1.1.2 4.1-1.3 3.9 1.2.6-.7 2.1 0 .5.4.8.3.7.6 1 1.4 1.7 2.1 3.2 1.7 3.1-1 4-3.6 2.6-2.5 2.2-7.3 0-.6 1.2-1.1.5-1.6-.6-.1-1.1 1.1-1.8.3-3.7-.9-8.6 3.1-10.6 6.2 0 .9.7.2 1.2.4zM165 25c-.3-.2-.5-.7-1.2-.8 0 .5.2 2.1-.9 1.5-.3-1.4-1.6-1.1-1.7.2-2.6 2.4-3.6 2.8-1.3 5.8 1.1-.2 2.2-2.1 3.5-2 .8.5 1.6-.1 2.2.8 1 .3 2.6-.2 2.2-1.7.4-2.8-1.3-2.5-2.8-3.8z"/>
|
|
||||||
<path d="M101.8 17.5c.7.2 1.2-.3 2-.1 0 .1-.1.1-.2.4-.4.1-.1.6.4.3 2.1-.5 1.5-.5 2-2.3.8-.9 3.8-3.7.5-2.4-1.2.7-4.8 1.8-4.3 2.9-.2.5-1.6.9-.4 1.2zM110.2 20.8c1.1.2.7-1-.7-.8-.9-.9-2.4-1-3.7-.5-.4-.3-.6-.4-1 .1-.4-.8-1.4.4-.6 1 2.1.6 2.7-1.1 5 .8v.1c-1.2-.2-2.6 1.8-.6.6.5 0 1.3.7 1.9.2 0 0-.2-.3-.5-.4.1-.1.3-.2.4-.4-.1-.1-1.1-.9-.2-.7zM97.8 22.8c.3.1 1-.1 1 .6.7.1 2.2-.4 2.9-.9-.6-.1-1.5-1.9-1.9-1.3-.4 1.1-1.8.4-2 1.6zM161.8 22.6c-1.2-.5-1.8.4.2.5.5 0 .7.9 1.3.6.4-.8 3.8.1 1.6-.9-.7-.6-2.3-.9-3.1-.2zM156.5 22.2c-.2.6-1 1.4-1 2.1 1.5 1.4 2.4-.4 1.4-1.9-.1-.3-.2-.4-.4-.2zM142.7 32c-.5.2-.2.9-.2 1.5 1.8 3.5 2-1 .2-1.5zM137 9.1c-.7-1.2.1-1.8.9-2.7 1.5-.6 1.2-1.8-.5 0-1.1.4-2.5 3-.4 2.7zM96.7 23.2c.9-.8 1.7-2.2-.6-1.2-.4.4-.3 1.6.6 1.2zM125.7 18.5c-.9-.9-2.7 1.3-.6 1 .2-.1.8-.5.6-1zM121.8 16.8c-.4-.1-1.4.4-2 .7.5.6 2.4.5 2-.7zM125.4 20.2c0 .3.4.3.9.5 1.2-1-.3-1.7-.9-.5zM114 25.1c-.8.4 1.1 1.6 1.3.6-.2-.5-1-.8-1.3-.6zM173.7 29c-.1 0-.1-.1-.2-.1-1.9 1.4-.2 3.2.2.1zM128.1 8.2c.7-.2.6-1.2-.4-.8-.4.4-.3.9.4.8zM126.2 9.4c.7-.2.5-1.2-.5-.7-.4.3-.3.9.5.7zM174.5 27.7c-.2 0-.4-.1-.6-.1-.1-.5-1-.4-.4.2 0 .2.1.4.2.6-.1.3.7.8.4-.1.2-.2.3-.4.4-.6zM124.3 20.1c-.2.3-.6 1 .3.8.5-.4.4-.7-.3-.8zM102.9 19.3c-.3 0-.3.6.1.4 1.1.3.8-1.3-.1-.4zM167.4 30.9c-.1.3-.2.4-.1.6.4.3 1-.3.1-.6zM130.4 22.7c-.2-.2-1 .1-.2.5.1-.2.1-.3.2-.5zM128 8.9c-.3 0-.5-.2-.6.3.1.1.4.3.6-.3zM101.4 18.5v.1c.1 0 .5.1.6-.2-.2-.2-.3-.2-.6.1zM98.2 21.1c-.2-.1-.4-.2-.6.2.3.2.3.1.6-.2zM99.8 20.5v-.1c-.1.1-.4-.1-.5.2.2.2.4.1.5-.1zM101.6 21.5c-.2 0-.4-.2-.5.1.2.3.3.2.5-.1zM148.7 24.4c0 .2-.1.2-.1.3.1.3.6 0 .1-.3z"/>
|
|
||||||
<path d="M107.8 20.9c0-.1-.2-.1-.3-.1 0 .1-.2.3.2.4 0-.1.1-.2.1-.3zM106.5 18.8c-.2 0-.4.1-.5.1v.1c.3.1.3.1.5-.2zM134.2 22.5c-.1.1-.2.1-.3.2 0 0 0 .1.1.1s.2-.1.3-.1c0-.1 0-.2-.1-.2zM128.5 18.5c0-.1.2-.1-.1-.3.1.1-.2.1.1.3zM106.9 23.4s0-.1-.2 0c.1 0 .1.2.2 0zM102.3 19.9c.1 0 .1-.1 0 0 .1-.1.1-.1 0 0 0-.1 0 0 0 0zM94.9 24.6v.1-.1zM156.4 25.4c-.5-.1-1.1 0-1.6-.4-5.7-3.3-1.2 2.2 1.6.9.9.1 1-.7 0-.5zM107.2 22.8c-.2-.2-.1-.2-.8-.1-.2 0-.8-.3-.7.3-.3.1-.2.8.3.3.1 0 .2-.1.3-.1.2-.1.9.1.9-.4z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<path d="M7 60.6C7 74 18 85 31.5 85S56 74 56 60.6 45 36.3 31.5 36.3 7 47.2 7 60.6zm24.5-21.9c12.1 0 22 9.8 22 21.9s-9.9 21.9-22 21.9-22-9.8-22-21.9 9.9-21.9 22-21.9z"/>
|
|
||||||
<path d="M48.7 84c-5 3.6-10.9 5.5-17.1 5.5-16.1 0-29.1-13-29.1-29C2.5 49 9.3 38.6 19.9 34c.6-.3.9-1 .6-1.6-.3-.6-1-.9-1.6-.6C7.4 36.8 0 48.2 0 60.6c0 16 12.1 29.3 27.7 31.2v6.1h-5.8c-2.4 0-4.4 2-4.4 4.4 0 2.4 2 4.4 4.4 4.4H36c2.4 0 4.4-2 4.4-4.4 0-2.4-2-4.4-4.4-4.4h-5.8V92h1.4c6.7 0 13.2-2.1 18.6-6 .6-.4.7-1.2.3-1.7-.4-.5-1.2-.7-1.8-.3zM38 102.3c0 1.1-.9 1.9-1.9 1.9H21.9a1.9 1.9 0 110-3.8H36c1.1 0 2 .9 2 1.9z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
<script>
|
|
||||||
import { stores } from '@sapper/app'
|
|
||||||
import { randomString } from 'utils/functions'
|
|
||||||
|
|
||||||
// Props
|
|
||||||
export let width = 56
|
|
||||||
export let color = '#000'
|
|
||||||
export let animated = false
|
|
||||||
const { page } = stores()
|
|
||||||
|
|
||||||
// Generate a random ID for the mask
|
|
||||||
const randomId = randomString(6, 'A')
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.1"
|
|
||||||
width={width} viewBox="0 0 56 56"
|
|
||||||
fill={color}
|
|
||||||
class="icon-svg icon-globe icon-globe--small" class:is-animated={animated}
|
|
||||||
>
|
|
||||||
<defs>
|
|
||||||
<clipPath id={randomId}>
|
|
||||||
<circle cx="28.1" cy="28" r="26.6"/>
|
|
||||||
</clipPath>
|
|
||||||
</defs>
|
|
||||||
<g clip-path="url({$page.path}#{randomId})">
|
|
||||||
<g class="anim anim-spinGlobeSmall">
|
|
||||||
<path d="M36.5 36.9c-2.3-1-2.2.3-3.5-2.2-1.1-.3-1.6-1-2.7-1.2-.4-.3-.3-.8-1.1-.8-.8-.3-1.7.6-2.4-.2-.4.2-.8.6-1.4.5-.3-.2-.9 0-1.3-.5.2-2.9-2.2.1-1.1-2.9l-.1-.1c-2.7 3.2-4.2-2.7-1.2-2.6.9 0 2.5-.6 2.7.9 0 .1.1.4.4.3h.1V28c.1 0-.2-1-.2-1.1-.1-.8 1.3-1.1 1.3-2-.4-.7-.2-.7.6-1.2.8-.6 1.1-1.5 2.3-1.3 0 .4 1 0 1.5-.4-.1-.4-.2-.3-1-.1-1-.8.2-1.5-1.8-.5.3-1.8 4-.6 3.5-2.4-1.2-.5-1.4-1.2-1.9-2.4-.4.1-1.1 1-1.4.2-1.2-2.1-2.9-1.6-2.2.8.1.6-.6.8-.4 1.6.3.8-.6 1-.9 0-.1-1.5-1.9-1-2.8-1.7-2-2.3 3.8-3.6 2.8-4.9-1.1-1.4-.4 2.5-2.7-.9-.5-.5 0-1-.5-1.5-1.4.6 1.3 3.7-1.3 2.5-.8.8-1.3.2-2.3.3-.4.3-.4.4-1.1.4-.8.1-.8-.4-1.5-.7-1.2-.3-2.9-.9-4.2-.1.1-.2.1-.3.2-.5-2.6 1.4-10.1-2.9-8.5 3-.1.4 0 .3-.6.6v.6c.5.3 1.6.3 1.9 1.1-.8.8.1 1 .5.1 3.9-2.9 6.8.2 8.9 3.4 0 2.2.5 4.1 2.1 5.9 0 1 1.8 2.7.5.1.9-1.4 2 4.3 4.8 3.8.1 0 .1 0 .3.1.8.4 1.8.9 2.6 1.7.4.5.9.8 1.5.7l.2.1c1 1.3-1.5 3.1.1 4.5.6 1.5 2.4 1.9 2.3 3.6-.3 1.6 0 3.4-1 4.9.4 1.7-1.2 4.5 1 5.2 1.8.3.4-1.1.6-2.2.1-.6.7-.7.5-1.5-.1-.9 1.6-1.3 2.3-1.8.8-1.3 1.8-2 2.6-3.5.8-1.1 2-.9 2.5-2.5-.1-1 2-2.1.5-3.1zM92.5 12.7c-8.2-1.2-4.2-2.7-10.2-.6-.4-.1-.6-.3-.9-.7-.8-2.2-3.8-.2-5.7-.7-.9-.5 1.9-.6.9-1.7-2.4-1.5-5.4.4-7.7 1.5-.8.4-.6 1.5-1.7 1.6-1.7-1.6-1.2-1.7-3 .2-1.1-.1-1.7.1-2.7.8-1.8.1-2.6.5-4.2 1.7-.6.5-1.9-.5-1.2-1.1.5-.2 1 .3 1.6-.3.5-2.4-4.6-1.7-5.7-.8-5.3 2.8-2.6 6.4-.8 5.3.4-.9-.1-2.1.9-2.8 1.7-1.6.6.3.5 1.1.6.9.3 1.4-.5 2.1-1.8 1.5-4.7.2-5.9 2.7.1 2-.8 1.2-1.8 1.9-1 1.5.6 2.6 2 1.8 1.5-1.2 1.9-3 4-1.3.1.1.1 0 .4.2l.2.2c-.9 1.2 1.3.4.2-.5-.7-.6-.8-2 .5-.5.4.4.4 1.4 1.1 1.3 1.2-.9.8.4 1.9.8 2-.2 2.3 1 .6 1.7-.8.3-1.6-.2-2.6-.3-.9.3-1.9.6-2.6-.3-.8-2.2-3.4-.7-5.2-.5-1 .4-.7 1.6-1.6 2.4-1.9 1.6-1.3 5.3 1.2 6.1 4.6.7 4.2-1.8 5.8 3.4-.4 4.7 1.9 11.8 5.5 4.8.5-.5.4-.9.8-1.6.6-.6 1.2-1.2.9-2.2-.9-3.2 2-3.8 2.3-5.9-1.9.4-4.6-3.7-4.2-5.1 1.5.5 2.5 4.5 3.8 4.1.8-.5 4.1-1.9 2.8-2.8-2.8.3-3.9-3.5-.9-1 7.1.8 4.3 4.5 6.7 5 .7-1.6 3.4-5.9 3.9-1.6 1.2-1.1 1 0 1.2 1.4-.3.5 1.2 2.1.9.8-.1 0-.2-.1-.3-.3-.4-1.9.7 0 1.6-.4 1.3-.7-.3-1.7-.3-2.7.2-.8.9-.2 1.6-.4 2-.6 2.8-2.3 2.3-4.2.5 0 .7-.9-.1-.5-.8-.3 0-1.6 1.1-.7.5.2.6.9 1.3 1.1-.2-1.9 1-2 2.5-3 .9-.7 1.2-1.9 1.1-3.1-.4-.5-1-.1-1.6-.5.5-.7 1.1-1.3 2.2-1.6 1.1-.4 2 0 3.2-.5.4-.2 2.9-1.5 2 .1-.6.7-2.6 2.1-1.2 3 1-.2 1.3-2.2 2.4-2.8 1.7-.2 5.5-1.8 4.1-3.6-.9-.6-2-.6-3.4-.5zm-35 11c-1-.3-2 .1-3.1-.3-.3-.6 1.1-2.6 1.5-1 .4-.2.4-.8 1.3-.8 0 .2-.1.4-.2.8.4.2.7.2 1.1.9-.3.2-.4.3-.6.4zm3.9.8c.1 1.4-1.5.5-1.3-.8-.8-.8-.5-1.7.7-2 .9.2-.2.9 0 1.3.9.5.6.4.6 1.5zM40.5 11.2c-.4-.6.2-1.1.3-1.9.2-.7 0-1.3.5-1.9.2-.6 1.7-.7 1.2-1.5-.7-.4-1.6.7-2.1-.3-2.4-2.5-6.6.1-9.6.1-1.7.3-2.8 1.5-4.2 2.4-.4.8.6.3 1.2.7.4.3.6.6 1.3.4 1.1-.4 3.4 1.1 2.4 2.4.9-.5 2.3.8.3.6.7.6.5.9.5 1.9.3 1 1.6 3.2 2.7 2.2.6-.6.3-1.4 1-2 1.2-.2 1.7-1.1 2.9-1.5.8 0 2.2-.4 1.6-1.6zM85.1 38.9c-.2.6-.6 2.4-1.6 1.3-.2-.7.2-1.5-.8-1.3-.7-.1-.6.4-1.1.9-.5.1-.9 0-1.3.4-3.6 2.8-3.1 1.1-2.3 5.4 1.3.2 3.2-1.4 4.6-.8.6.9 1.7.6 2 1.7.9.7 2.9.8 3.1-1 1.6-3-.4-3.3-1.5-5.3-.4-.4-.4-1-1.1-1.3zM21.1 7.4c.7.5 1.4.1 2.1.7-.1.1-.1.1-.4.3-.5 0-.3.7.3.5 2.5.3 1.8.1 3-1.7 1.2-.7 5.5-2.5 1.5-2.4-1.6.3-5.8.2-5.7 1.5-.3.3-2 .3-.8 1.1z"/>
|
|
||||||
<path d="M28.8 14.2c1.1.6 1.2-.8-.4-1.2-.5-.9-.7-1-1.8-1.6-.6-.5-1.2-.2-2-.4-.3-.5-.4-.6-1.1-.3-.1-1-1.7-.1-1.1.8 2 1.4 3.3-.1 5.1 2.8v.2c-.3-.2-.6-.2-.9-.1-1.7.1-1.5.9 0 .5.6.2 1.1 1.3 2 1 0 0-.1-.4-.3-.6l.6-.3c-.2-.1-.9-1.3-.1-.8zM15.5 12.3v.3c.3.5 1.1.1 1.9.2.6 0 .9.5 1.6 0-.6-.3-.8-2.7-1.5-2.1-.3.2-.7.6-1.3.3-.5-.2-1-.1-1.4.5 0 .3.9.3.7.8zM84.7 38.1c.5.1 1.1-.4 1.7.1.9 1 1.5.4.4-.3-.5-1-2.1-1.9-3.3-1.5-.2-.1-.2-.2-.8-.5h-.1c-1.2-.1 0 .6.9 1.1.7.1.5 1.2 1.2 1.1zM78 33.8c-.4.6-1.6 1.1-1.9 1.8 1.1 2.1 2.8.6 2.3-1.5 0-.3-.1-.4-.4-.3zM59.4 39c-.6.1-.6.9-.8 1.5.5 4.5 2.5-.3.8-1.5zM62.2 12c-.2-1.3.4-1.8 1.5-2.3.1 0 .1 0 .3-.3 0 0 .1 0 .1-.1 1.8 0 1.9-1.5-.5-.2-1.2.2-3.7 2.5-1.4 2.9zM13.4 11.6c1.3-.5 2.7-1.7-.2-1.6-.6.3-1 1.5.2 1.6zM44.8 18.4c.2.1.4.1.6.2.3-.1 1-.2 1-.8-.2-.9-3-.4-1.6.6zM42.9 14.4c-.2-.4-.4-.1-1.1 0-.5 0-.8-.3-1.4 0 .4.9 2.5 1.4 2.5 0zM45.4 19.5c-.1.4.3.5.8.9 1.6-.6.4-1.9-.8-.9zM32.3 21.5c0-.6-.7-1.3-1.1-1.2-1 .1.5 2.2 1.1 1.2zM93.9 47.9c0-.1-.1-.2-.1-.2-2.8.8-1.6 3.3.1.2zM53.1 7.6c.9 0 1.1-1.1-.2-1-.6.2-.7.9.2 1zM50.4 8.2c.9.1 1-1.1-.2-1-.5.2-.6.9.2 1zM94.4 46c-.2-.2-.7-.1-.3.5-.1.2-.1.5 0 .7-.2.3.4 1.1.5.1.2-.2.4-.3.6-.5l-.6-.3c0-.2-.1-.4-.2-.5zM44.3 19.9c.7-.1.7-.5 0-.9-.4.2-1 .7 0 .9zM21.6 9.7c-.3-.1-.6.5 0 .5.1.1.2.1.4.1.3 0 .5-.2.5-.4 0-.3-.5-.4-.9-.2zM85.9 48c.3.6 1.2.1.4-.6-.2.3-.3.5-.4.6zM49.3 24.6c.2-.2.3-.3.4-.5-.1-.2-1-.2-.4.5zM52.6 8.3c-.3-.1-.5-.4-.8.1.2.1.4.4.8-.1zM21 8.4c-.2-.2-.3-.3-.7-.1v.2c.1-.1.4.2.7-.1zM15.4 10c.1 0 .2-.1.4-.2-.2-.2-.3-.4-.7-.1.1.2.2.3.3.3zM17.8 9.9v-.2c-.1.1-.4-.2-.6.1.2.2.4.2.6.1zM18.9 11.8c.1 0 .2-.1.4-.2-.2-.1-.3-.4-.6 0l.2.2zM68.5 33.5c0 .3.7.2.2-.3-.1.1-.2.2-.2.3z"/>
|
|
||||||
<path d="M26.2 13.4c0-.1-.2-.1-.2-.2-.1.1-.4.2 0 .5.1-.1.2-.2.2-.3zM25 10.5v.1c.3.3.3.3.6 0-.2 0-.4-.1-.6-.1zM54 25.4h-.4v.2h.4v-.2zM49.4 18.6c0 .1-.3 0-.1.3 0-.1.3-.1.1-.3zM24.1 15.7s0 .2.2 0c-.1.1 0-.1-.2 0zM20.7 10.1c0 .1.1.1.1 0 0 0 .1-.1-.1 0zM10.9 12.4zM76.7 37.3c-.5-.3-1.2-.5-1.5-1.1-4.8-5.7-2.1 1.9 1.4 1.6.3 0 .6.4.9 0 0-.3-.6-.5-.8-.5zM24.9 15.2c-.1-.3-.1-.3-.8-.4-.2-.1-.7-.7-.8 0-.3 0-.6.8.2.5h.4c0-.1.7.4 1-.1zM133.5 36.9c-2.3-1-2.2.3-3.5-2.2-1.1-.3-1.6-1-2.7-1.2-.4-.3-.3-.8-1.1-.8-.8-.3-1.7.6-2.4-.2-.4.2-.8.6-1.4.5-.3-.2-.9 0-1.3-.5.2-2.9-2.2.1-1.1-2.9l-.1-.1c-2.7 3.2-4.2-2.7-1.2-2.6.9 0 2.5-.6 2.7.9 0 .1.1.4.4.3h.1V28c.1 0-.2-1-.2-1.1-.1-.8 1.3-1.1 1.3-2-.4-.7-.2-.7.6-1.2.8-.6 1.1-1.5 2.3-1.3 0 .4 1 0 1.5-.4-.1-.4-.2-.3-1-.1-1-.8.2-1.5-1.8-.5.3-1.8 4-.6 3.5-2.4-1.2-.5-1.4-1.2-1.9-2.4-.4.1-1.1 1-1.4.2-1.2-2.1-2.9-1.6-2.2.8.1.6-.6.8-.4 1.6.3.8-.6 1-.9 0-.1-1.5-1.9-1-2.8-1.7-2-2.3 3.8-3.6 2.8-4.9-1.1-1.4-.4 2.5-2.7-.9-.5-.5 0-1-.5-1.5-1.4.6 1.3 3.7-1.3 2.5-.8.8-1.3.2-2.3.3-.4.3-.4.4-1.1.4-.8.1-.8-.4-1.5-.7-1.2-.3-2.9-.9-4.2-.1.1-.2.1-.3.2-.5-2.6 1.4-10.1-2.9-8.5 3-.1.4 0 .3-.6.6v.6c.5.3 1.6.3 1.9 1.1-.8.8.1 1 .5.1 3.9-2.9 6.8.2 8.9 3.4 0 2.2.5 4.1 2.1 5.9 0 1 1.8 2.7.5.1.9-1.4 2 4.3 4.8 3.8.1 0 .1 0 .3.1.8.4 1.8.9 2.6 1.7.4.5.9.8 1.5.7l.2.1c1 1.3-1.5 3.1.1 4.5.6 1.5 2.4 1.9 2.3 3.6-.3 1.6 0 3.4-1 4.9.4 1.7-1.2 4.5 1 5.2 1.8.3.4-1.1.6-2.2.1-.6.7-.7.5-1.5-.1-.9 1.6-1.3 2.3-1.8.8-1.3 1.8-2 2.6-3.5.8-1.1 2-.9 2.5-2.5-.2-1 2-2.1.5-3.1zM193 13.4c-1-.8-2.1-.8-3.5-.7-8.2-1.2-4.2-2.7-10.2-.6-.4-.1-.6-.3-.9-.7-.8-2.2-3.8-.2-5.7-.7-.9-.5 1.9-.6.9-1.7-2.4-1.5-5.4.4-7.7 1.5-.8.4-.6 1.5-1.7 1.6-1.7-1.6-1.2-1.7-3 .2-1.1-.1-1.7.1-2.7.8-1.8.1-2.6.5-4.2 1.7-.6.5-1.9-.5-1.2-1.1.5-.2 1 .3 1.6-.3.5-2.4-4.6-1.7-5.7-.8-5.3 2.8-2.6 6.4-.8 5.3.4-.9-.1-2.1.9-2.8 1.7-1.6.6.3.5 1.1.6.9.3 1.4-.5 2.1-1.8 1.5-4.7.2-5.9 2.7.1 2-.8 1.2-1.8 1.9-1 1.5.6 2.6 2 1.8 1.5-1.2 1.9-3 4-1.3.1.1.1 0 .4.2l.2.2c-.9 1.2 1.3.4.2-.5-.7-.6-.8-2 .5-.5.4.4.4 1.4 1.1 1.3 1.2-.9.8.4 1.9.8 2-.2 2.3 1 .6 1.7-.8.3-1.6-.2-2.6-.3-.9.3-1.9.6-2.6-.3-.8-2.2-3.4-.7-5.2-.5-1 .4-.7 1.6-1.6 2.4-1.9 1.6-1.3 5.3 1.2 6.1 4.6.7 4.2-1.8 5.8 3.4-.4 4.7 1.9 11.8 5.5 4.8.5-.5.4-.9.8-1.6.6-.6 1.2-1.2.9-2.2-.9-3.2 2-3.8 2.3-5.9-1.9.4-4.6-3.7-4.2-5.1 1.5.5 2.5 4.5 3.8 4.1.8-.5 4.1-1.9 2.8-2.8-2.8.3-3.9-3.5-.9-1 7.1.8 4.3 4.5 6.7 5 .7-1.6 3.4-5.9 3.9-1.6 1.2-1.1 1 0 1.2 1.4-.3.5 1.2 2.1.9.8-.1 0-.2-.1-.3-.3-.4-1.9.7 0 1.6-.4 1.3-.7-.3-1.7-.3-2.7.2-.8.9-.2 1.6-.4 2-.6 2.8-2.3 2.3-4.2.5 0 .7-.9-.1-.5-.8-.3 0-1.6 1.1-.7.5.2.6.9 1.3 1.1-.2-1.9 1-2 2.5-3 .9-.7 1.2-1.9 1.1-3.1-.4-.5-1-.1-1.6-.5.5-.7 1.1-1.3 2.2-1.6 1.1-.4 2 0 3.2-.5.4-.2 2.9-1.5 2 .1-.6.7-2.6 2.1-1.2 3 1-.2 1.3-2.2 2.4-2.8 1.7.1 5.5-1.5 4.2-3.4zm-38.6 10.3c-1-.3-2 .1-3.1-.3-.3-.6 1.1-2.6 1.5-1 .4-.2.4-.8 1.3-.8 0 .2-.1.4-.2.8.4.2.7.2 1.1.9-.2.2-.4.3-.6.4zm3.9.8c.1 1.4-1.5.5-1.3-.8-.8-.8-.5-1.7.7-2 .9.2-.2.9 0 1.3 1 .5.6.4.6 1.5zM137.5 11.2c-.4-.6.2-1.1.3-1.9.1-.7-.1-1.3.4-1.9.2-.6 1.7-.7 1.2-1.5-.7-.4-1.6.7-2.1-.3-2.4-2.5-6.6.1-9.6.1-1.7.3-2.7 1.5-4.1 2.4-.4.8.6.3 1.2.7.4.3.6.6 1.3.4 1.1-.4 3.4 1.1 2.4 2.4.9-.5 2.3.8.3.6.7.6.5.9.5 1.9.3 1 1.6 3.2 2.7 2.2.6-.6.3-1.4 1-2 1.2-.2 1.7-1.1 2.9-1.5.7 0 2.2-.4 1.6-1.6zM182.1 38.9c-.2.6-.6 2.4-1.6 1.3-.2-.7.2-1.5-.8-1.3-.7-.1-.6.4-1.1.9-.5.1-.9 0-1.3.4-3.6 2.8-3.1 1.1-2.3 5.4 1.3.2 3.2-1.4 4.6-.8.6.9 1.7.6 2 1.7.9.7 2.9.8 3.1-1 1.6-3-.4-3.3-1.5-5.3-.5-.4-.5-1-1.1-1.3zM118.1 7.4c.7.5 1.4.1 2.1.7-.1.1-.1.1-.4.3-.5 0-.3.7.3.5 2.5.3 1.8.1 3-1.7 1.2-.7 5.5-2.5 1.5-2.4-1.6.3-5.9.1-5.8 1.5-.3.3-1.9.3-.7 1.1z"/>
|
|
||||||
<path d="M125.8 14.2c1.1.6 1.2-.8-.4-1.2-.5-.9-.7-1-1.8-1.6-.6-.5-1.2-.2-2-.4-.3-.5-.4-.6-1.1-.3-.1-1-1.7-.1-1.1.8 2 1.4 3.3-.1 5.1 2.8v.2c-.3-.2-.6-.2-.9-.1-1.7.1-1.5.9 0 .5.6.2 1.1 1.3 2 1 0 0-.1-.4-.3-.6l.6-.3c-.2-.1-1-1.3-.1-.8zM112.5 12.3v.3c.3.5 1.1.1 1.9.2.6 0 .9.5 1.6 0-.6-.3-.8-2.7-1.5-2.1-.3.2-.7.6-1.3.3-.5-.2-1-.1-1.4.5 0 .3.9.3.7.8zM181.7 38.1c.5.1 1.1-.4 1.7.1.9 1 1.5.4.4-.3-.5-1-2.1-1.9-3.3-1.5-.2-.1-.2-.2-.8-.5h-.1c-1.2-.1 0 .6.9 1.1.6.1.4 1.2 1.2 1.1zM175 33.8c-.4.6-1.6 1.1-1.9 1.8 1.1 2.1 2.8.6 2.3-1.5 0-.3-.2-.4-.4-.3zM156.4 39c-.6.1-.6.9-.8 1.5.5 4.5 2.5-.3.8-1.5zM159.2 12c-.2-1.3.4-1.8 1.5-2.3.1 0 .1 0 .3-.3 0 0 .1 0 .1-.1 1.8 0 1.9-1.5-.5-.2-1.2.2-3.8 2.5-1.4 2.9zM110.4 11.6c1.3-.5 2.7-1.7-.2-1.6-.7.3-1 1.5.2 1.6zM141.7 18.4c.2.1.4.1.6.2.3-.1 1-.2 1-.8-.2-.9-3-.4-1.6.6zM139.9 14.4c-.2-.4-.4-.1-1.1 0-.5 0-.8-.3-1.4 0 .3.9 2.4 1.4 2.5 0zM142.4 19.5c-.1.4.3.5.8.9 1.6-.6.3-1.9-.8-.9zM129.3 21.5c0-.6-.7-1.3-1.1-1.2-1 .1.4 2.2 1.1 1.2zM190.8 47.9c0-.1-.1-.2-.1-.2-2.7.8-1.6 3.3.1.2zM150 7.6c.9 0 1.1-1.1-.2-1-.6.2-.7.9.2 1zM147.4 8.2c.9.1 1-1.1-.2-1-.6.2-.6.9.2 1zM191.4 46c-.2-.2-.7-.1-.3.5-.1.2-.1.5 0 .7-.2.3.4 1.1.5.1.2-.2.4-.3.6-.5l-.6-.3c-.1-.2-.1-.4-.2-.5zM141.3 19.9c.7-.1.7-.5 0-.9-.4.2-1.1.7 0 .9zM118.6 9.7c-.3-.1-.6.5 0 .5.1.1.2.1.4.1.3 0 .5-.2.5-.4-.1-.3-.5-.4-.9-.2zM182.9 48c.3.6 1.2.1.4-.6-.2.3-.4.5-.4.6zM146.3 24.6c.2-.2.3-.3.4-.5-.2-.2-1.1-.2-.4.5zM149.5 8.3c-.3-.1-.5-.4-.8.1.2.1.4.4.8-.1zM118 8.4c-.2-.2-.3-.3-.7-.1v.2c.1-.1.4.2.7-.1zM112.3 10c.1 0 .2-.1.4-.2-.2-.2-.3-.4-.7-.1.1.2.2.3.3.3zM114.7 9.9v-.2c-.1.1-.4-.2-.6.1.2.2.4.2.6.1zM115.9 11.8c.1 0 .2-.1.4-.2-.2-.1-.3-.4-.6 0 0 .1.1.2.2.2zM165.5 33.5c0 .3.7.2.2-.3-.1.1-.2.2-.2.3z"/>
|
|
||||||
<path d="M123.1 13.4c0-.1-.2-.1-.2-.2-.1.1-.4.2 0 .5.1-.1.2-.2.2-.3zM121.9 10.5v.1c.3.3.3.3.6 0-.2 0-.4-.1-.6-.1zM150.9 25.4h-.4v.2h.4c.1 0 .1-.1 0-.2zM146.4 18.6c0 .1-.3 0-.1.3 0-.1.3-.1.1-.3zM121 15.7s0 .2.2 0c0 .1 0-.1-.2 0zM117.7 10.1c0 .1.1.1.1 0 0 0 0-.1-.1 0zM107.9 12.4h-.1.1zM173.6 37.3c-.5-.3-1.2-.5-1.5-1.1-4.8-5.7-2.1 1.9 1.4 1.6.3 0 .6.4.9 0 .1-.3-.5-.5-.8-.5zM121.8 15.2c-.1-.3-.1-.3-.8-.4-.2-.1-.7-.7-.8 0-.3 0-.6.8.2.5h.4c.1-.1.8.4 1-.1z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<path fill="none" d="M28 2.8C14.1 2.8 2.8 14.1 2.8 28S14.1 53.2 28 53.2 53.2 41.9 53.2 28 41.9 2.8 28 2.8z"/>
|
|
||||||
<path d="M28 0C12.6 0 0 12.6 0 28s12.6 28 28 28 28-12.6 28-28S43.4 0 28 0zm0 53.2C14.1 53.2 2.8 41.9 2.8 28S14.1 2.8 28 2.8 53.2 14.1 53.2 28 41.9 53.2 28 53.2z"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
<script>
|
|
||||||
export let width = 18
|
|
||||||
export let color = '#fff'
|
|
||||||
export let hidden = undefined
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 19 18" {width} fill={color} class={$$props.class} aria-hidden={hidden}>
|
|
||||||
<path fill-rule="evenodd" d="M8.36 0a7.76 7.76 0 016.02 12.63l3.99 3.99a.81.81 0 11-1.15 1.14l-3.99-3.99A7.76 7.76 0 118.35 0zm0 1.62a6.14 6.14 0 10.01 12.28 6.14 6.14 0 00-.01-12.28zm2.38 5.32a.81.81 0 110 1.62H5.98a.81.81 0 110-1.62z"/>
|
|
||||||
</svg>
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
<script>
|
|
||||||
export let href = '#'
|
|
||||||
export let text = ''
|
|
||||||
export let noScroll = undefined
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<a href={href} class="link-change" sapper-noscroll={noScroll}>
|
|
||||||
{text}
|
|
||||||
<span class="icon">
|
|
||||||
<slot></slot>
|
|
||||||
</span>
|
|
||||||
</a>
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
<script>
|
|
||||||
export let href = '/'
|
|
||||||
export let text = ''
|
|
||||||
export let target = null
|
|
||||||
export let rel = null
|
|
||||||
export let active = false
|
|
||||||
export let noScroll = undefined
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<a {href} {target} {rel} class="link-translate" class:is-active={!!active} sapper-noscroll={noScroll}>
|
|
||||||
<slot />
|
|
||||||
<div class="text" data-text={text}>
|
|
||||||
<span>{text}</span>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
<script>
|
|
||||||
import { onMount } from 'svelte'
|
|
||||||
import { charsToSpan } from 'utils/functions'
|
|
||||||
// Animations
|
|
||||||
import { animateIn } from 'animations/TitleSite'
|
|
||||||
|
|
||||||
// Props and variables
|
|
||||||
export let init = false
|
|
||||||
let mounted = false
|
|
||||||
let scope
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Run code when mounted
|
|
||||||
*/
|
|
||||||
onMount(() => {
|
|
||||||
animateIn(scope, init)
|
|
||||||
mounted = true
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div class="title-location title-location--inline" role="heading" aria-level="1"
|
|
||||||
bind:this={scope}
|
|
||||||
style="opacity: {mounted ? 1 : 0}"
|
|
||||||
>
|
|
||||||
<div aria-label="Houses">
|
|
||||||
<div class="anim-mask">
|
|
||||||
{@html charsToSpan('Houses')}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<em class="anim-mask">
|
|
||||||
<span>of</span>
|
|
||||||
<span>the</span>
|
|
||||||
</em>
|
|
||||||
|
|
||||||
<div aria-label="World">
|
|
||||||
<div class="anim-mask">
|
|
||||||
{@html charsToSpan('World')}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
<script>
|
|
||||||
import { onMount } from 'svelte'
|
|
||||||
|
|
||||||
// Variables
|
|
||||||
let toggleEl
|
|
||||||
let grid
|
|
||||||
let pill
|
|
||||||
let layoutSetting
|
|
||||||
|
|
||||||
// Elements
|
|
||||||
const layoutGridClass = 'photos--grid'
|
|
||||||
const layoutListClass = 'photos--list'
|
|
||||||
|
|
||||||
// Change active pill
|
|
||||||
const toggleAnimate = (elem, pill, toggle) => {
|
|
||||||
pill.style.width = Math.round(elem.getBoundingClientRect().width) + 'px'
|
|
||||||
pill.style.left = Math.round(elem.getBoundingClientRect().left - toggleEl.getBoundingClientRect().left) + 'px'
|
|
||||||
}
|
|
||||||
|
|
||||||
// Toggle layout
|
|
||||||
const toggleLayout = event => {
|
|
||||||
const clicked = event.currentTarget
|
|
||||||
const type = clicked.dataset.layout
|
|
||||||
|
|
||||||
// Change the layout
|
|
||||||
switch (type) {
|
|
||||||
case 'grid':
|
|
||||||
grid.classList.add(layoutGridClass)
|
|
||||||
grid.classList.remove(layoutListClass)
|
|
||||||
break
|
|
||||||
case 'list':
|
|
||||||
grid.classList.add(layoutListClass)
|
|
||||||
grid.classList.remove(layoutGridClass)
|
|
||||||
break
|
|
||||||
default: break
|
|
||||||
}
|
|
||||||
|
|
||||||
// Animate the active pill
|
|
||||||
toggleAnimate(clicked, pill, toggleEl)
|
|
||||||
|
|
||||||
// Add/Remove active classes
|
|
||||||
toggleEl.querySelectorAll('button').forEach(button => button.classList.remove('active'))
|
|
||||||
clicked.classList.add('active')
|
|
||||||
|
|
||||||
// Remember this setting
|
|
||||||
localStorage.setItem('photosLayout', type)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Run code when mounted
|
|
||||||
*/
|
|
||||||
onMount(() => {
|
|
||||||
grid = document.querySelector('.photos')
|
|
||||||
|
|
||||||
// Get layout setting from storage
|
|
||||||
layoutSetting = (localStorage.getItem('photosLayout')) ? localStorage.getItem('photosLayout') : 'list'
|
|
||||||
|
|
||||||
// Init of first option
|
|
||||||
toggleAnimate(toggleEl.querySelector(`[data-layout="${layoutSetting}"]`), pill, toggleEl)
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div class="toggle" role="switch" aria-checked="true" bind:this={toggleEl}>
|
|
||||||
<button data-layout="list" class:active={layoutSetting === 'list'} on:click={toggleLayout}>
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="19" height="17" viewBox="0 0 19 17">
|
|
||||||
<g class="anim">
|
|
||||||
<rect width="15" height="3"/>
|
|
||||||
<rect width="15" height="3" x="4" y="7"/>
|
|
||||||
<rect width="15" height="3" y="14"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
<span>List</span>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button data-layout="grid" class:active={layoutSetting === 'grid'} on:click={toggleLayout}>
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="18" height="20" viewBox="0 0 18 20">
|
|
||||||
<g class="anim">
|
|
||||||
<rect width="7" height="7"/>
|
|
||||||
<rect width="7" height="7" x="11" y="2"/>
|
|
||||||
<rect width="7" height="7" y="11"/>
|
|
||||||
<rect width="7" height="7" x="11" y="13"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
<span>Grid</span>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<div class="pill" aria-hidden="true" role="presentation" bind:this={pill}></div>
|
|
||||||
</div>
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
import * as sapper from '@sapper/app'
|
|
||||||
|
|
||||||
// Start Sapper
|
|
||||||
sapper.start({
|
|
||||||
target: document.body
|
|
||||||
})
|
|
||||||
25
src/components/Metas.svelte
Normal file
25
src/components/Metas.svelte
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
export let title: string = ''
|
||||||
|
export let description: string = ''
|
||||||
|
export let image: string = ''
|
||||||
|
export let url: string = undefined
|
||||||
|
export let type: string = 'website'
|
||||||
|
export let card: string = 'summary_large_image'
|
||||||
|
export let creator: string = '@flayks'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svelte:head>
|
||||||
|
<title>{title}</title>
|
||||||
|
<meta name="description" content={description}>
|
||||||
|
|
||||||
|
<meta property="og:title" content={title} />
|
||||||
|
<meta property="og:description" content={description} />
|
||||||
|
<meta property="og:image" content={image} />
|
||||||
|
<meta property="og:type" content={type} />
|
||||||
|
{#if url}
|
||||||
|
<meta property="og:url" content={url} />
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<meta property="twitter:card" content={card} />
|
||||||
|
<meta property="twitter:creator" content={creator} />
|
||||||
|
</svelte:head>
|
||||||
3
src/components/molecules/Location.svelte
Normal file
3
src/components/molecules/Location.svelte
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
export let location
|
||||||
|
</script>
|
||||||
27
src/components/organisms/Locations.svelte
Normal file
27
src/components/organisms/Locations.svelte
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<script>
|
||||||
|
// Components
|
||||||
|
import Button from '$components/atoms/Button.svelte'
|
||||||
|
import Location from '$components/molecules/Location.svelte'
|
||||||
|
|
||||||
|
export let locations
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="browse">
|
||||||
|
<div class="browse__description">
|
||||||
|
<p>Browse all the cities and countries</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ul class="browse__continents" id="continents">
|
||||||
|
<li>
|
||||||
|
<Button type="button" text="All" class="button-outline" />
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="browse__locations" id="locations_list" role="list">
|
||||||
|
{#each locations as location (location.id)}
|
||||||
|
<Location
|
||||||
|
location={location}
|
||||||
|
/>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
1
src/global.d.ts
vendored
Normal file
1
src/global.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
/// <reference types="@sveltejs/kit" />
|
||||||
@@ -1,112 +0,0 @@
|
|||||||
<script>
|
|
||||||
import { onMount, onDestroy } from 'svelte'
|
|
||||||
import { continents, locations } from 'utils/store'
|
|
||||||
import { getPosition, getRandomArrayItem } from 'utils/functions'
|
|
||||||
// Dependencies
|
|
||||||
import ScrollOut from 'scroll-out'
|
|
||||||
import Lazy from 'svelte-lazy'
|
|
||||||
|
|
||||||
// Props
|
|
||||||
export let type = null
|
|
||||||
export let autoRotate = true
|
|
||||||
export let scrollSmooth = 0.5
|
|
||||||
export let opacity = 1
|
|
||||||
let scope
|
|
||||||
let globe
|
|
||||||
let windowHeight
|
|
||||||
let containerTop = 0
|
|
||||||
let containerHeight = 0
|
|
||||||
$: randomRotationPosition = getRandomArrayItem($continents.filter(continent => continent.countries)).rotation_position
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Functions
|
|
||||||
*/
|
|
||||||
// Globe update
|
|
||||||
const update = () => {
|
|
||||||
requestAnimationFrame(update)
|
|
||||||
globe.update()
|
|
||||||
}
|
|
||||||
|
|
||||||
// On scroll
|
|
||||||
const onScroll = () => {
|
|
||||||
let scrollDiff = (containerTop + windowHeight + (containerHeight - windowHeight) / 2) - document.documentElement.scrollTop
|
|
||||||
let scrollRatio = (1 - (scrollDiff / windowHeight)) * 2
|
|
||||||
globe && globe.updateCameraPos(scrollRatio, scrollDiff - windowHeight)
|
|
||||||
}
|
|
||||||
|
|
||||||
// On resize
|
|
||||||
const onResize = () => {
|
|
||||||
if (scope) {
|
|
||||||
containerTop = getPosition(scope).top
|
|
||||||
containerHeight = scope.clientHeight
|
|
||||||
}
|
|
||||||
if (globe) {
|
|
||||||
globe.resize()
|
|
||||||
globe.update()
|
|
||||||
}
|
|
||||||
onScroll()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Run code when mounted
|
|
||||||
*/
|
|
||||||
onMount(async () => {
|
|
||||||
// Import libraries and code
|
|
||||||
let InteractiveGlobe
|
|
||||||
await import('globe/index').then(module => InteractiveGlobe = module.default)
|
|
||||||
|
|
||||||
// Init the globe from library
|
|
||||||
globe = new InteractiveGlobe({
|
|
||||||
el: scope,
|
|
||||||
//cameraDistance: size, // Smaller number == larger globe
|
|
||||||
autoRotationSpeed: autoRotate ? -0.0025 : 0,
|
|
||||||
rotationStart: randomRotationPosition, // In degrees
|
|
||||||
scrollSmoothing: scrollSmooth,
|
|
||||||
opacity: opacity,
|
|
||||||
texture: `/img/globe/map-${window.innerWidth > 1440 && window.devicePixelRatio > 1 ? '4k' : '2k'}.png`,
|
|
||||||
markers: [ ...$locations.map(location => {
|
|
||||||
return {
|
|
||||||
name: location.name,
|
|
||||||
slug: location.slug,
|
|
||||||
countryName: location.country.name,
|
|
||||||
countrySlug: location.country.slug,
|
|
||||||
lat: location.coordinates.lat,
|
|
||||||
lng: location.coordinates.lng,
|
|
||||||
className: location.close ? 'is-close' : '',
|
|
||||||
}
|
|
||||||
}) ],
|
|
||||||
onLinkClicked: () => {}
|
|
||||||
})
|
|
||||||
|
|
||||||
// Run the globe
|
|
||||||
update()
|
|
||||||
onResize()
|
|
||||||
|
|
||||||
// Enable/Disable the globe when shown/hidden
|
|
||||||
const globeScroll = ScrollOut({
|
|
||||||
targets: scope,
|
|
||||||
onShown: () => globe.enable(),
|
|
||||||
onHidden: () => globe.disable()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Destroy when unmounted
|
|
||||||
*/
|
|
||||||
onDestroy(() => {
|
|
||||||
globe && globe.destroy()
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<svelte:window on:scroll={onScroll} on:resize={onResize} bind:innerHeight={windowHeight} />
|
|
||||||
|
|
||||||
{#if type === 'part'}
|
|
||||||
<div class="globe--part">
|
|
||||||
<div class="globe" bind:this={scope} />
|
|
||||||
</div>
|
|
||||||
{:else}
|
|
||||||
<div class="globe" bind:this={scope} />
|
|
||||||
{/if}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
<script>
|
|
||||||
import { dateOlderThan } from 'utils/functions'
|
|
||||||
// Components
|
|
||||||
import Badge from 'atoms/Badge'
|
|
||||||
|
|
||||||
// Props
|
|
||||||
export let location
|
|
||||||
|
|
||||||
// Variables
|
|
||||||
const { name, slug, country, last_updated } = location
|
|
||||||
const timeLimit = 2 * 7 * 24 * 60 * 60 * 1000 // d*h*m*s*ms = 1 week
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div class="location" role="listitem">
|
|
||||||
<a href="/location/{country.slug}/{slug}" rel="prefetch" sapper-noscroll>
|
|
||||||
<img src={country.flag.full_url} alt="Flag of {country.name}">
|
|
||||||
|
|
||||||
<div class="anim-mask mask-city">
|
|
||||||
<h3 class="location__city">{name}</h3>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="anim-mask mask-country">
|
|
||||||
<p class="location__country style-caps">{country.name}</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{#if dateOlderThan(last_updated, timeLimit)}
|
|
||||||
<Badge size="small" text="new" />
|
|
||||||
{/if}
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
<script>
|
|
||||||
import { site } from 'utils/store'
|
|
||||||
// Components
|
|
||||||
import IconArrow from 'atoms/IconArrow'
|
|
||||||
|
|
||||||
// Props
|
|
||||||
export let title = false
|
|
||||||
export let small = false
|
|
||||||
export let brightness = 'dark'
|
|
||||||
export let align = 'center'
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<form method="POST" action={$site.newsletter_url} target="_blank" id="sib-form" class="form"
|
|
||||||
class:form--light={brightness === 'light'}
|
|
||||||
class:page__part={!small}
|
|
||||||
>
|
|
||||||
{#if title}
|
|
||||||
<h2 class="style-location">
|
|
||||||
<label for="SUB_EMAIL">{$site.newsletter_subtitle}</label>
|
|
||||||
</h2>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
<div class="newsletter__input form__group form__inputgroup">
|
|
||||||
<input type="email" id="SUB_EMAIL" name="EMAIL" value="" placeholder="Your email address..." class="input__text" required>
|
|
||||||
<button type="submit" form="sib-form" aria-label="Subscribe" class="button-control dir-right"
|
|
||||||
class:button-control--pink={brightness === 'light'}
|
|
||||||
class:button-control--lightpink={brightness === 'dark'}
|
|
||||||
>
|
|
||||||
<IconArrow direction="right" color="#fff" class="icon" width="12" />
|
|
||||||
<IconArrow direction="right" color="#fff" class="icon" width="12" hidden="true" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="newsletter__notice" class:is-aligned--right={align === 'right'}>
|
|
||||||
<p class="style-notice">No spam, we promise!</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<input type="text" name="email_address_check" value="" style="display: none;">
|
|
||||||
<input type="hidden" name="locale" value="en">
|
|
||||||
<input type="hidden" name="html_type" value="simple">
|
|
||||||
</form>
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
<script>
|
|
||||||
import { createEventDispatcher } from 'svelte'
|
|
||||||
|
|
||||||
// Props
|
|
||||||
export let className = ''
|
|
||||||
export let photos
|
|
||||||
export let currentIndex
|
|
||||||
const dispatch = createEventDispatcher()
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<ol class={className}>
|
|
||||||
{#each photos as dot, index}
|
|
||||||
<li
|
|
||||||
class:active={index === currentIndex}
|
|
||||||
class:small={index < currentIndex - 2 || index > currentIndex + 2}
|
|
||||||
class:hidden={index < currentIndex - 3 || index > currentIndex + 3}
|
|
||||||
on:click={() => dispatch('goToIndex', index)}
|
|
||||||
>
|
|
||||||
<button aria-label="Go to photo #{index + 1}"></button>
|
|
||||||
</li>
|
|
||||||
{/each}
|
|
||||||
</ol>
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
<script>
|
|
||||||
import { onMount } from 'svelte'
|
|
||||||
import { site, currentLocation } from 'utils/store'
|
|
||||||
import { getThumbnail, formatDate } from 'utils/functions'
|
|
||||||
// Animations
|
|
||||||
import { animateIn } from 'animations/Photo'
|
|
||||||
|
|
||||||
// Props and variables
|
|
||||||
export let photo
|
|
||||||
export let index
|
|
||||||
let scope
|
|
||||||
|
|
||||||
// Default size for the image
|
|
||||||
const defaultWidth = 900
|
|
||||||
const defaultHeight = Math.ceil(defaultWidth / 1.5)
|
|
||||||
|
|
||||||
// Location related
|
|
||||||
const { name, date, location, city } = photo
|
|
||||||
const { private_hash } = photo.image
|
|
||||||
const imgAlt = `${name}, ${city ? city : location.region}, ${location.country.name}`
|
|
||||||
const nameSplit = name.split(', ')
|
|
||||||
|
|
||||||
// Photo index
|
|
||||||
const odd = index % 2 === 1
|
|
||||||
const photoIndex = (index < 10 ? '0': '') + index
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Run code when mounted
|
|
||||||
*/
|
|
||||||
onMount(() => {
|
|
||||||
animateIn(scope)
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div class="photo" class:photo--odd={odd} role="figure" aria-labelledby="photo-{index + 1}" bind:this={scope}>
|
|
||||||
<div class="photo__location wrap">
|
|
||||||
<div class="wrapper">
|
|
||||||
<h2 class="title-location" id="photo-{index + 1}">
|
|
||||||
{#each nameSplit as _, i}
|
|
||||||
<span class="line">
|
|
||||||
<span>
|
|
||||||
{nameSplit[i]}{#if i < nameSplit.length - 1},{/if}
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
{/each}
|
|
||||||
</h2>
|
|
||||||
<p class="style-caps">{city ? city : location.region}, {location.country.name}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="photo__image wrap">
|
|
||||||
<div class="align">
|
|
||||||
<a href="/viewer/{location.country.slug}/{location.slug}/{photo.slug}" sapper-noscroll>
|
|
||||||
<picture class="photo__picture">
|
|
||||||
<source media="(min-width: 992px)" data-srcset={getThumbnail(private_hash, 1200)}>
|
|
||||||
<source media="(min-width: 768px)" data-srcset={getThumbnail(private_hash, 992)}>
|
|
||||||
<source media="(min-width: 500px)" data-srcset={getThumbnail(private_hash, 650)}>
|
|
||||||
<source media="(min-width: 300px)" data-srcset={getThumbnail(private_hash, 400)}>
|
|
||||||
<img src="data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs="
|
|
||||||
width={defaultWidth} height={defaultHeight}
|
|
||||||
alt={imgAlt}
|
|
||||||
class="lazyload"
|
|
||||||
/>
|
|
||||||
</picture>
|
|
||||||
</a>
|
|
||||||
<time class="photo__date" datetime={formatDate(date, 'DATETIME')}>
|
|
||||||
{formatDate(date, 'FULL')}
|
|
||||||
</time>
|
|
||||||
<div class="photo__number">
|
|
||||||
<span>{photoIndex}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
<script>
|
|
||||||
import { currentLocation } from 'utils/store'
|
|
||||||
// Components
|
|
||||||
import IconGlobe from 'atoms/IconGlobe'
|
|
||||||
|
|
||||||
// Props
|
|
||||||
export let type = ''
|
|
||||||
export let radius = 32
|
|
||||||
|
|
||||||
// Variables
|
|
||||||
let location
|
|
||||||
let locationName
|
|
||||||
let locationOf
|
|
||||||
|
|
||||||
$: {
|
|
||||||
location = $currentLocation
|
|
||||||
locationName = location ? location.name : 'World'
|
|
||||||
locationOf = location ? 'Of' : 'Of The'
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div class="switcher {type}">
|
|
||||||
<div class="switcher__text" class:empty={!location}>
|
|
||||||
<a href="/" sapper-noscroll>
|
|
||||||
{#if !location}
|
|
||||||
<span class="top">Houses</span>
|
|
||||||
<span class="bottom">
|
|
||||||
<em class="same-line">{locationOf}</em> {locationName}
|
|
||||||
</span>
|
|
||||||
{:else}
|
|
||||||
<span class="top">Houses <em>{locationOf}</em></span>
|
|
||||||
<span class="bottom">{locationName}</span>
|
|
||||||
{/if}
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="button-control button-control--dashed switcher__icon">
|
|
||||||
<a href="/choose" aria-label="Change the location" sapper-noscroll>
|
|
||||||
<IconGlobe
|
|
||||||
color={type.includes('side') ? '#333' : '#fff'}
|
|
||||||
width={type.includes('side') ? 18 : 24}
|
|
||||||
/>
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
|
|
||||||
<circle cx="50%" cy="50%" r="{type.includes('side') ? 24 : radius}px"></circle>
|
|
||||||
</svg>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@@ -1,242 +0,0 @@
|
|||||||
<script>
|
|
||||||
import { onMount, createEventDispatcher } from 'svelte'
|
|
||||||
import { stores } from '@sapper/app'
|
|
||||||
import { currentLocation, fullscreen } from 'utils/store'
|
|
||||||
import { getThumbnail, formatDate } from 'utils/functions'
|
|
||||||
// Dependencies
|
|
||||||
import SwipeListener from 'swipe-listener'
|
|
||||||
// Animations
|
|
||||||
import { animateIn } from 'animations/Carousel'
|
|
||||||
// Components
|
|
||||||
import IconArrow from 'atoms/IconArrow'
|
|
||||||
import Counter from 'atoms/Counter'
|
|
||||||
import PaginationDots from 'molecules/PaginationDots'
|
|
||||||
|
|
||||||
// Props and Variables
|
|
||||||
export let photos
|
|
||||||
export let viewer = false
|
|
||||||
export let locationUrl = false
|
|
||||||
const dispatch = createEventDispatcher()
|
|
||||||
const { page } = stores()
|
|
||||||
let scope
|
|
||||||
let swiped
|
|
||||||
let currentIndex = 0
|
|
||||||
|
|
||||||
// Reactive variables from currentIndex
|
|
||||||
$: currentPhoto = photos[currentIndex] || null
|
|
||||||
$: prevPhoto = photos[currentIndex - 1] || photos[photos.length - 1]
|
|
||||||
$: nextPhoto = photos[currentIndex + 1] || photos[0]
|
|
||||||
|
|
||||||
// Default size for the image
|
|
||||||
const defaultWidth = 900
|
|
||||||
const defaultHeight = Math.ceil(defaultWidth / 1.5)
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Navigate to a photo
|
|
||||||
*/
|
|
||||||
// Change current index from param
|
|
||||||
const goToPhoto = to => {
|
|
||||||
if (to === 'prev') {
|
|
||||||
currentIndex--
|
|
||||||
currentIndex = (currentIndex < 0) ? photos.length - 1 : currentIndex
|
|
||||||
} else if (to === 'next') {
|
|
||||||
currentIndex++
|
|
||||||
currentIndex = (currentIndex >= photos.length) ? 0 : currentIndex
|
|
||||||
} else {
|
|
||||||
currentIndex = to
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dispatch current photo
|
|
||||||
dispatch('photoChange', photos[currentIndex])
|
|
||||||
// Reset fullscreen value if open
|
|
||||||
fullscreen.set()
|
|
||||||
// Reset swiped event if fired
|
|
||||||
requestAnimationFrame(() => swiped = false)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hover on controls
|
|
||||||
const hoverPhoto = event => {
|
|
||||||
const button = event.currentTarget.querySelector('button')
|
|
||||||
const photoActive = scope.querySelector('.is-active')
|
|
||||||
|
|
||||||
let photoToHover
|
|
||||||
if (event.currentTarget.dataset.to === 'prev') {
|
|
||||||
photoToHover = (photoActive.previousSibling != null) ? photoActive.previousSibling : photoActive.parentNode.lastChild
|
|
||||||
} else {
|
|
||||||
photoToHover = (photoActive.nextSibling != null) ? photoActive.nextSibling : photoActive.parentNode.firstChild
|
|
||||||
}
|
|
||||||
|
|
||||||
// Toggle class and focus of the button
|
|
||||||
if (event.type === 'mouseenter') {
|
|
||||||
photoToHover.classList.add('hover')
|
|
||||||
button.classList.add('hover')
|
|
||||||
} else if (event.type === 'mouseleave') {
|
|
||||||
photoToHover.classList.remove('hover')
|
|
||||||
button.classList.remove('hover')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Open fullscreen
|
|
||||||
const openFullscreen = event => {
|
|
||||||
if (!swiped) {
|
|
||||||
fullscreen.set(currentPhoto)
|
|
||||||
}
|
|
||||||
// Reset swiped event if fired
|
|
||||||
swiped = false
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Navigation
|
|
||||||
*/
|
|
||||||
// Drag and swipe
|
|
||||||
const swipe = directions => {
|
|
||||||
swiped = true
|
|
||||||
|
|
||||||
// Detect swipe direction
|
|
||||||
if (directions.right) {
|
|
||||||
goToPhoto('prev')
|
|
||||||
} else if (directions.left) {
|
|
||||||
goToPhoto('next')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Keyboard navigation
|
|
||||||
const keyboardNav = event => {
|
|
||||||
if ([37,80,74].includes(event.keyCode)) {
|
|
||||||
goToPhoto('prev')
|
|
||||||
} else if ([39,78,75].includes(event.keyCode)) {
|
|
||||||
goToPhoto('next')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Run code when mounted
|
|
||||||
*/
|
|
||||||
onMount(() => {
|
|
||||||
// Entering transition
|
|
||||||
animateIn(scope)
|
|
||||||
|
|
||||||
// Enable gestures
|
|
||||||
const touch = SwipeListener(scope)
|
|
||||||
|
|
||||||
// Viewer: Navigate to photo on init and URL change
|
|
||||||
if (viewer) {
|
|
||||||
page.subscribe(page => {
|
|
||||||
if (page.path.includes('/viewer/')) {
|
|
||||||
goToPhoto(photos.findIndex(photo => photo.slug === page.params.photo))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<svelte:window on:keydown={keyboardNav} />
|
|
||||||
|
|
||||||
<div class="carousel" role="region" aria-label="Photos" bind:this={scope}
|
|
||||||
on:swipe={event => swipe(event.detail.directions)}
|
|
||||||
>
|
|
||||||
<div class="wrap">
|
|
||||||
<div class="gallery">
|
|
||||||
<div class="gallery__images">
|
|
||||||
{#each photos as { id, name, location, city, image }, index}
|
|
||||||
<div class="gallery__photo"
|
|
||||||
class:is-prev={id === prevPhoto.id}
|
|
||||||
class:is-active={id === currentPhoto.id}
|
|
||||||
class:is-next={id === nextPhoto.id}
|
|
||||||
role="tabpanel"
|
|
||||||
aria-label="Photo {index + 1} of {photos.length}"
|
|
||||||
aria-hidden={index === currentIndex ? undefined : true}
|
|
||||||
>
|
|
||||||
<picture class="gallery__picture"
|
|
||||||
on:click={openFullscreen}
|
|
||||||
>
|
|
||||||
<source media="(min-width: 968px)" data-srcset={getThumbnail(image.private_hash, 1200)}>
|
|
||||||
<source media="(min-width: 800px)" data-srcset={getThumbnail(image.private_hash, 900)}>
|
|
||||||
<source media="(min-width: 500px)" data-srcset={getThumbnail(image.private_hash, 600)}>
|
|
||||||
<source media="(min-width: 300px)" data-srcset={getThumbnail(image.private_hash, 400)}>
|
|
||||||
<img src="data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs="
|
|
||||||
alt="{name}, {city ? city : location.name}, {location.country.name}"
|
|
||||||
width={defaultWidth} height={defaultHeight}
|
|
||||||
class:lazyload={
|
|
||||||
// Load the current index and the two previous/next ones
|
|
||||||
index === currentIndex || index >= currentIndex - 2 && index <= currentIndex + 2
|
|
||||||
// If last photo, load the two first ones (index = 0)
|
|
||||||
|| currentIndex === photos.length - 1 && (index === 0 || index === 1)
|
|
||||||
// If first photo, load the two last ones (index = photos length)
|
|
||||||
|| currentIndex === 0 && (index === photos.length - 1 || index === photos.length - 2)
|
|
||||||
}
|
|
||||||
>
|
|
||||||
</picture>
|
|
||||||
</div>
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="carousel__controls">
|
|
||||||
<div class="carousel__area carousel__area--prev" data-to="prev" rel="prev"
|
|
||||||
on:mouseenter={hoverPhoto} on:mouseleave={hoverPhoto}
|
|
||||||
on:click={() => goToPhoto('prev')}
|
|
||||||
>
|
|
||||||
<button class="button-control button-control--white dir-left" aria-label="Previous">
|
|
||||||
<IconArrow direction="left" color="#ff6c89" class="icon" />
|
|
||||||
<IconArrow direction="left" color="#fff" class="icon" hidden="true" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="carousel__area carousel__area--next" data-to="next" rel="next"
|
|
||||||
on:mouseenter={hoverPhoto} on:mouseleave={hoverPhoto}
|
|
||||||
on:click={() => goToPhoto('next')}
|
|
||||||
>
|
|
||||||
<button class="button-control button-control--white dir-right" aria-label="Next">
|
|
||||||
<IconArrow direction="right" color="#ff6c89" class="icon" />
|
|
||||||
<IconArrow direction="right" color="#fff" class="icon" hidden="true" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{#if viewer}
|
|
||||||
<Counter {currentIndex} className="carousel__number" />
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="carousel__infos">
|
|
||||||
<div class="carousel__locations">
|
|
||||||
{#each photos as { id, name, location, city }, index}
|
|
||||||
<div class="carousel__location style-location"
|
|
||||||
class:is-prev={id === prevPhoto.id}
|
|
||||||
class:is-active={id === currentPhoto.id}
|
|
||||||
class:is-next={id === nextPhoto.id}
|
|
||||||
>
|
|
||||||
<p class="street">{name}</p>
|
|
||||||
<p class="state style-caps style-caps--transparent">
|
|
||||||
{#if locationUrl}
|
|
||||||
<a href="/location/{location.country.slug}/{location.slug}" sapper-noscroll>
|
|
||||||
{city ? city : location.name}, {location.country.name}
|
|
||||||
</a>
|
|
||||||
{:else}
|
|
||||||
{city ? city : location.name}, {location.country.name}
|
|
||||||
{/if}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
{#if viewer}
|
|
||||||
<p class="carousel__date">{formatDate(currentPhoto.date, 'FULL')}</p>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{#if !viewer}
|
|
||||||
<PaginationDots className="carousel__dots" {photos} {currentIndex}
|
|
||||||
on:goToIndex={event => currentIndex = event.detail}
|
|
||||||
/>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{#if viewer}
|
|
||||||
<PaginationDots className="carousel__dots" {photos} {currentIndex}
|
|
||||||
on:goToIndex={event => currentIndex = event.detail}
|
|
||||||
/>
|
|
||||||
{/if}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
<script>
|
|
||||||
import { stores } from '@sapper/app'
|
|
||||||
import { site, currentLocation } from 'utils/store'
|
|
||||||
// Components
|
|
||||||
import LinkTranslate from 'atoms/LinkTranslate'
|
|
||||||
import Switcher from 'molecules/Switcher'
|
|
||||||
|
|
||||||
// Variables
|
|
||||||
const { page } = stores()
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<footer class="footer">
|
|
||||||
<div class="wrap">
|
|
||||||
<div class="footer__left">
|
|
||||||
<Switcher radius="30" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<nav class="footer__right" >
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
<LinkTranslate href="/subscribe" text="Keep Updated" active={$page.path.includes('subscribe')} rel="prefetch" noScroll />
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<LinkTranslate href="/credits" text="Credits" active={$page.path.includes('credits')} rel="prefetch" noScroll />
|
|
||||||
</li>
|
|
||||||
{#if $site}
|
|
||||||
<li class="instagram">
|
|
||||||
<LinkTranslate href="https://instagram.com/{$site.instagram}" text="Instagram" target="_blank" rel="noopener">
|
|
||||||
<svg width="20" height="20" xmlns="http://www.w3.org/2000/svg" fill="#fff">
|
|
||||||
<path d="M11.245 0c1.615.005 2.002.02 2.878.06 1.064.048 1.791.217 2.427.464a4.902 4.902 0 0 1 1.772 1.154 4.902 4.902 0 0 1 1.153 1.771c.247.636.416 1.363.465 2.428.042.914.056 1.295.06 3.095v2.055c-.004 1.8-.018 2.182-.06 3.096-.049 1.064-.218 1.791-.465 2.427a4.902 4.902 0 0 1-1.153 1.772 4.902 4.902 0 0 1-1.772 1.153c-.636.247-1.363.416-2.427.465-1.067.049-1.407.06-4.123.06s-3.057-.011-4.124-.06c-1.064-.049-1.79-.218-2.427-.465a4.902 4.902 0 0 1-1.771-1.153A4.902 4.902 0 0 1 .524 16.55c-.247-.636-.416-1.363-.465-2.427C.02 13.247.005 12.86 0 11.245v-2.49c.005-1.616.02-2.002.06-2.878.048-1.065.217-1.792.464-2.428a4.902 4.902 0 0 1 1.154-1.771A4.902 4.902 0 0 1 3.448.524C4.086.277 4.813.108 5.877.06 6.753.02 7.14.005 8.754 0zm-.204 1.802H8.958c-1.739.003-2.101.016-3 .057-.974.045-1.504.208-1.856.345-.467.181-.8.398-1.15.748-.35.35-.567.683-.748 1.15-.137.352-.3.882-.345 1.857-.04.898-.054 1.26-.057 2.999v2.083c.003 1.739.016 2.101.057 3 .045.975.208 1.504.345 1.857.181.466.398.8.748 1.15.35.35.683.566 1.15.747.352.137.882.3 1.857.345 1.054.048 1.37.058 4.04.058h.288c2.407 0 2.738-.012 3.754-.058.975-.045 1.504-.208 1.857-.345.466-.18.8-.398 1.15-.748.35-.35.566-.683.747-1.15.137-.352.3-.881.345-1.856.048-1.055.058-1.371.058-4.041v-.288c0-2.407-.012-2.738-.058-3.753-.045-.975-.208-1.505-.345-1.857a3.098 3.098 0 0 0-.748-1.15 3.099 3.099 0 0 0-1.15-.748c-.352-.137-.881-.3-1.856-.345-.899-.04-1.261-.054-3-.057zM10 4.864a5.135 5.135 0 1 1 0 10.271 5.135 5.135 0 0 1 0-10.27zm0 1.802a3.334 3.334 0 1 0 0 6.667 3.334 3.334 0 0 0 0-6.667zm5.338-3.205a1.2 1.2 0 1 1 0 2.4 1.2 1.2 0 0 1 0-2.4z" fill-rule="evenodd"/>
|
|
||||||
</svg>
|
|
||||||
</LinkTranslate>
|
|
||||||
</li>
|
|
||||||
{/if}
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li class="by">
|
|
||||||
<a href="https://cetrucflotte.com" title="A project by Cetrucflotte" target="_blank" rel="noopener">
|
|
||||||
<img src="/img/logo-ctf.svg" alt="Logo of Cetrucflotte">
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
||||||
</div>
|
|
||||||
</footer>
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
<script>
|
|
||||||
import { fullscreen } from 'utils/store'
|
|
||||||
import { throttle, getThumbnail } from 'utils/functions'
|
|
||||||
// Dependencies
|
|
||||||
import imagesLoaded from 'imagesloaded'
|
|
||||||
// Components
|
|
||||||
import IconGlobe from 'atoms/IconGlobe'
|
|
||||||
import IconZoomOut from 'atoms/IconZoomOut'
|
|
||||||
|
|
||||||
// Variables
|
|
||||||
let scope
|
|
||||||
let loading = false
|
|
||||||
let open = false
|
|
||||||
let closed = false
|
|
||||||
|
|
||||||
// Wait for fullscreen store value
|
|
||||||
$: if ($fullscreen) openFullscreen($fullscreen)
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Functions
|
|
||||||
*/
|
|
||||||
// Open fullscreen
|
|
||||||
const openFullscreen = throttle(currentPhoto => {
|
|
||||||
const { name, image, location } = currentPhoto
|
|
||||||
loading = true
|
|
||||||
|
|
||||||
if (!open) {
|
|
||||||
const img = document.createElement('img')
|
|
||||||
const imgContainer = scope.querySelector('.fullscreen__image')
|
|
||||||
img.src = getThumbnail(image.private_hash, null, 1600, 'crop', 80)
|
|
||||||
img.alt = `${name}, ${location.name}, ${location.country.name}`
|
|
||||||
img.width = 2400
|
|
||||||
img.height = 1600
|
|
||||||
imgContainer.append(img)
|
|
||||||
|
|
||||||
// Show fullscreen when new image is loaded
|
|
||||||
imagesLoaded(scope, instance => {
|
|
||||||
open = true
|
|
||||||
loading = false
|
|
||||||
closed = false
|
|
||||||
|
|
||||||
// Scroll to photo's center
|
|
||||||
imgContainer.scrollTo((img.clientWidth - scope.clientWidth) / 2, 0)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}, 800)
|
|
||||||
|
|
||||||
// Close fullscreen
|
|
||||||
const closeFullscreen = throttle(() => {
|
|
||||||
// Reset values
|
|
||||||
open = false
|
|
||||||
closed = true
|
|
||||||
|
|
||||||
// Clear image and reset fullscreen store value
|
|
||||||
if (scope) {
|
|
||||||
setTimeout(() => {
|
|
||||||
scope.querySelector('.fullscreen__image').innerHTML = ''
|
|
||||||
fullscreen.set()
|
|
||||||
}, 800) // Transition duration
|
|
||||||
}
|
|
||||||
}, 800)
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div class="fullscreen" bind:this={scope}>
|
|
||||||
<div class="fullscreen__image" class:is-open={open} on:click={closeFullscreen} />
|
|
||||||
|
|
||||||
<div class="fullscreen__loading" class:is-hidden={!loading}>
|
|
||||||
<IconGlobe width="24" color="#fff" animated="true" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="fullscreen__close" class:is-visible={open}>
|
|
||||||
<button class="button-control button-control--gray button-control--shadow dir-top" aria-label="Close"
|
|
||||||
on:click={closeFullscreen}
|
|
||||||
>
|
|
||||||
<IconZoomOut color="#fff" width="22" class="icon" />
|
|
||||||
<IconZoomOut color="#fff" width="22" class="icon" hidden="true" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
<script>
|
|
||||||
import { onMount } from 'svelte'
|
|
||||||
import { flip } from 'svelte/animate'
|
|
||||||
import { receive, send } from 'animations/crossfade'
|
|
||||||
import { locations, continents } from 'utils/store'
|
|
||||||
import { throttle } from 'utils/functions'
|
|
||||||
// Components
|
|
||||||
import Button from 'atoms/Button'
|
|
||||||
import Location from 'molecules/Location'
|
|
||||||
import Newsletter from 'organisms/Newsletter'
|
|
||||||
// Animations
|
|
||||||
import { animateIn } from 'animations/Locations'
|
|
||||||
|
|
||||||
// Variables
|
|
||||||
const transitionDuration = 800
|
|
||||||
let list
|
|
||||||
let continentsToDisplay = []
|
|
||||||
let continentsFiltered = []
|
|
||||||
$: filteredLocations = $locations.filter(location => continentsFiltered.includes(location.country.continent))
|
|
||||||
|
|
||||||
// Define continents to show
|
|
||||||
$continents.forEach(cont => !!cont.countries && continentsToDisplay.push(cont))
|
|
||||||
continentsFiltered = [...continentsToDisplay]
|
|
||||||
|
|
||||||
// Filter by continent
|
|
||||||
// Detects if click difference if too short with a throttled function
|
|
||||||
const toggleContinents = throttle((event, continent) => {
|
|
||||||
continentsFiltered = (!continent) ? [...continentsToDisplay] : [continent]
|
|
||||||
}, transitionDuration)
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Run code when mounted
|
|
||||||
*/
|
|
||||||
onMount(() => {
|
|
||||||
// Entering transition
|
|
||||||
animateIn(list)
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div class="browse wrap">
|
|
||||||
<div class="browse__description style-description">
|
|
||||||
<p>Browse all the cities and countries</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<ul class="browse__continents" id="continents">
|
|
||||||
{#if continentsToDisplay.length > 1}
|
|
||||||
<li on:click={e => toggleContinents(e)}>
|
|
||||||
<Button type="button" text="All" class="button-outline {(continentsFiltered.length <= 1) ? 'disabled' : ''}" />
|
|
||||||
</li>
|
|
||||||
{/if}
|
|
||||||
{#each continentsToDisplay as continent}
|
|
||||||
<li on:click={e => toggleContinents(e, continent)}>
|
|
||||||
<Button type="button" text={continent.name} class="button-outline {(!continentsFiltered.includes(continent)) ? 'disabled' : ''}" />
|
|
||||||
</li>
|
|
||||||
{/each}
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<div class="browse__locations" id="locations_list" role="list" bind:this={list}>
|
|
||||||
{#each filteredLocations as location (location.id)}
|
|
||||||
<div
|
|
||||||
animate:flip="{{ duration: transitionDuration }}"
|
|
||||||
in:receive="{{ key: location.id }}"
|
|
||||||
out:send="{{ key: location.id }}"
|
|
||||||
>
|
|
||||||
<Location {location} />
|
|
||||||
</div>
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Newsletter />
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
<script>
|
|
||||||
import { site } from 'utils/store'
|
|
||||||
// Components
|
|
||||||
import NewsletterForm from 'molecules/NewsletterForm'
|
|
||||||
|
|
||||||
// Props
|
|
||||||
export let brightness = undefined
|
|
||||||
export let title = 'Keep Updated'
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div class="newsletter" class:newsletter--light={brightness === 'light'}>
|
|
||||||
<div class="wrapper">
|
|
||||||
<div class="newsletter__text style-description style-description--small" class:style-description--dark={brightness === 'light'}>
|
|
||||||
<h2 class="style-location">
|
|
||||||
<label for="SUB_EMAIL">{title}</label>
|
|
||||||
</h2>
|
|
||||||
<p>{$site.newsletter_text}</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<NewsletterForm align="right" {brightness} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
<script>
|
|
||||||
import { onMount, createEventDispatcher } from 'svelte'
|
|
||||||
import { site, currentLocation } from 'utils/store'
|
|
||||||
// Components
|
|
||||||
import Newsletter from 'organisms/Newsletter'
|
|
||||||
// Props
|
|
||||||
export let photos
|
|
||||||
export let paginatedPhotos
|
|
||||||
export let photosPerPage
|
|
||||||
|
|
||||||
// Variables
|
|
||||||
const dispatch = createEventDispatcher()
|
|
||||||
let currentIndex = photosPerPage
|
|
||||||
const pagesTotal = Math.ceil(photos.length / photosPerPage)
|
|
||||||
const pagesArray = Array.from({ length: pagesTotal }, (v, k) => k + 1).reverse()
|
|
||||||
let pageTranslate = 100 - (100 / pagesTotal)
|
|
||||||
|
|
||||||
// Add more photos to the loop
|
|
||||||
const displayMorePhotos = () => {
|
|
||||||
if (currentIndex < photos.length) {
|
|
||||||
// Display the X next hidden photos
|
|
||||||
const photosToAppend = photos.filter(photo => photo.hidden === true).splice(0, photosPerPage)
|
|
||||||
photosToAppend.forEach(photo => photo.hidden = false)
|
|
||||||
|
|
||||||
// Merge new photos to show to the existing ones
|
|
||||||
dispatch('updatePagination', [...paginatedPhotos, ...photosToAppend])
|
|
||||||
|
|
||||||
// Increment current index
|
|
||||||
currentIndex = currentIndex + photosPerPage
|
|
||||||
|
|
||||||
// Animate the pagination
|
|
||||||
pageTranslate = pageTranslate - (100 / pagesTotal)
|
|
||||||
} else {
|
|
||||||
currentIndex = photos.length
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<section class="pagination">
|
|
||||||
{#if photos.length && currentIndex < photos.length}
|
|
||||||
<div class="pagination__page" class:disabled={currentIndex === photos.length}
|
|
||||||
on:click={displayMorePhotos}
|
|
||||||
on:mouseenter={() => pageTranslate = pageTranslate - (100 / pagesTotal) * 0.666}
|
|
||||||
on:mouseleave={() => pageTranslate = pageTranslate + (100 / pagesTotal) * 0.666}
|
|
||||||
rel="next"
|
|
||||||
>
|
|
||||||
<div class="pagination__info">page</div>
|
|
||||||
<div class="pagination__numbers">
|
|
||||||
<div class="scroll" style="transform: translateY(-{pageTranslate}%) translateZ(0);">
|
|
||||||
{#each pagesArray as page}
|
|
||||||
<span>{page}</span>
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
/{pagesTotal}
|
|
||||||
</div>
|
|
||||||
<p class="pagination__caption style-caps">See more photos</p>
|
|
||||||
|
|
||||||
{:else if $currentLocation}
|
|
||||||
<div class="pagination__message">
|
|
||||||
<Newsletter
|
|
||||||
title="That's all folks!"
|
|
||||||
brightness="light"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
</section>
|
|
||||||
57
src/routes/__layout.svelte
Normal file
57
src/routes/__layout.svelte
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { setContext } from 'svelte'
|
||||||
|
// Other
|
||||||
|
import '$utils/polyfills'
|
||||||
|
import '../style/style.scss'
|
||||||
|
|
||||||
|
export let data: any
|
||||||
|
|
||||||
|
// Set global data
|
||||||
|
setContext('global', data)
|
||||||
|
|
||||||
|
// console.log(data)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<slot />
|
||||||
|
|
||||||
|
<script context="module" lang="ts">
|
||||||
|
import { fetchAPI } from '$utils/api'
|
||||||
|
|
||||||
|
export async function load ({ page, session, fetch, context }) {
|
||||||
|
const res = await fetchAPI(`
|
||||||
|
query {
|
||||||
|
location {
|
||||||
|
name
|
||||||
|
slug
|
||||||
|
country {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
country {
|
||||||
|
name
|
||||||
|
slug
|
||||||
|
}
|
||||||
|
|
||||||
|
continent {
|
||||||
|
name
|
||||||
|
slug
|
||||||
|
}
|
||||||
|
|
||||||
|
settings {
|
||||||
|
seo_name
|
||||||
|
seo_title
|
||||||
|
seo_description
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
|
||||||
|
const { data } = res
|
||||||
|
|
||||||
|
return {
|
||||||
|
props: {
|
||||||
|
data,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
<script>
|
|
||||||
import { onMount } from 'svelte'
|
|
||||||
import { site, pageReady } from 'utils/store'
|
|
||||||
// Components
|
|
||||||
import IconArrow from 'atoms/IconArrow'
|
|
||||||
import TitleSite from 'atoms/TitleSite'
|
|
||||||
import Button from 'atoms/Button'
|
|
||||||
import Footer from 'organisms/Footer'
|
|
||||||
|
|
||||||
// Props
|
|
||||||
export let status
|
|
||||||
export let error
|
|
||||||
|
|
||||||
onMount(() => {
|
|
||||||
pageReady.set(true)
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<svelte:head>
|
|
||||||
<title>Houses Of - {error.message}</title>
|
|
||||||
</svelte:head>
|
|
||||||
|
|
||||||
{#if process.env.NODE_ENV === 'development' && error.stack}
|
|
||||||
<div class="wrap">
|
|
||||||
<pre>{error.stack}</pre>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
<main class="housesof" class:is-transitioning={!$pageReady}>
|
|
||||||
<section class="page">
|
|
||||||
<div class="wrap">
|
|
||||||
<div class="page__top">
|
|
||||||
<a href="/" class="button-control button-control--lightpink dir-left" on:click|preventDefault={() => window.location = '/'}>
|
|
||||||
<IconArrow direction="left" color="#fff" class="icon" />
|
|
||||||
<IconArrow direction="left" color="#fff" class="icon" hidden="true" />
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<TitleSite />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="page__description style-description">
|
|
||||||
<p>Oh no… Looks like something wrong just happened. Like a nasty error {status}.</p>
|
|
||||||
<Button href="/" class="button" text="Go back to homepage" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Footer />
|
|
||||||
</section>
|
|
||||||
</main>
|
|
||||||
@@ -1,126 +0,0 @@
|
|||||||
<script context="module">
|
|
||||||
import mainQuery from 'utils/mainQuery'
|
|
||||||
|
|
||||||
export async function preload (page, session) {
|
|
||||||
await this.fetch(apiEndpoints.gql, {
|
|
||||||
method: 'post',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'Authorization': 'bearer ' + process.env.CONFIG.API_TOKEN
|
|
||||||
},
|
|
||||||
body: JSON.stringify({ query: mainQuery })
|
|
||||||
})
|
|
||||||
.then(res => res.json())
|
|
||||||
.then(res => {
|
|
||||||
const { data } = res
|
|
||||||
|
|
||||||
// Manipulate countries data
|
|
||||||
data.countries.data.forEach(country => {
|
|
||||||
const matchingContinent = data.continents.data.find(continent => continent.id === country.continent.id)
|
|
||||||
// Replace continent with request data
|
|
||||||
country.continent = matchingContinent
|
|
||||||
// Add countries to each continents
|
|
||||||
matchingContinent.countries = []
|
|
||||||
matchingContinent.countries.push(country)
|
|
||||||
})
|
|
||||||
|
|
||||||
// Replace each location's country with request data
|
|
||||||
data.locations.data.forEach(location => {
|
|
||||||
location.country = data.countries.data.find(country => country.id === location.country.id)
|
|
||||||
})
|
|
||||||
|
|
||||||
// Filter and keep only the latest photo for each location
|
|
||||||
// https://stackoverflow.com/questions/61636965/
|
|
||||||
const latestPhotos = Object.values(data.photos.data.reduce((photos, photo) => {
|
|
||||||
if (photos.hasOwnProperty(photo.location.id)) {
|
|
||||||
if (new Date(photos[photo.location.id].created_on) < new Date(photo.created_on)) {
|
|
||||||
photos[photo.location.id] = photo
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
photos[photo.location.id] = photo
|
|
||||||
}
|
|
||||||
return photos
|
|
||||||
}, {}))
|
|
||||||
|
|
||||||
// Add last updated date to each location
|
|
||||||
data.locations.data.forEach(location => {
|
|
||||||
const latestPhoto = latestPhotos.find(photo => photo.location.id === location.id)
|
|
||||||
if (latestPhoto) {
|
|
||||||
location.last_updated = latestPhoto.created_on
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// Set data into store
|
|
||||||
site.set(data.site.data[0])
|
|
||||||
continents.set(data.continents.data)
|
|
||||||
countries.set(data.countries.data)
|
|
||||||
locations.set(data.locations.data)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { onMount } from 'svelte'
|
|
||||||
import { stores } from '@sapper/app'
|
|
||||||
import {
|
|
||||||
apiEndpoints,
|
|
||||||
site,
|
|
||||||
continents,
|
|
||||||
countries,
|
|
||||||
locations,
|
|
||||||
pageReady
|
|
||||||
} from 'utils/store'
|
|
||||||
// Dependencies
|
|
||||||
import lazySizes from 'lazysizes'
|
|
||||||
// Components
|
|
||||||
import AnalyticsTracker from 'utils/AnalyticsTracker'
|
|
||||||
import Transition from 'utils/Transition'
|
|
||||||
|
|
||||||
// Variables
|
|
||||||
const { page } = stores()
|
|
||||||
|
|
||||||
// Settings
|
|
||||||
lazySizes.cfg.lazyClass = 'lazyload'
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Head stuff
|
|
||||||
*/
|
|
||||||
// Preconnect
|
|
||||||
const preconnect = [
|
|
||||||
'https://api.housesof.world',
|
|
||||||
'https://www.googletagmanager.com',
|
|
||||||
'https://stats.g.doubleclick.net',
|
|
||||||
'https://www.google-analytics.com',
|
|
||||||
]
|
|
||||||
// Preload assets
|
|
||||||
const preload = {
|
|
||||||
fonts: [
|
|
||||||
'/fonts/G-Light.woff2',
|
|
||||||
'/fonts/G-Regular.woff2',
|
|
||||||
'/fonts/G-Semibold.woff2',
|
|
||||||
'/fonts/M-Extralight.woff2',
|
|
||||||
'/fonts/M-Light.woff2',
|
|
||||||
]
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" global>
|
|
||||||
@import "../style/style.scss";
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<svelte:head>
|
|
||||||
<link rel="canonical" href="{process.env.CONFIG.PROD_URL}{$page.path}">
|
|
||||||
{#each preconnect as host}
|
|
||||||
<link rel="preconnect" href={host} crossorigin>
|
|
||||||
<link rel="dns-prefetch" href={host}>
|
|
||||||
{/each}
|
|
||||||
{#each preload.fonts as font}
|
|
||||||
<link rel="preload" href={font} as="font" type="font/woff2" crossorigin>
|
|
||||||
{/each}
|
|
||||||
</svelte:head>
|
|
||||||
|
|
||||||
<slot />
|
|
||||||
|
|
||||||
<Transition />
|
|
||||||
|
|
||||||
<AnalyticsTracker {stores} id={process.env.CONFIG.GA_TRACKER_ID} />
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
<script>
|
|
||||||
import { onMount } from 'svelte'
|
|
||||||
import { stores } from '@sapper/app'
|
|
||||||
import {
|
|
||||||
site,
|
|
||||||
currentLocation,
|
|
||||||
currentPhotos,
|
|
||||||
pageReady,
|
|
||||||
pageAnimation
|
|
||||||
} from 'utils/store'
|
|
||||||
// Dependencies
|
|
||||||
import Lazy from 'svelte-lazy'
|
|
||||||
// Components
|
|
||||||
import IconArrow from 'atoms/IconArrow'
|
|
||||||
import TitleSite from 'atoms/TitleSite'
|
|
||||||
import InteractiveGlobe from 'molecules/InteractiveGlobe'
|
|
||||||
import Locations from 'organisms/Locations'
|
|
||||||
import Footer from 'organisms/Footer'
|
|
||||||
import Transition from 'utils/Transition'
|
|
||||||
import SocialMetas from 'utils/SocialMetas'
|
|
||||||
// Animations
|
|
||||||
import { animateIn } from 'animations/page'
|
|
||||||
|
|
||||||
// Variables
|
|
||||||
const { page } = stores()
|
|
||||||
pageAnimation.set(animateIn)
|
|
||||||
const pageTitle = `${$site.seo_name} - ${$site.seo_title_default} across the globe`
|
|
||||||
|
|
||||||
// Reset current location
|
|
||||||
currentLocation.set()
|
|
||||||
currentPhotos.set()
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Run code when mounted
|
|
||||||
*/
|
|
||||||
onMount(() => {
|
|
||||||
// Page is loaded
|
|
||||||
pageReady.set(true)
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<svelte:head>
|
|
||||||
<title>{pageTitle}</title>
|
|
||||||
<meta name="description" content={$site.seo_description_default}>
|
|
||||||
<SocialMetas
|
|
||||||
url="{process.env.CONFIG.PROD_URL}{$page.path}"
|
|
||||||
title="{pageTitle}"
|
|
||||||
description={$site.seo_description_default}
|
|
||||||
image={$site.seo_share_image.full_url}
|
|
||||||
/>
|
|
||||||
</svelte:head>
|
|
||||||
|
|
||||||
<main class="housesof" class:is-transitioning={!$pageReady}>
|
|
||||||
<section class="page explore">
|
|
||||||
<div class="wrap">
|
|
||||||
<div class="page__top">
|
|
||||||
<a href="/" class="button-control button-control--lightpink dir-left" aria-label="Back to homepage" rel="prefetch">
|
|
||||||
<IconArrow direction="left" color="#fff" class="icon" />
|
|
||||||
<IconArrow direction="left" color="#fff" class="icon" hidden="true" />
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<TitleSite />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="explore__description page__description page__part style-description">
|
|
||||||
<p>{$site.explore_globe}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{#if process.browser}
|
|
||||||
<Lazy offset={window.innerHeight} fadeOption={null}>
|
|
||||||
<InteractiveGlobe />
|
|
||||||
</Lazy>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
<Locations />
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<Footer />
|
|
||||||
</main>
|
|
||||||
@@ -1,90 +0,0 @@
|
|||||||
<script>
|
|
||||||
import { onMount } from 'svelte'
|
|
||||||
import { stores } from '@sapper/app'
|
|
||||||
import { site, pageReady, pageAnimation } from 'utils/store'
|
|
||||||
// Dependencies
|
|
||||||
import Lazy from 'svelte-lazy'
|
|
||||||
// Components
|
|
||||||
import IconArrow from 'atoms/IconArrow'
|
|
||||||
import TitleSite from 'atoms/TitleSite'
|
|
||||||
import LinkTranslate from 'atoms/LinkTranslate'
|
|
||||||
import InteractiveGlobe from 'molecules/InteractiveGlobe'
|
|
||||||
import Footer from 'organisms/Footer'
|
|
||||||
import SocialMetas from 'utils/SocialMetas'
|
|
||||||
// Animations
|
|
||||||
import { animateIn } from 'animations/page'
|
|
||||||
|
|
||||||
// Variables
|
|
||||||
const { page } = stores()
|
|
||||||
pageAnimation.set(animateIn)
|
|
||||||
const pageTitle = `${$site.seo_name} - Credits`
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Run code when mounted
|
|
||||||
*/
|
|
||||||
onMount(() => {
|
|
||||||
// Page is loaded
|
|
||||||
pageReady.set(true)
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<svelte:head>
|
|
||||||
<title>{pageTitle}</title>
|
|
||||||
<meta name="description" content={$site.credits_text}>
|
|
||||||
<SocialMetas
|
|
||||||
url="{process.env.CONFIG.PROD_URL}{$page.path}"
|
|
||||||
title="{pageTitle}"
|
|
||||||
description={$site.credits_text}
|
|
||||||
image={$site.seo_share_image.full_url}
|
|
||||||
/>
|
|
||||||
</svelte:head>
|
|
||||||
|
|
||||||
<main class="housesof page--credits" class:is-transitioning={!$pageReady}>
|
|
||||||
<section class="page">
|
|
||||||
<div class="wrap">
|
|
||||||
<div class="page__top">
|
|
||||||
<a href="/" class="button-control button-control--lightpink dir-left">
|
|
||||||
<IconArrow direction="left" color="#fff" class="icon" />
|
|
||||||
<IconArrow direction="left" color="#fff" class="icon" hidden="true" />
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<TitleSite />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="page__description page__part style-description">
|
|
||||||
<p>{$site.credits_text}</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{#if $site.credits_list}
|
|
||||||
<div class="page__list page__part">
|
|
||||||
{#each $site.credits_list as { title, credits }}
|
|
||||||
<div class="page__category">
|
|
||||||
<h2 class="title-category">{title}</h2>
|
|
||||||
{#each credits as { name, role, website }, i}
|
|
||||||
<dl>
|
|
||||||
<dt class="style-location">
|
|
||||||
{#if website}
|
|
||||||
<LinkTranslate href={website} text={name} target="_blank" rel="noopener" />
|
|
||||||
{:else}
|
|
||||||
{name}
|
|
||||||
{/if}
|
|
||||||
</dt>
|
|
||||||
<dd class="style-caps style-caps style-caps--transparent">{role}</dd>
|
|
||||||
</dl>
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{#if process.browser}
|
|
||||||
<Lazy offset={window.innerHeight} fadeOption={null}>
|
|
||||||
<InteractiveGlobe type="part" opacity="0.5" />
|
|
||||||
</Lazy>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
<Footer />
|
|
||||||
</section>
|
|
||||||
</main>
|
|
||||||
@@ -1,137 +1,21 @@
|
|||||||
<script context="module">
|
<script lang="ts">
|
||||||
// Variables
|
import { getContext } from 'svelte'
|
||||||
let limit = process.env.CONFIG.HOME_PHOTOS_LIMIT
|
|
||||||
|
|
||||||
// Preload data (photos to display)
|
|
||||||
export async function preload (page, session) {
|
|
||||||
// Load Carousel photos
|
|
||||||
const fields = [
|
|
||||||
'id', 'name', 'image.private_hash',
|
|
||||||
'location.id', 'location.name', 'location.slug',
|
|
||||||
'location.country.name', 'location.country.slug'
|
|
||||||
]
|
|
||||||
const sort = '?' // Random sort
|
|
||||||
const req = await this.fetch(`${apiEndpoints.rest}/items/photos?fields=${fields.join()}&status=published&sort=${sort}&limit=${limit}`, {
|
|
||||||
'Authorization': 'bearer ' + process.env.CONFIG.API_TOKEN
|
|
||||||
})
|
|
||||||
const photos = await req.json()
|
|
||||||
if (req.ok) {
|
|
||||||
return { photos: photos.data }
|
|
||||||
}
|
|
||||||
this.error(404, 'Not found')
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { onMount } from 'svelte'
|
|
||||||
import { stores } from '@sapper/app'
|
|
||||||
import {
|
|
||||||
apiEndpoints,
|
|
||||||
site,
|
|
||||||
currentLocation,
|
|
||||||
currentPhotos,
|
|
||||||
pageReady,
|
|
||||||
pageAnimation
|
|
||||||
} from 'utils/store'
|
|
||||||
import { charsToSpan, smoothScroll } from 'utils/functions'
|
|
||||||
// Dependencies
|
|
||||||
import Lazy from 'svelte-lazy'
|
|
||||||
// Components
|
// Components
|
||||||
import Button from 'atoms/Button'
|
import Metas from '$components/Metas.svelte'
|
||||||
import IconGlobeSmall from 'atoms/IconGlobeSmall'
|
import Locations from '$components/organisms/Locations.svelte'
|
||||||
import InteractiveGlobe from 'molecules/InteractiveGlobe'
|
|
||||||
import Carousel from 'organisms/Carousel'
|
|
||||||
import Fullscreen from 'organisms/Fullscreen'
|
|
||||||
import Locations from 'organisms/Locations'
|
|
||||||
import Footer from 'organisms/Footer'
|
|
||||||
import SocialMetas from 'utils/SocialMetas'
|
|
||||||
// Animations
|
|
||||||
import { animateIn } from 'animations/index'
|
|
||||||
pageAnimation.set(animateIn)
|
|
||||||
|
|
||||||
// Props and Variables
|
const globalData: any = getContext('global')
|
||||||
export let photos = ''
|
console.log(globalData)
|
||||||
const { page } = stores()
|
|
||||||
let winWidth = 0
|
|
||||||
|
|
||||||
// Reset current location if existing
|
|
||||||
currentLocation.set()
|
|
||||||
currentPhotos.set()
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Run code when mounted
|
|
||||||
*/
|
|
||||||
onMount(() => {
|
|
||||||
// Page is loaded
|
|
||||||
pageReady.set(true)
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:head>
|
<Metas
|
||||||
<title>{$site.seo_name} - {$site.seo_title_default} across the globe</title>
|
title="Houses Of"
|
||||||
<meta name="description" content={$site.seo_description_default}>
|
description=""
|
||||||
<SocialMetas
|
image=""
|
||||||
url="{process.env.CONFIG.PROD_URL}"
|
|
||||||
title="{$site.seo_name} - {$site.seo_title_default} across the globe"
|
|
||||||
description={$site.seo_description_default}
|
|
||||||
image={$site.seo_share_image.full_url}
|
|
||||||
/>
|
/>
|
||||||
</svelte:head>
|
|
||||||
|
|
||||||
<svelte:window bind:innerWidth={winWidth} />
|
<h1>Houses Of</h1>
|
||||||
|
|
||||||
<main class="housesof" class:is-transitioning={!$pageReady}>
|
<Locations
|
||||||
<section class="intro">
|
locations={globalData.location}
|
||||||
<div class="anim-mask">
|
/>
|
||||||
<div class="anim title-parallax" id="title-houses">
|
|
||||||
<h1 class="title-massive" aria-label="Houses">
|
|
||||||
{@html charsToSpan('Houses')}
|
|
||||||
</h1>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="wrap" id="intro-description">
|
|
||||||
<div class="intro__description style-description">
|
|
||||||
<p>{$site.description}</p>
|
|
||||||
|
|
||||||
<Button type="a" href="#choose" class="button" text="Explore locations" on:click={smoothScroll}>
|
|
||||||
<IconGlobeSmall width="22" color="#666" />
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="intro-carousel">
|
|
||||||
<Carousel {photos} locationUrl={true} />
|
|
||||||
<Fullscreen />
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="explore explore--homepage">
|
|
||||||
<div class="of" id="title-of" role="heading" aria-level="2" aria-label="of">
|
|
||||||
<div class="anim-mask">
|
|
||||||
{@html charsToSpan('of')}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="explore__description style-description" id="choose">
|
|
||||||
<p>{$site.explore_globe}</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{#if process.browser}
|
|
||||||
<Lazy offset={window.innerHeight} fadeOption={null}>
|
|
||||||
<InteractiveGlobe />
|
|
||||||
</Lazy>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
<div class="anim-mask anim-title">
|
|
||||||
<h1 class="title-massive title-parallax" id="title-world" aria-label="World">
|
|
||||||
{@html charsToSpan('World')}
|
|
||||||
</h1>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Locations />
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<Footer />
|
|
||||||
</main>
|
|
||||||
@@ -1,209 +0,0 @@
|
|||||||
<script context="module">
|
|
||||||
import { apiEndpoints } from 'utils/store'
|
|
||||||
|
|
||||||
// Preload data
|
|
||||||
export async function preload (page, session) {
|
|
||||||
// Load photos
|
|
||||||
const fields = [
|
|
||||||
'id', 'name', 'slug', 'date', 'image.private_hash',
|
|
||||||
'location.id', 'location.name', 'location.slug', 'location.region',
|
|
||||||
'location.country.name', 'location.country.slug', 'city',
|
|
||||||
'created_on', 'modified_on'
|
|
||||||
].join(',')
|
|
||||||
const sort = ['-created_on', 'name'].join(',')
|
|
||||||
const limit = -1
|
|
||||||
const req = await this.fetch(`${apiEndpoints.rest}/items/photos?fields=${fields}&status=published&filter[location.slug][rlike]=%${page.params.place}%&limit=${limit}&sort=${sort}`, {
|
|
||||||
'Authorization': 'bearer ' + process.env.CONFIG.API_TOKEN
|
|
||||||
})
|
|
||||||
const photos = await req.json()
|
|
||||||
if (req.ok) {
|
|
||||||
return { photos: photos.data }
|
|
||||||
}
|
|
||||||
this.error(404, 'Not found')
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { onMount } from 'svelte'
|
|
||||||
import { stores } from '@sapper/app'
|
|
||||||
import {
|
|
||||||
site,
|
|
||||||
locations,
|
|
||||||
currentLocation,
|
|
||||||
currentPhotos,
|
|
||||||
pageReady,
|
|
||||||
pageAnimation
|
|
||||||
} from 'utils/store'
|
|
||||||
import { formatDate, relativeTime, getThumbnail } from 'utils/functions'
|
|
||||||
// Components
|
|
||||||
import IconGlobe from 'atoms/IconGlobe'
|
|
||||||
import IconGlobeSmall from 'atoms/IconGlobeSmall'
|
|
||||||
import LinkChange from 'atoms/LinkChange'
|
|
||||||
import ToggleLayout from 'atoms/ToggleLayout'
|
|
||||||
import Photo from 'molecules/Photo'
|
|
||||||
import Switcher from 'molecules/Switcher'
|
|
||||||
import Pagination from 'organisms/Pagination'
|
|
||||||
import Footer from 'organisms/Footer'
|
|
||||||
import SocialMetas from 'utils/SocialMetas'
|
|
||||||
// Animations
|
|
||||||
import { animateIn } from 'animations/place'
|
|
||||||
|
|
||||||
// Props and variables
|
|
||||||
export let photos
|
|
||||||
const { page } = stores()
|
|
||||||
pageAnimation.set(animateIn)
|
|
||||||
let layoutSetting
|
|
||||||
let windowWidth
|
|
||||||
$: latestPhoto = photos[0]
|
|
||||||
|
|
||||||
// Update current location
|
|
||||||
const location = $locations.find(loc => loc.slug === $page.params.place)
|
|
||||||
const { description, country, illu_desktop, illu_desktop_2x, illu_mobile } = location
|
|
||||||
currentLocation.set(location)
|
|
||||||
currentPhotos.set(photos)
|
|
||||||
|
|
||||||
// Define dates
|
|
||||||
$: latestPhotoModified = latestPhoto ? latestPhoto.modified_on.replace(' ', 'T') : ''
|
|
||||||
$: dateUpdatedFull = latestPhoto ? formatDate(latestPhotoModified, 'FULL') : ''
|
|
||||||
$: dateUpdatedDatetime = latestPhoto ? formatDate(latestPhotoModified, 'DATETIME') : ''
|
|
||||||
$: dateUpdatedRelative = latestPhoto ? relativeTime(latestPhotoModified, 2592000000) : ''
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Pagination
|
|
||||||
*/
|
|
||||||
let photosPerPage = $site.photos_per_page
|
|
||||||
|
|
||||||
// Hide photos by default
|
|
||||||
photos.forEach((photo, index) => photo.hidden = (index + 1 > photosPerPage) ? true : false)
|
|
||||||
let paginatedPhotos = photos.filter(photo => photo.hidden === false)
|
|
||||||
|
|
||||||
// Update pagination event from Pagination component
|
|
||||||
const updatePagination = event => paginatedPhotos = event.detail
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Run code when mounted
|
|
||||||
*/
|
|
||||||
onMount(() => {
|
|
||||||
// Page is loaded
|
|
||||||
pageReady.set(true)
|
|
||||||
|
|
||||||
// Get layout setting from storage
|
|
||||||
layoutSetting = localStorage.getItem('photosLayout')
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<svelte:head>
|
|
||||||
<title>{$site.seo_name} – {$site.seo_title_default} of {location.name}, {country.name}</title>
|
|
||||||
<meta name="description" content="{$site.seo_name} {location.name} {description}">
|
|
||||||
<SocialMetas
|
|
||||||
url="{process.env.CONFIG.PROD_URL}/location/{country.slug}/{location.slug}"
|
|
||||||
title="{$site.seo_name} – {$site.seo_title_default} of {location.name}, {country.name}"
|
|
||||||
description="{$site.seo_name} {location.name} {description}"
|
|
||||||
image={latestPhoto ? getThumbnail(latestPhoto.image.private_hash, 1200, 630) : null}
|
|
||||||
/>
|
|
||||||
</svelte:head>
|
|
||||||
|
|
||||||
<svelte:window bind:innerWidth={windowWidth} />
|
|
||||||
|
|
||||||
<main class="housesof" class:is-transitioning={!$pageReady}>
|
|
||||||
<section class="place">
|
|
||||||
<div class="place__title">
|
|
||||||
<h1 class="title-location title-location--big" aria-label="Houses of {location.name}" data-rellax-speed="-2.75" data-rellax-max-y="200">
|
|
||||||
<span class="place__title_top anim-mask">
|
|
||||||
<span class="place__title_houses">Houses</span>
|
|
||||||
<em class="place__title_of">of</em>
|
|
||||||
</span>
|
|
||||||
<span class="place__title_bottom anim-mask">
|
|
||||||
<span class="place__title_name">{location.name}</span>
|
|
||||||
</span>
|
|
||||||
</h1>
|
|
||||||
|
|
||||||
<div data-rellax-speed={windowWidth <= 768 ? -2.5 : -1.75} data-rellax-max-y="200">
|
|
||||||
<a href="/choose" class="button-control button-control--big button-control--dashed" aria-label="Change location">
|
|
||||||
<span class="center">
|
|
||||||
<IconGlobe width={windowWidth <= 768 ? 32 : 44} color="#fff" />
|
|
||||||
<span>Change</span>
|
|
||||||
</span>
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
|
|
||||||
<circle cx="50%" cy="50%" r="43%" />
|
|
||||||
</svg>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="place__wrap wrap">
|
|
||||||
<div class="place__description">
|
|
||||||
<div class="wrapper">
|
|
||||||
<p>{$site.description}</p>
|
|
||||||
|
|
||||||
{#if description}
|
|
||||||
<p>
|
|
||||||
Houses Of
|
|
||||||
<LinkChange href="/choose" text={location.name}>
|
|
||||||
<IconGlobeSmall width="14" color="#999" />
|
|
||||||
</LinkChange>
|
|
||||||
{description}
|
|
||||||
</p>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
{#if photos.length}
|
|
||||||
<p class="updated style-caps">
|
|
||||||
<strong>Updated</strong>
|
|
||||||
<time datetime={dateUpdatedDatetime} title={dateUpdatedFull}>{dateUpdatedRelative}</time>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<ToggleLayout />
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{#if illu_desktop || illu_desktop_2x || illu_mobile}
|
|
||||||
<div class="place__illustration">
|
|
||||||
<div class="parallax" data-rellax-speed="-5" data-rellax-max-y="400">
|
|
||||||
<div class="place__illustration_img"
|
|
||||||
style="{`--url-desktop: ${illu_desktop ? `url(${illu_desktop.full_url});` : undefined}`}
|
|
||||||
{`--url-desktop-2x: ${illu_desktop_2x ? `url(${illu_desktop_2x.full_url});` : undefined}`}
|
|
||||||
{`--url-mobile: ${illu_mobile ? `url(${illu_mobile.full_url});` : undefined}`}"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="photos photos--{layoutSetting || 'list'}">
|
|
||||||
<div class="photos__sidewrap wrap">
|
|
||||||
<aside class="photos__side">
|
|
||||||
<Switcher type="switcher--side" />
|
|
||||||
|
|
||||||
{#if photos.length}
|
|
||||||
<p class="updated style-caps">
|
|
||||||
<strong>Updated</strong>
|
|
||||||
<time datetime={dateUpdatedDatetime} title={dateUpdatedFull}>{dateUpdatedRelative}</time>
|
|
||||||
</p>
|
|
||||||
{/if}
|
|
||||||
</aside>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{#if photos}
|
|
||||||
<div class="photos__view wrap">
|
|
||||||
{#each paginatedPhotos as photo}
|
|
||||||
<Photo {photo} index={photos.length - photos.indexOf(photo)} />
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Pagination {photos} {paginatedPhotos} {photosPerPage}
|
|
||||||
on:updatePagination={updatePagination}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{:else}
|
|
||||||
<div class="wrap" style="padding-top: 20vw; padding-bottom: 20vw;">
|
|
||||||
<p style="text-align: center; color: #333;">No photo for {location.name}</p>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<Footer />
|
|
||||||
</main>
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
const fs = require('fs')
|
|
||||||
const fetch = require('node-fetch')
|
|
||||||
import { apiEndpoints } from 'utils/store'
|
|
||||||
import { formatDate } from 'utils/functions'
|
|
||||||
|
|
||||||
|
|
||||||
// Variables
|
|
||||||
let baseURL
|
|
||||||
const pages = ['']
|
|
||||||
|
|
||||||
// Get routes and push it to array
|
|
||||||
const routesExclude = ['sitemap', 'index', 'location', 'viewer']
|
|
||||||
fs.readdirSync('./src/routes').forEach(file => {
|
|
||||||
const filename = file.split('.')[0]
|
|
||||||
if (!file.startsWith('.') && !filename.startsWith('_') && routesExclude.indexOf(filename) === -1) {
|
|
||||||
pages.push(filename)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
// Render function
|
|
||||||
const render = (pages, locations) => {
|
|
||||||
return `<?xml version="1.0" encoding="UTF-8" ?>
|
|
||||||
<urlset
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
|
|
||||||
xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd"
|
|
||||||
>
|
|
||||||
${pages.map(page => `
|
|
||||||
<url>
|
|
||||||
<loc>${baseURL}/${page}</loc>
|
|
||||||
<priority>0.75</priority>
|
|
||||||
</url>`).join('\n')}
|
|
||||||
|
|
||||||
${locations.map(loc => `
|
|
||||||
<url>
|
|
||||||
<loc>${baseURL}/location/${loc.country.slug}/${loc.slug}</loc>
|
|
||||||
<priority>1</priority>
|
|
||||||
<lastmod>${formatDate(loc.updated, 'DATETIME')}</lastmod>
|
|
||||||
<changefreq>weekly</changefreq>
|
|
||||||
</url>`).join('\n')
|
|
||||||
}
|
|
||||||
</urlset>`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get function
|
|
||||||
export async function get (req, res, next) {
|
|
||||||
let locations
|
|
||||||
|
|
||||||
// Define base url from request
|
|
||||||
baseURL = `https://${req.headers.host}`
|
|
||||||
|
|
||||||
// Get locations
|
|
||||||
await fetch(`${apiEndpoints.rest}/items/locations?fields=slug,country.slug,modified_on&status=published&sort=created_on`)
|
|
||||||
.then(res => res.json())
|
|
||||||
.then(res => {
|
|
||||||
locations = res.data
|
|
||||||
})
|
|
||||||
|
|
||||||
// Add last modified date to each location from its last photo
|
|
||||||
const updatedLocations = locations.map(async (location, i) => {
|
|
||||||
await fetch(`${apiEndpoints.rest}/items/photos?fields=created_on&limit=1&sort=-created_on&status=published&filter[location.slug][rlike]=%${location.slug}`)
|
|
||||||
.then(res => res.json())
|
|
||||||
.then(res => {
|
|
||||||
const latestPhoto = res.data[0]
|
|
||||||
location.updated = latestPhoto ? latestPhoto.created_on : location.modified_on
|
|
||||||
})
|
|
||||||
return location
|
|
||||||
})
|
|
||||||
await Promise.all(updatedLocations)
|
|
||||||
|
|
||||||
// Set headers
|
|
||||||
res.setHeader('Cache-Control', 'max-age=0, s-max-age=600') // 10 minutes
|
|
||||||
res.setHeader('Content-Type', 'application/rss+xml')
|
|
||||||
|
|
||||||
// Render sitemap
|
|
||||||
const sitemap = render(pages, locations)
|
|
||||||
res.end(sitemap)
|
|
||||||
}
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
<script>
|
|
||||||
import { onMount } from 'svelte'
|
|
||||||
import { stores } from '@sapper/app'
|
|
||||||
import { site, pageReady, pageAnimation } from 'utils/store'
|
|
||||||
// Dependencies
|
|
||||||
import Lazy from 'svelte-lazy'
|
|
||||||
// Components
|
|
||||||
import IconArrow from 'atoms/IconArrow'
|
|
||||||
import TitleSite from 'atoms/TitleSite'
|
|
||||||
import LinkTranslate from 'atoms/LinkTranslate'
|
|
||||||
import InteractiveGlobe from 'molecules/InteractiveGlobe'
|
|
||||||
import NewsletterForm from 'molecules/NewsletterForm'
|
|
||||||
import Footer from 'organisms/Footer'
|
|
||||||
import SocialMetas from 'utils/SocialMetas'
|
|
||||||
// Animations
|
|
||||||
import { animateIn } from 'animations/page'
|
|
||||||
|
|
||||||
// Variables
|
|
||||||
const { page } = stores()
|
|
||||||
pageAnimation.set(animateIn)
|
|
||||||
const pageTitle = `${$site.seo_name} - Keep Updated`
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Run code when mounted
|
|
||||||
*/
|
|
||||||
onMount(() => {
|
|
||||||
// Page is loaded
|
|
||||||
pageReady.set(true)
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<svelte:head>
|
|
||||||
<title>{pageTitle}</title>
|
|
||||||
<meta name="description" content={$site.subscribe_text}>
|
|
||||||
<SocialMetas
|
|
||||||
url="{process.env.CONFIG.PROD_URL}{$page.path}"
|
|
||||||
title="{pageTitle}"
|
|
||||||
description={$site.subscribe_text}
|
|
||||||
image={$site.seo_share_image.full_url}
|
|
||||||
/>
|
|
||||||
</svelte:head>
|
|
||||||
|
|
||||||
<main class="housesof page--credits" class:is-transitioning={!$pageReady}>
|
|
||||||
<section class="page">
|
|
||||||
<div class="wrap">
|
|
||||||
<div class="page__top">
|
|
||||||
<a href="/" class="button-control button-control--lightpink dir-left">
|
|
||||||
<IconArrow direction="left" color="#fff" class="icon" />
|
|
||||||
<IconArrow direction="left" color="#fff" class="icon" hidden="true" />
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<TitleSite />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="newsletter newsletter--column">
|
|
||||||
<div class="newsletter__text style-description page__part">
|
|
||||||
<p>{$site.newsletter_text}</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="page__part">
|
|
||||||
<NewsletterForm title={true} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{#if process.browser}
|
|
||||||
<Lazy offset={window.innerHeight} fadeOption={null}>
|
|
||||||
<InteractiveGlobe type="part" opacity="0.5" />
|
|
||||||
</Lazy>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
<Footer />
|
|
||||||
</section>
|
|
||||||
</main>
|
|
||||||
@@ -1,137 +0,0 @@
|
|||||||
<script context="module">
|
|
||||||
// Define either to preload data or use the store
|
|
||||||
let preloaded
|
|
||||||
currentPhotos.subscribe(store => preloaded = store ? store : undefined)
|
|
||||||
|
|
||||||
// Preload data
|
|
||||||
export async function preload (page, session) {
|
|
||||||
// Load the photos if not loaded
|
|
||||||
if (!preloaded) {
|
|
||||||
const fields = [
|
|
||||||
'id', 'name', 'slug', 'date', 'image.private_hash',
|
|
||||||
'location.id', 'location.name', 'location.slug',
|
|
||||||
'location.country.name', 'location.country.slug'
|
|
||||||
]
|
|
||||||
const req = await this.fetch(`${apiEndpoints.rest}/items/photos?fields=${fields.join()}&status=published&filter[location.slug][rlike]=%${page.params.place}%`, {
|
|
||||||
'Authorization': 'bearer ' + process.env.CONFIG.API_TOKEN
|
|
||||||
})
|
|
||||||
const photos = await req.json()
|
|
||||||
if (req.ok) {
|
|
||||||
return { photos: photos.data }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Use the store otherwise
|
|
||||||
else return {
|
|
||||||
photos: preloaded
|
|
||||||
}
|
|
||||||
this.error(404, 'Not found')
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { onMount } from 'svelte'
|
|
||||||
import { stores } from '@sapper/app'
|
|
||||||
import {
|
|
||||||
apiEndpoints,
|
|
||||||
site,
|
|
||||||
locations,
|
|
||||||
currentLocation,
|
|
||||||
currentPhotos,
|
|
||||||
pageReady,
|
|
||||||
pageAnimation
|
|
||||||
} from 'utils/store'
|
|
||||||
import { getThumbnail } from 'utils/functions'
|
|
||||||
// Components
|
|
||||||
import IconGlobe from 'atoms/IconGlobe'
|
|
||||||
import IconCross from 'atoms/IconCross'
|
|
||||||
import Carousel from 'organisms/Carousel'
|
|
||||||
import Fullscreen from 'organisms/Fullscreen'
|
|
||||||
import Transition from 'utils/Transition'
|
|
||||||
import SocialMetas from 'utils/SocialMetas'
|
|
||||||
// Animations
|
|
||||||
import { animateIn } from 'animations/viewer'
|
|
||||||
|
|
||||||
// Props
|
|
||||||
export let photos
|
|
||||||
|
|
||||||
const { page } = stores()
|
|
||||||
pageAnimation.set(animateIn)
|
|
||||||
|
|
||||||
// Update store current location
|
|
||||||
currentLocation.set($locations.find(loc => loc.slug === $page.params.place))
|
|
||||||
currentPhotos.set(photos)
|
|
||||||
|
|
||||||
let windowWidth
|
|
||||||
let gotoLink
|
|
||||||
let currentPhoto = photos.find(photo => photo.slug === $page.params.photo)
|
|
||||||
|
|
||||||
|
|
||||||
// Photo has changed (from Carousel)
|
|
||||||
const photoChanged = event => {
|
|
||||||
const currentPhoto = event.detail
|
|
||||||
const windowPathname = window.location.pathname
|
|
||||||
if (currentPhoto) {
|
|
||||||
const newUrl = windowPathname.substring(0, windowPathname.lastIndexOf('/') + 1) + currentPhoto.slug
|
|
||||||
// Go to page via a sapper-noscroll link to avoid scroll jump (hacky)
|
|
||||||
if (gotoLink && newUrl) {
|
|
||||||
gotoLink.href = newUrl
|
|
||||||
gotoLink.click()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Run code when mounted
|
|
||||||
*/
|
|
||||||
onMount(() => {
|
|
||||||
// Page is loaded
|
|
||||||
pageReady.set(true)
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<svelte:head>
|
|
||||||
{#if $currentLocation}
|
|
||||||
<title>{$site.seo_name} – {$site.seo_title_default} of {$currentLocation.name}, {$currentLocation.country.name}</title>
|
|
||||||
<meta name="description" content="{$site.seo_name} {$currentLocation.name} {$currentLocation.description}">
|
|
||||||
<SocialMetas
|
|
||||||
url="{process.env.CONFIG.PROD_URL}/viewer/{currentPhoto.location.country.slug}/{currentPhoto.location.slug}/{currentPhoto.slug}"
|
|
||||||
title="{$site.seo_name} - {$site.seo_title_default} of {$currentLocation.name}, {$currentLocation.country.name}"
|
|
||||||
description="{$site.seo_name} {$currentLocation.name} {$currentLocation.description}"
|
|
||||||
image={getThumbnail(currentPhoto.image.private_hash, 1200, 630)}
|
|
||||||
/>
|
|
||||||
{/if}
|
|
||||||
</svelte:head>
|
|
||||||
|
|
||||||
<svelte:window bind:innerWidth={windowWidth} />
|
|
||||||
|
|
||||||
<main class="housesof" class:is-transitioning={!$pageReady}>
|
|
||||||
<section class="viewer">
|
|
||||||
<div class="viewer__top">
|
|
||||||
<p class="tip">Tap for fullscreen</p>
|
|
||||||
|
|
||||||
<div class="viewer__buttons">
|
|
||||||
<a href="/choose" class="button-control button-control--dashed" aria-label="Change the location" rel="prefetch">
|
|
||||||
<IconGlobe color="#fff" width={windowWidth >= 768 ? 22 : 18} />
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
|
|
||||||
<circle cx="50%" cy="50%" r="{windowWidth >= 768 ? 32 : 24}px"></circle>
|
|
||||||
</svg>
|
|
||||||
</a>
|
|
||||||
{#if $currentLocation}
|
|
||||||
<a href="/location/{$currentLocation.country.slug}/{$currentLocation.slug}" class="button-control button-control--lightpink dir-bottom" aria-label="Back to photos" rel="prefetch">
|
|
||||||
<IconCross color="#fff" width="18" class="icon" />
|
|
||||||
<IconCross color="#fff" width="18" class="icon" hidden="true" />
|
|
||||||
</a>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<a href="/" bind:this={gotoLink} aria-hidden="true" hidden class="hidden" sapper-noscroll> </a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Carousel {photos} viewer={true}
|
|
||||||
on:photoChange={photoChanged}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Fullscreen />
|
|
||||||
</section>
|
|
||||||
</main>
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
import sirv from 'sirv'
|
|
||||||
import polka from 'polka'
|
|
||||||
import compression from 'compression'
|
|
||||||
import * as sapper from '@sapper/server'
|
|
||||||
|
|
||||||
// Define environment
|
|
||||||
const { PORT, NODE_ENV } = process.env
|
|
||||||
const dev = NODE_ENV === 'development'
|
|
||||||
|
|
||||||
// Setup server
|
|
||||||
polka()
|
|
||||||
.use(
|
|
||||||
compression({ threshold: 0 }),
|
|
||||||
sirv('static', { dev }),
|
|
||||||
sapper.middleware()
|
|
||||||
)
|
|
||||||
.listen(PORT, err => {
|
|
||||||
if (err) console.log('error', err)
|
|
||||||
})
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
import { timestamp, files, shell, routes } from '@sapper/service-worker'
|
|
||||||
|
|
||||||
const ASSETS = `cache${timestamp}`
|
|
||||||
|
|
||||||
// `shell` is an array of all the files generated by the bundler,
|
|
||||||
// `files` is an array of everything in the `static` directory
|
|
||||||
const to_cache = shell.concat(files)
|
|
||||||
const cached = new Set(to_cache)
|
|
||||||
|
|
||||||
// Install
|
|
||||||
self.addEventListener('install', event => {
|
|
||||||
event.waitUntil(
|
|
||||||
caches
|
|
||||||
.open(ASSETS)
|
|
||||||
.then(cache => cache.addAll(to_cache))
|
|
||||||
.then(() => {
|
|
||||||
self.skipWaiting()
|
|
||||||
})
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
// Activate
|
|
||||||
self.addEventListener('activate', event => {
|
|
||||||
event.waitUntil(
|
|
||||||
caches.keys().then(async keys => {
|
|
||||||
// delete old caches
|
|
||||||
for (const key of keys) {
|
|
||||||
if (key !== ASSETS) await caches.delete(key)
|
|
||||||
}
|
|
||||||
|
|
||||||
self.clients.claim()
|
|
||||||
})
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
// Fetch
|
|
||||||
self.addEventListener('fetch', event => {
|
|
||||||
if (event.request.method !== 'GET' || event.request.headers.has('range')) return
|
|
||||||
|
|
||||||
const url = new URL(event.request.url)
|
|
||||||
|
|
||||||
// don't try to handle e.g. data: URIs
|
|
||||||
if (!url.protocol.startsWith('http')) return
|
|
||||||
|
|
||||||
// ignore dev server requests
|
|
||||||
if (url.hostname === self.location.hostname && url.port !== self.location.port) return
|
|
||||||
|
|
||||||
// always serve static files and bundler-generated assets from cache
|
|
||||||
if (url.host === self.location.host && cached.has(url.pathname)) {
|
|
||||||
event.respondWith(caches.match(event.request))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// for pages, you might want to serve a shell `service-worker-index.html` file,
|
|
||||||
// which Sapper has generated for you. It's not right for every
|
|
||||||
// app, but if it's right for yours then uncomment this section
|
|
||||||
/*
|
|
||||||
if (url.origin === self.origin && routes.find(route => route.pattern.test(url.pathname))) {
|
|
||||||
event.respondWith(caches.match('/service-worker-index.html'))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (event.request.cache === 'only-if-cached') return
|
|
||||||
|
|
||||||
// for everything else, try the network first, falling back to
|
|
||||||
// cache if the user is offline. (If the pages never change, you
|
|
||||||
// might prefer a cache-first approach to a network-first one.)
|
|
||||||
event.respondWith(
|
|
||||||
caches
|
|
||||||
.open(`offline${timestamp}`)
|
|
||||||
.then(async cache => {
|
|
||||||
try {
|
|
||||||
const response = await fetch(event.request)
|
|
||||||
cache.put(event.request, response.clone())
|
|
||||||
return response
|
|
||||||
} catch(err) {
|
|
||||||
const response = await cache.match(event.request)
|
|
||||||
if (response) return response
|
|
||||||
|
|
||||||
throw err
|
|
||||||
}
|
|
||||||
})
|
|
||||||
)
|
|
||||||
})
|
|
||||||
@@ -1,38 +1,52 @@
|
|||||||
html {
|
html {
|
||||||
font: #{$base-font-size} $font-sans;
|
font: #{$base-font-size}/1.2 $font-sans;
|
||||||
color: $color-text;
|
color: #fff;
|
||||||
min-width: 320px;
|
min-width: 320px;
|
||||||
overflow-x: hidden;
|
word-break: normal;
|
||||||
}
|
}
|
||||||
body {
|
body {
|
||||||
@include font-smooth;
|
@include font-smooth;
|
||||||
background: $color-primary;
|
background: $color-primary;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
|
overflow-x: hidden;
|
||||||
|
overscroll-behavior-y: none;
|
||||||
}
|
}
|
||||||
*, *:before, *:after {
|
*, *:before, *:after {
|
||||||
box-sizing: border-box;
|
text-rendering: optimizeLegibility;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
}
|
}
|
||||||
strong {
|
strong {
|
||||||
font-weight: normal;
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
em {
|
em {
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
figure, p, dl, dt, dd, ul, ol, li {
|
figure, p, dl, dt, dd, ul, li {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
figure img {
|
figure, picture {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
nav li:before {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
button {
|
button {
|
||||||
background: none;
|
background: none;
|
||||||
border: none;
|
border: none;
|
||||||
outline: none;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Accessibility outline
|
||||||
|
// Remove default focus styles for mouse users if :focus-visible is supported
|
||||||
|
[data-js-focus-visible] :focus:not([data-focus-visible-added]) {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
[data-focus-visible-added], *:focus-visible {
|
||||||
|
outline: 1px dashed $color-tertiary;
|
||||||
|
}
|
||||||
|
|
||||||
// Selection
|
// Selection
|
||||||
::selection { color: #fff; background: $color-secondary; }
|
::selection { color: #fff; background: $color-secondary; }
|
||||||
::-moz-selection { color: #fff; background: $color-secondary; }
|
::-moz-selection { color: #fff; background: $color-secondary; }
|
||||||
@@ -50,215 +64,19 @@ button {
|
|||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Title: Massive
|
|
||||||
.title-massive {
|
|
||||||
font-family: $font-serif-extra;
|
|
||||||
font-size: pxVW(800);
|
|
||||||
line-height: 1;
|
|
||||||
color: $color-secondary;
|
|
||||||
letter-spacing: -2vw;
|
|
||||||
text-align: center;
|
|
||||||
pointer-events: none;
|
|
||||||
user-select: none;
|
|
||||||
|
|
||||||
@include breakpoint (lg) {
|
/* Global elements
|
||||||
font-size: pxVW(700);
|
========================================================================== */
|
||||||
}
|
// Split text elements
|
||||||
@include breakpoint (1920px) {
|
.word, .char {
|
||||||
font-size: rem(900px);
|
|
||||||
letter-spacing: -40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&, span {
|
|
||||||
will-change: transform, opacity;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Title: Category
|
|
||||||
.title-category {
|
|
||||||
font-family: $font-serif;
|
|
||||||
font-size: rem(28px);
|
|
||||||
line-height: 1;
|
|
||||||
color: $color-secondary;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Title: Locations
|
|
||||||
.title-location {
|
|
||||||
font-family: $font-serif;
|
|
||||||
font-size: rem(48px);
|
|
||||||
line-height: 1;
|
|
||||||
color: $color-secondary;
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
font-size: rem(64px);
|
|
||||||
}
|
|
||||||
@include breakpoint (lg) {
|
|
||||||
font-size: rem(72px);
|
|
||||||
}
|
|
||||||
@include breakpoint (xl) {
|
|
||||||
font-size: rem(96px);
|
|
||||||
}
|
|
||||||
|
|
||||||
em {
|
|
||||||
display: block;
|
|
||||||
font-size: rem(18px);
|
|
||||||
color: $color-lightpurple;
|
|
||||||
text-transform: uppercase;
|
|
||||||
letter-spacing: 1px;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
font-size: rem(32px);
|
transform-style: preserve-3d;
|
||||||
margin-right: -8px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
span, em {
|
|
||||||
will-change: transform;
|
will-change: transform;
|
||||||
}
|
}
|
||||||
|
.words-3d {
|
||||||
// Bigger version
|
perspective: 800px;
|
||||||
&--big {
|
|
||||||
font-size: pxVW(180);
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
font-size: pxVW(130);
|
|
||||||
}
|
|
||||||
@include breakpoint (md) {
|
|
||||||
font-size: pxVW(160);
|
|
||||||
}
|
|
||||||
@include breakpoint (lg) {
|
|
||||||
font-size: rem(160px);
|
|
||||||
}
|
|
||||||
|
|
||||||
em {
|
|
||||||
display: inline-block;
|
|
||||||
font-size: 0.35em;
|
|
||||||
|
|
||||||
@include breakpoint (md) {
|
|
||||||
margin-left: -8px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Inline version
|
|
||||||
&--inline {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: baseline;
|
|
||||||
}
|
|
||||||
|
|
||||||
em {
|
|
||||||
margin: 8px 0 4px;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
margin: 2px 16px 0 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
span {
|
span {
|
||||||
position: relative;
|
transform-origin: 0 85%;
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Text Styles
|
|
||||||
========================================================================== */
|
|
||||||
// Location
|
|
||||||
.style-location {
|
|
||||||
font-family: $font-serif;
|
|
||||||
font-size: 6vw;
|
|
||||||
color: #fff;
|
|
||||||
line-height: 1.15;
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
@include breakpoint (mob) {
|
|
||||||
font-size: rem(24px);
|
|
||||||
}
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
font-size: rem(28px);
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: #fff;
|
|
||||||
text-decoration: none;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: $color-secondary;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.street {
|
|
||||||
margin-bottom: 8px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Information (capitalized text)
|
|
||||||
.style-caps {
|
|
||||||
font-family: $font-sans;
|
|
||||||
font-size: rem(12px);
|
|
||||||
color: $color-tertiary;
|
|
||||||
text-transform: uppercase;
|
|
||||||
letter-spacing: 1px;
|
|
||||||
|
|
||||||
// Transparent variant
|
|
||||||
&--transparent {
|
|
||||||
color: rgba($color-tertiary, 0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
font-size: rem(14px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Short text (description)
|
|
||||||
.style-description {
|
|
||||||
color: $color-tertiary;
|
|
||||||
font-family: $font-sans-light;
|
|
||||||
font-size: rem(18px);
|
|
||||||
line-height: 1.55;
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
max-width: 572px;
|
|
||||||
margin: 0 auto;
|
|
||||||
font-size: rem(28px);
|
|
||||||
line-height: 1.64;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dark text
|
|
||||||
&--dark {
|
|
||||||
color: $color-text;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Small text variant
|
|
||||||
&--small {
|
|
||||||
font-size: rem(16px);
|
|
||||||
line-height: 1.4;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
font-size: rem(20px);
|
|
||||||
line-height: 1.5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Notice
|
|
||||||
.style-notice {
|
|
||||||
color: rgba($color-tertiary, 0.5);
|
|
||||||
font-family: $font-sans-light;
|
|
||||||
font-size: rem(14px);
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
font-size: rem(16px);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,12 +1,7 @@
|
|||||||
/* Fonts list
|
/* Fonts list
|
||||||
========================================================================== */
|
========================================================================== */
|
||||||
$fonts: (
|
@include font-face("Garnett", "G-Light", 300);
|
||||||
"G-Light",
|
@include font-face("Garnett", "G-Regular", 400);
|
||||||
"G-Regular",
|
@include font-face("Garnett", "G-Semibold", 500);
|
||||||
"G-Semibold",
|
@include font-face("Magnolia", "M-Extralight", 200);
|
||||||
"M-Extralight",
|
@include font-face("Magnolia", "M-Light", 300);
|
||||||
"M-Light"
|
|
||||||
);
|
|
||||||
@each $font in $fonts {
|
|
||||||
@include font-face($font);
|
|
||||||
}
|
|
||||||
0
src/style/_typography.scss
Normal file
0
src/style/_typography.scss
Normal file
@@ -12,36 +12,42 @@ $color-gray: #666;
|
|||||||
$color-lightgray: #999;
|
$color-lightgray: #999;
|
||||||
|
|
||||||
// CSS Variables
|
// CSS Variables
|
||||||
// :root {
|
:root {
|
||||||
// }
|
// Sizes
|
||||||
|
--container-width: 1680px;
|
||||||
|
|
||||||
|
// Animation
|
||||||
|
--ease-quart: cubic-bezier(.165, .84, .44, 1);
|
||||||
|
--ease-cubic: cubic-bezier(.785, .135, .15, .86);
|
||||||
|
--ease-inout-quart: cubic-bezier(.76, 0, .24, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Fonts
|
/* Fonts
|
||||||
========================================================================== */
|
========================================================================== */
|
||||||
$base-font-size: 28px;
|
$base-font-size: 28px !default;
|
||||||
|
|
||||||
// Families
|
// Families
|
||||||
$replacement-sans: "Helvetica, Arial, sans-serif";
|
$replacement-sans: "Helvetica, Arial, sans-serif";
|
||||||
$replacement-serif: "Georgia, serif";
|
$replacement-serif: "Georgia, serif";
|
||||||
$font-sans: "G-Regular", #{$replacement-sans};
|
$font-sans: "Garnett", #{$replacement-sans};
|
||||||
$font-sans-sb: "G-Semibold", #{$replacement-sans};
|
$font-serif: "Magnolia", #{$replacement-serif};
|
||||||
$font-sans-light: "G-Light", #{$replacement-sans};
|
|
||||||
$font-serif: "M-Light", #{$replacement-serif};
|
|
||||||
$font-serif-extra: "M-Extralight", #{$replacement-serif};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Sizes, margins and spacing
|
/* Sizes, margins and spacing
|
||||||
====================================================================== */
|
====================================================================== */
|
||||||
$base-width: 1600;
|
$base-width: 1600 !default;
|
||||||
|
|
||||||
// Blocks
|
// Grid
|
||||||
|
$cols-m: 12 !default;
|
||||||
|
$cols-d: 32 !default;
|
||||||
|
|
||||||
|
|
||||||
/* Directories
|
/* Directories
|
||||||
========================================================================== */
|
========================================================================== */
|
||||||
$dir-img: "/img";
|
$dir-img: "/images" !default;
|
||||||
$dir-fonts: "/fonts";
|
$dir-fonts: "/fonts" !default;
|
||||||
|
|
||||||
|
|
||||||
/* Animation
|
/* Animation
|
||||||
@@ -54,10 +60,14 @@ $ease-inout: ease-in-out;
|
|||||||
|
|
||||||
/* Responsive breakpoints
|
/* Responsive breakpoints
|
||||||
========================================================================== */
|
========================================================================== */
|
||||||
$screen-mob: 450px;
|
$breakpoints: (
|
||||||
$screen-xs: 767px;
|
mob: 450px,
|
||||||
$screen-sm: 768px;
|
mob-lg: 550px,
|
||||||
$screen-md: 992px;
|
xs: 767px,
|
||||||
$screen-lg: 1200px;
|
sm: 768px,
|
||||||
$screen-xl: 1440px;
|
md: 992px,
|
||||||
$screen-xxl: 1600px;
|
sd: 1200px,
|
||||||
|
lg: 1440px,
|
||||||
|
xl: 1600px,
|
||||||
|
fhd: 1920px,
|
||||||
|
) !default;
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
/*
|
|
||||||
** Badge
|
|
||||||
*/
|
|
||||||
.badge {
|
|
||||||
display: inline-flex;
|
|
||||||
justify-content: center;
|
|
||||||
text-align: center;
|
|
||||||
color: $color-primary-darker;
|
|
||||||
font-family: $font-sans-sb;
|
|
||||||
text-transform: uppercase;
|
|
||||||
letter-spacing: 1px;
|
|
||||||
background-color: $color-secondary-light;
|
|
||||||
box-shadow: 0 0 0 4px rgba($color-tertiary, 0.15);
|
|
||||||
border-radius: 50vh;
|
|
||||||
|
|
||||||
// Small size
|
|
||||||
&--small {
|
|
||||||
height: 14px;
|
|
||||||
padding: 0 4px;
|
|
||||||
font-size: rem(7px);
|
|
||||||
line-height: 15px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,283 +0,0 @@
|
|||||||
// Button: Control
|
|
||||||
.button-control {
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
width: 40px;
|
|
||||||
height: 40px;
|
|
||||||
overflow: hidden;
|
|
||||||
padding-top: 2px;
|
|
||||||
pointer-events: auto;
|
|
||||||
border-radius: 50%;
|
|
||||||
border: none;
|
|
||||||
cursor: pointer;
|
|
||||||
outline: none;
|
|
||||||
transition: background-color 350ms $ease-quart;
|
|
||||||
will-change: transform, opacity;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
width: 56px;
|
|
||||||
height: 56px;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Icon
|
|
||||||
.icon {
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
display: block;
|
|
||||||
height: auto;
|
|
||||||
transition: transform 500ms $ease-quart, opacity 150ms $ease-inout;
|
|
||||||
will-change: transform;
|
|
||||||
|
|
||||||
&:not([data-width]) {
|
|
||||||
width: 13px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
&:not([data-width]) {
|
|
||||||
width: 20px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.icon[aria-hidden] {
|
|
||||||
opacity: 0;
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
left: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Variants
|
|
||||||
*/
|
|
||||||
&--white {
|
|
||||||
background-color: #fff;
|
|
||||||
|
|
||||||
&:hover, &.hover {
|
|
||||||
background-color: $color-secondary;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&--lightpink {
|
|
||||||
background-color: rgba($color-secondary, 0.4);
|
|
||||||
|
|
||||||
&:hover, &.hover {
|
|
||||||
background-color: rgba($color-secondary, 0.85);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&--pink {
|
|
||||||
background-color: rgba($color-secondary, 0.85);
|
|
||||||
|
|
||||||
&:hover, &.hover {
|
|
||||||
background-color: $color-secondary;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&--gray {
|
|
||||||
background-color: $color-gray;
|
|
||||||
|
|
||||||
&:hover, &.hover {
|
|
||||||
background-color: $color-text;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Effects
|
|
||||||
*/
|
|
||||||
&--shadow {
|
|
||||||
box-shadow: 0 0 10px rgba(#000, 0.4);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Directions
|
|
||||||
*/
|
|
||||||
// To left
|
|
||||||
&.dir-left {
|
|
||||||
.icon[aria-hidden] {
|
|
||||||
transform: translate(100%, -50%);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover, &.hover {
|
|
||||||
.icon:not([aria-hidden]) {
|
|
||||||
opacity: 0;
|
|
||||||
transform: translate(-100%, 0);
|
|
||||||
}
|
|
||||||
.icon[aria-hidden] {
|
|
||||||
opacity: 1;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// To right
|
|
||||||
&.dir-right {
|
|
||||||
.icon[aria-hidden] {
|
|
||||||
transform: translate(-150%, -50%);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover, &.hover {
|
|
||||||
.icon:not([aria-hidden]) {
|
|
||||||
opacity: 0;
|
|
||||||
transform: translate(100%, 0);
|
|
||||||
}
|
|
||||||
.icon[aria-hidden] {
|
|
||||||
opacity: 1;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// From top
|
|
||||||
&.dir-top {
|
|
||||||
.icon[aria-hidden] {
|
|
||||||
left: auto;
|
|
||||||
transform: translate(0, -150%);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover, &.hover {
|
|
||||||
.icon:not([aria-hidden]) {
|
|
||||||
opacity: 0;
|
|
||||||
transform: translate(0, 100%);
|
|
||||||
}
|
|
||||||
.icon[aria-hidden] {
|
|
||||||
opacity: 1;
|
|
||||||
transform: translate(0, -50%);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// From bottom
|
|
||||||
&.dir-bottom {
|
|
||||||
.icon[aria-hidden] {
|
|
||||||
left: auto;
|
|
||||||
transform: translate(0, 150%);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover, &.hover {
|
|
||||||
.icon:not([aria-hidden]) {
|
|
||||||
opacity: 0;
|
|
||||||
transform: translate(0, -100%);
|
|
||||||
}
|
|
||||||
.icon[aria-hidden] {
|
|
||||||
opacity: 1;
|
|
||||||
transform: translate(0, -50%);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Dashed style
|
|
||||||
*/
|
|
||||||
&--dashed {
|
|
||||||
position: relative;
|
|
||||||
overflow: visible;
|
|
||||||
background-color: rgba($color-lightpurple, 0.5);
|
|
||||||
transition: background-color 150ms $ease-inout;
|
|
||||||
will-change: transform, opacity;
|
|
||||||
|
|
||||||
// Icon
|
|
||||||
svg[fill] {
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dashed circle
|
|
||||||
svg:not([fill]) {
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
left: 50%;
|
|
||||||
width: 130%;
|
|
||||||
height: 130%;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
}
|
|
||||||
circle {
|
|
||||||
display: block;
|
|
||||||
stroke-width: 1.75;
|
|
||||||
stroke-dasharray: 7, 3;
|
|
||||||
stroke: rgba($color-lightpurple, 0.35);
|
|
||||||
fill: none;
|
|
||||||
transform-origin: 50% 50%;
|
|
||||||
animation: rotateDashes 5s linear infinite;
|
|
||||||
animation-play-state: paused;
|
|
||||||
animation-delay: 50ms;
|
|
||||||
transition: stroke 150ms $ease-inout;
|
|
||||||
will-change: stroke;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hover
|
|
||||||
&:hover, &:focus {
|
|
||||||
background-color: rgba($color-lightpurple, 0.65);
|
|
||||||
|
|
||||||
* {
|
|
||||||
animation-play-state: running;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Big version
|
|
||||||
*/
|
|
||||||
&--big {
|
|
||||||
width: 88px;
|
|
||||||
height: 88px;
|
|
||||||
text-decoration: none;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
width: 120px;
|
|
||||||
height: 120px;
|
|
||||||
}
|
|
||||||
@include breakpoint (lg) {
|
|
||||||
width: 152px;
|
|
||||||
height: 152px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.center {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
span {
|
|
||||||
display: block;
|
|
||||||
margin-top: 8px;
|
|
||||||
color: rgba(#fff, 0.3);
|
|
||||||
text-transform: uppercase;
|
|
||||||
font-family: $font-sans-sb;
|
|
||||||
font-size: rem(8px);
|
|
||||||
letter-spacing: 1px;
|
|
||||||
line-height: 1;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
margin-top: 10px;
|
|
||||||
font-size: rem(10px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
img {
|
|
||||||
display: block;
|
|
||||||
width: 24px;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
width: 40px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Big Dashed
|
|
||||||
&.button-control--dashed {
|
|
||||||
// Icon
|
|
||||||
svg[fill] {
|
|
||||||
@include breakpoint (xs) {
|
|
||||||
width: 28px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Circle
|
|
||||||
circle {
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
stroke-width: 4.5;
|
|
||||||
stroke-dasharray: 20, 8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
// Button: Outline
|
|
||||||
.button-outline {
|
|
||||||
overflow: hidden;
|
|
||||||
position: relative;
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
height: 32px;
|
|
||||||
padding: 1px 16px 0;
|
|
||||||
background: none;
|
|
||||||
font-family: $font-sans-sb;
|
|
||||||
font-size: rem(14px);
|
|
||||||
color: #fff;
|
|
||||||
border: 2px solid #fff;
|
|
||||||
border-radius: 50vh;
|
|
||||||
text-decoration: none;
|
|
||||||
cursor: pointer;
|
|
||||||
outline: none;
|
|
||||||
transition: all 275ms $ease-cubic;
|
|
||||||
will-change: border, color;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
height: 40px;
|
|
||||||
font-size: rem(18px);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Second text
|
|
||||||
.text {
|
|
||||||
span {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:after {
|
|
||||||
opacity: 0;
|
|
||||||
content: attr(data-text);
|
|
||||||
position: absolute;
|
|
||||||
display: block;
|
|
||||||
text-align: center;
|
|
||||||
top: 50%;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
transform: translateY(100%);
|
|
||||||
}
|
|
||||||
|
|
||||||
span, &:after {
|
|
||||||
transition: transform 275ms $ease-cubic, opacity 275ms $ease-cubic;
|
|
||||||
will-change: transform, opacity;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Disabled
|
|
||||||
&.disabled {
|
|
||||||
color: $color-lightpurple;
|
|
||||||
border-color: $color-lightpurple;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hover
|
|
||||||
&:hover {
|
|
||||||
color: $color-tertiary;
|
|
||||||
border-color: $color-tertiary;
|
|
||||||
|
|
||||||
span {
|
|
||||||
opacity: 0;
|
|
||||||
transform: translateY(-75%);
|
|
||||||
}
|
|
||||||
.text:after {
|
|
||||||
opacity: 1;
|
|
||||||
transform: translateY(-50%);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,97 +0,0 @@
|
|||||||
// Default button
|
|
||||||
.button {
|
|
||||||
position: relative;
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
height: 40px;
|
|
||||||
overflow: hidden;
|
|
||||||
padding: 0 16px;
|
|
||||||
background: #fff;
|
|
||||||
font-family: $font-sans-sb;
|
|
||||||
font-size: rem(14px);
|
|
||||||
color: $color-gray;
|
|
||||||
border-radius: 50vh;
|
|
||||||
text-decoration: none;
|
|
||||||
border: none;
|
|
||||||
outline: none;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: background-color 250ms $ease-cubic, color 350ms $ease-cubic;
|
|
||||||
will-change: background-color, color;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
height: 48px;
|
|
||||||
padding: 1px 24px 0;
|
|
||||||
font-size: rem(18px);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Icon if existing
|
|
||||||
img, svg {
|
|
||||||
position: relative;
|
|
||||||
z-index: 2;
|
|
||||||
display: block;
|
|
||||||
width: 18px;
|
|
||||||
height: auto;
|
|
||||||
margin-right: 8px;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
width: 22px;
|
|
||||||
height: auto;
|
|
||||||
margin-right: 16px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
svg {
|
|
||||||
transition: all 350ms $ease-cubic;
|
|
||||||
|
|
||||||
.anim {
|
|
||||||
animation-delay: 100ms;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Text
|
|
||||||
.text {
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
&:after {
|
|
||||||
content: attr(data-text);
|
|
||||||
opacity: 0;
|
|
||||||
display: block;
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
transform: translateY(100%);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
span {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
span, .text:after {
|
|
||||||
transition: transform 275ms $ease-cubic, opacity 275ms $ease-cubic;
|
|
||||||
will-change: transform, opacity;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hover
|
|
||||||
&:hover {
|
|
||||||
color: #fff;
|
|
||||||
background-color: $color-secondary;
|
|
||||||
|
|
||||||
svg {
|
|
||||||
fill: #fff;
|
|
||||||
}
|
|
||||||
.anim {
|
|
||||||
animation-play-state: running;
|
|
||||||
}
|
|
||||||
.text {
|
|
||||||
span {
|
|
||||||
opacity: 0;
|
|
||||||
transform: translateY(-75%);
|
|
||||||
}
|
|
||||||
&:after {
|
|
||||||
opacity: 1;
|
|
||||||
transform: translateY(-50%);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
// Counter
|
|
||||||
.counter {
|
|
||||||
display: inline-flex;
|
|
||||||
justify-content: center;
|
|
||||||
font-family: $font-serif-extra;
|
|
||||||
font-size: pxVW(672);
|
|
||||||
color: rgba($color-tertiary, 0.4);
|
|
||||||
text-align: center;
|
|
||||||
pointer-events: none;
|
|
||||||
user-select: none;
|
|
||||||
|
|
||||||
// Column
|
|
||||||
&__column {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
line-height: 0.85;
|
|
||||||
text-align: right;
|
|
||||||
margin: 0 0px;
|
|
||||||
transition: transform 0.6s $ease-quart;
|
|
||||||
will-change: transform;
|
|
||||||
|
|
||||||
// Last column
|
|
||||||
&:last-child {
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
// SVG Globe icon
|
|
||||||
.icon-svg {
|
|
||||||
height: 100%;
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
&:after {
|
|
||||||
content: "";
|
|
||||||
display: block;
|
|
||||||
padding-bottom: 133.93%; /* 1.33 ratio */
|
|
||||||
}
|
|
||||||
|
|
||||||
// Small size
|
|
||||||
&--small {
|
|
||||||
&:after {
|
|
||||||
content: "";
|
|
||||||
display: block;
|
|
||||||
padding-bottom: 100%; /* 1:1 ratio */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Animate by default
|
|
||||||
&.is-animated {
|
|
||||||
.anim {
|
|
||||||
animation-play-state: running;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
// Text input
|
|
||||||
.input__text {
|
|
||||||
position: relative;
|
|
||||||
display: block;
|
|
||||||
width: 100%;
|
|
||||||
height: 48px;
|
|
||||||
padding: 0 24px;
|
|
||||||
color: #fff;
|
|
||||||
font-size: rem(16px);
|
|
||||||
font-family: $font-sans-light;
|
|
||||||
border: 2px solid rgba($color-secondary, 0.6);
|
|
||||||
border-radius: 50vh;
|
|
||||||
transition: border 300ms $ease-quart;
|
|
||||||
background: none;
|
|
||||||
outline: none;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
font-size: rem(18px);
|
|
||||||
height: 64px;
|
|
||||||
padding: 0 32px;
|
|
||||||
}
|
|
||||||
|
|
||||||
// States
|
|
||||||
&::placeholder {
|
|
||||||
color: #fff;
|
|
||||||
opacity: 0.75;
|
|
||||||
transition: all 300ms $ease-quart;
|
|
||||||
}
|
|
||||||
&:focus {
|
|
||||||
@extend %input__text--active;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
%input__text--active {
|
|
||||||
border-color: $color-secondary;
|
|
||||||
|
|
||||||
&::placeholder {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,116 +0,0 @@
|
|||||||
/*
|
|
||||||
** Link: Change location
|
|
||||||
*/
|
|
||||||
.link-change {
|
|
||||||
position: relative;
|
|
||||||
display: inline-block;
|
|
||||||
margin: 0 6px;
|
|
||||||
padding: 0 4px;
|
|
||||||
color: $color-secondary;
|
|
||||||
text-decoration: none;
|
|
||||||
transition: color 200ms $ease-cubic;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
padding: 0 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Line
|
|
||||||
&:after {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
z-index: -1;
|
|
||||||
background-color: rgba($color-secondary, 0.22);
|
|
||||||
width: 100%;
|
|
||||||
height: 8px;
|
|
||||||
bottom: 3px;
|
|
||||||
left: 0;
|
|
||||||
border-radius: 50vh;
|
|
||||||
transition: all 200ms $ease-cubic;
|
|
||||||
transition-delay: 50ms;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
height: 14px;
|
|
||||||
bottom: 5px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Icon
|
|
||||||
.icon {
|
|
||||||
position: relative;
|
|
||||||
z-index: 3;
|
|
||||||
top: -3px;
|
|
||||||
display: inline-flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
width: 22px;
|
|
||||||
height: 22px;
|
|
||||||
margin-left: 6px;
|
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 50%;
|
|
||||||
|
|
||||||
svg {
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hover
|
|
||||||
&:hover {
|
|
||||||
color: $color-text;
|
|
||||||
|
|
||||||
&:after {
|
|
||||||
background-color: rgba($color-secondary, 0.4);
|
|
||||||
}
|
|
||||||
svg * {
|
|
||||||
animation-play-state: running;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Link: Translation effect
|
|
||||||
*/
|
|
||||||
.link-translate {
|
|
||||||
display: inline-block;
|
|
||||||
|
|
||||||
.text {
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
&:after {
|
|
||||||
content: attr(data-text);
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
text-align: center;
|
|
||||||
transform: translateY(-50%);
|
|
||||||
opacity: 1;
|
|
||||||
transition: all 275ms $ease-cubic;
|
|
||||||
will-change: transform, opacity;
|
|
||||||
}
|
|
||||||
|
|
||||||
span {
|
|
||||||
display: inline-block;
|
|
||||||
transform: translateY(100%);
|
|
||||||
opacity: 0;
|
|
||||||
transition: all 275ms $ease-cubic;
|
|
||||||
will-change: transform, opacity;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// States
|
|
||||||
&:hover {
|
|
||||||
.text {
|
|
||||||
&:after {
|
|
||||||
transform: translateY(-75%);
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
span {
|
|
||||||
transform: translateY(0);
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,92 +0,0 @@
|
|||||||
// Switcher
|
|
||||||
.switcher {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: #C78FEC;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Text
|
|
||||||
&__text {
|
|
||||||
position: relative;
|
|
||||||
z-index: 2;
|
|
||||||
display: block;
|
|
||||||
font-family: $font-serif;
|
|
||||||
font-size: rem(30px);
|
|
||||||
line-height: 1;
|
|
||||||
text-align: right;
|
|
||||||
|
|
||||||
em {
|
|
||||||
margin-left: -2px;
|
|
||||||
margin-right: 16px;
|
|
||||||
font-size: rem(14px);
|
|
||||||
text-transform: uppercase;
|
|
||||||
color: $color-lightpurple;
|
|
||||||
letter-spacing: 1px;
|
|
||||||
|
|
||||||
&.same-line {
|
|
||||||
margin-right: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.bottom {
|
|
||||||
display: block;
|
|
||||||
color: $color-secondary;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.empty {
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Icon
|
|
||||||
&__icon {
|
|
||||||
width: 52px;
|
|
||||||
height: 52px;
|
|
||||||
margin-top: 4px;
|
|
||||||
margin-left: -8px;
|
|
||||||
|
|
||||||
a {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Side version (smaller)
|
|
||||||
*/
|
|
||||||
&--side {
|
|
||||||
.switcher {
|
|
||||||
&__text {
|
|
||||||
font-size: rem(22px);
|
|
||||||
}
|
|
||||||
&__icon {
|
|
||||||
width: 40px;
|
|
||||||
height: 40px;
|
|
||||||
background-color: #F4EDFB;
|
|
||||||
|
|
||||||
circle {
|
|
||||||
stroke: #F4EDFB;
|
|
||||||
}
|
|
||||||
img, svg[fill] {
|
|
||||||
transform: rotate(90deg);
|
|
||||||
}
|
|
||||||
&:hover {
|
|
||||||
background-color: darken(#F4EDFB, 7);
|
|
||||||
|
|
||||||
circle {
|
|
||||||
stroke: darken(#F4EDFB, 7);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.top {
|
|
||||||
color: $color-primary;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
// Toggle Button
|
|
||||||
.toggle {
|
|
||||||
position: relative;
|
|
||||||
margin-top: 58px;
|
|
||||||
background-color: rgba($color-secondary, 0.25);
|
|
||||||
display: inline-flex;
|
|
||||||
border-radius: 50vh;
|
|
||||||
|
|
||||||
button, .pill {
|
|
||||||
position: relative;
|
|
||||||
z-index: 2;
|
|
||||||
color: $color-secondary;
|
|
||||||
border-radius: 50vh;
|
|
||||||
padding: 12px 24px;
|
|
||||||
font-family: $font-sans-sb;
|
|
||||||
font-size: rem(18px);
|
|
||||||
line-height: 0;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
outline: none;
|
|
||||||
transition: color 100ms;
|
|
||||||
will-change: color;
|
|
||||||
}
|
|
||||||
button {
|
|
||||||
span {
|
|
||||||
margin-left: 16px;
|
|
||||||
}
|
|
||||||
svg {
|
|
||||||
fill: $color-secondary;
|
|
||||||
* {
|
|
||||||
transition: fill 100ms;
|
|
||||||
transition-delay: 0ms;
|
|
||||||
will-change: fill;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Active button
|
|
||||||
&.active {
|
|
||||||
color: #fff;
|
|
||||||
|
|
||||||
svg * {
|
|
||||||
fill: #C78FEC;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hover
|
|
||||||
&:hover:not(.active) {
|
|
||||||
color: $color-secondary-bright;
|
|
||||||
|
|
||||||
svg {
|
|
||||||
fill: $color-secondary-bright;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// List icon
|
|
||||||
&[data-layout="list"]:hover {
|
|
||||||
rect:nth-of-type(even) {
|
|
||||||
animation: layoutListEven 600ms $ease-cubic infinite alternate forwards;
|
|
||||||
}
|
|
||||||
rect:nth-of-type(odd) {
|
|
||||||
animation: layoutListOdd 600ms $ease-cubic infinite alternate forwards;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Grid icon
|
|
||||||
&[data-layout="grid"]:hover {
|
|
||||||
rect:nth-of-type(even) {
|
|
||||||
animation: layoutGridEven 600ms $ease-cubic infinite alternate forwards;
|
|
||||||
}
|
|
||||||
rect:nth-of-type(odd) {
|
|
||||||
animation: layoutGridOdd 600ms $ease-cubic infinite alternate forwards;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pill (active)
|
|
||||||
.pill {
|
|
||||||
position: absolute;
|
|
||||||
z-index: 1;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: auto;
|
|
||||||
height: 100%;
|
|
||||||
background-color: $color-primary;
|
|
||||||
transition: all 500ms $ease-quart;
|
|
||||||
will-change: width, left;
|
|
||||||
|
|
||||||
span {
|
|
||||||
content: attr(data-text);
|
|
||||||
display: block;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
14
src/style/layout/_grid.scss
Normal file
14
src/style/layout/_grid.scss
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
/*
|
||||||
|
** Grid
|
||||||
|
*/
|
||||||
|
.grid {
|
||||||
|
--columns: #{$cols-m};
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(var(--columns), 1fr);
|
||||||
|
grid-column: 1 / span var(--columns);
|
||||||
|
align-items: start;
|
||||||
|
|
||||||
|
@include bp (sm) {
|
||||||
|
--columns: #{$cols-d};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
.explore {
|
|
||||||
// Description
|
|
||||||
&__description {
|
|
||||||
position: relative;
|
|
||||||
z-index: 3;
|
|
||||||
max-width: 312px;
|
|
||||||
margin: 0 auto 72px;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
max-width: 472px;
|
|
||||||
margin-bottom: 120px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Globe
|
|
||||||
// .globe {
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Browse
|
|
||||||
.browse {
|
|
||||||
position: relative;
|
|
||||||
z-index: 3;
|
|
||||||
margin-top: 72px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
// Main page
|
|
||||||
.housesof {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
transition: opacity 0.3s $ease-quart;
|
|
||||||
will-change: opacity;
|
|
||||||
|
|
||||||
&.is-transitioning {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
// Form
|
|
||||||
.form {
|
|
||||||
label {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Group item
|
|
||||||
// &__group {
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Input group
|
|
||||||
&__inputgroup {
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
button {
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
right: 10px;
|
|
||||||
transform: translateY(-50%);
|
|
||||||
width: 32px;
|
|
||||||
height: 32px;
|
|
||||||
padding: 0;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
right: 20px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hover
|
|
||||||
&:hover {
|
|
||||||
.input__text {
|
|
||||||
@extend %input__text--active;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Variants
|
|
||||||
*/
|
|
||||||
// Light version
|
|
||||||
&--light {
|
|
||||||
// Text input
|
|
||||||
.input__text {
|
|
||||||
&, &::placeholder {
|
|
||||||
color: $color-text;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,191 +0,0 @@
|
|||||||
// Globe
|
|
||||||
.globe {
|
|
||||||
position: relative;
|
|
||||||
z-index: 2;
|
|
||||||
width: 100vw;
|
|
||||||
height: 180vw;
|
|
||||||
min-height: 700px;
|
|
||||||
max-height: 1472px;
|
|
||||||
overflow: hidden;
|
|
||||||
cursor: grab;
|
|
||||||
user-select: none;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
height: 130vw;
|
|
||||||
}
|
|
||||||
@include breakpoint (md) {
|
|
||||||
height: 112vw;
|
|
||||||
}
|
|
||||||
@include breakpoint (xl) {
|
|
||||||
height: 100vw;
|
|
||||||
}
|
|
||||||
|
|
||||||
// DEBUG //
|
|
||||||
// background: rgba(red, 0.2);
|
|
||||||
// &:after {
|
|
||||||
// content: "";
|
|
||||||
// display: block;
|
|
||||||
// position: absolute;
|
|
||||||
// top: 50%;
|
|
||||||
// left: 0;
|
|
||||||
// background: blue;
|
|
||||||
// width: 100%;
|
|
||||||
// height: 2px;
|
|
||||||
// margin-top: -1px;
|
|
||||||
// }
|
|
||||||
// END DEBUG //
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Partial globe
|
|
||||||
*/
|
|
||||||
&--part {
|
|
||||||
overflow: hidden;
|
|
||||||
height: 30vw;
|
|
||||||
min-height: 300px;
|
|
||||||
max-height: 500px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Markers
|
|
||||||
*/
|
|
||||||
&__markers {
|
|
||||||
z-index: 210;
|
|
||||||
|
|
||||||
// When dragging
|
|
||||||
&.is-grabbing {
|
|
||||||
cursor: grabbing;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Marker
|
|
||||||
.marker {
|
|
||||||
position: absolute;
|
|
||||||
z-index: 2;
|
|
||||||
cursor: pointer;
|
|
||||||
display: block;
|
|
||||||
top: -4px;
|
|
||||||
left: -4px;
|
|
||||||
padding: 4px;
|
|
||||||
opacity: 1;
|
|
||||||
will-change: transform;
|
|
||||||
|
|
||||||
// Dot
|
|
||||||
&:before {
|
|
||||||
content: "";
|
|
||||||
display: block;
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 8px;
|
|
||||||
height: 8px;
|
|
||||||
background: $color-secondary;
|
|
||||||
border-radius: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
span {
|
|
||||||
transition: color 0.4s $ease-quart, opacity 0.3s $ease-inout;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hover glow effect
|
|
||||||
&.hover {
|
|
||||||
&:before {
|
|
||||||
animation: globeMarkerPulse 1s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Label
|
|
||||||
&__label {
|
|
||||||
position: absolute;
|
|
||||||
bottom: -16px;
|
|
||||||
left: 16px;
|
|
||||||
color: transparent;
|
|
||||||
}
|
|
||||||
// Location city
|
|
||||||
&__city {
|
|
||||||
font-family: $font-serif;
|
|
||||||
font-size: rem(18px);
|
|
||||||
line-height: 1;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
font-size: rem(24px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Location country
|
|
||||||
&__country {
|
|
||||||
display: block;
|
|
||||||
opacity: 0.8;
|
|
||||||
font-family: $font-sans;
|
|
||||||
font-size: rem(8px);
|
|
||||||
line-height: 1;
|
|
||||||
text-transform: uppercase;
|
|
||||||
letter-spacing: 1px;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
font-size: rem(10px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Active
|
|
||||||
&.is-active {
|
|
||||||
&, span {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
.marker {
|
|
||||||
&__city {
|
|
||||||
color: $color-secondary;
|
|
||||||
}
|
|
||||||
&__country {
|
|
||||||
color: $color-text;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Is light
|
|
||||||
&.is-light {
|
|
||||||
&.is-active {
|
|
||||||
.marker {
|
|
||||||
&__city {
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
&__country {
|
|
||||||
color: #d2b7e4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Left positioned
|
|
||||||
&.is-left {
|
|
||||||
.marker {
|
|
||||||
&__label {
|
|
||||||
left: auto;
|
|
||||||
right: 32px;
|
|
||||||
}
|
|
||||||
&__country {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Marker is close to another one
|
|
||||||
// Show the marker infos only on hover
|
|
||||||
&.is-close {
|
|
||||||
// Dot
|
|
||||||
&:before {
|
|
||||||
width: 7px;
|
|
||||||
height: 7px;
|
|
||||||
}
|
|
||||||
// Label
|
|
||||||
.marker__label {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show labels on hover
|
|
||||||
&:hover {
|
|
||||||
.marker__label {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
// Location
|
|
||||||
.location {
|
|
||||||
position: relative;
|
|
||||||
margin-bottom: 48px;
|
|
||||||
|
|
||||||
&, a * {
|
|
||||||
will-change: transform, opacity;
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
position: relative;
|
|
||||||
z-index: 2;
|
|
||||||
display: flex;
|
|
||||||
flex-flow: column;
|
|
||||||
align-items: center;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Flag image
|
|
||||||
img {
|
|
||||||
display: block;
|
|
||||||
width: 32px;
|
|
||||||
height: auto;
|
|
||||||
margin: 0 auto;
|
|
||||||
border-radius: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
// City
|
|
||||||
&__city {
|
|
||||||
font-family: $font-serif;
|
|
||||||
font-size: rem(32px);
|
|
||||||
color: $color-secondary;
|
|
||||||
|
|
||||||
@include breakpoint (md) {
|
|
||||||
font-size: rem(48px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Masks
|
|
||||||
.mask-city {
|
|
||||||
height: 40px;
|
|
||||||
margin: 16px 0 12px;
|
|
||||||
|
|
||||||
@include breakpoint (md) {
|
|
||||||
height: 64px;
|
|
||||||
margin-top: 24px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.mask-country {
|
|
||||||
height: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Badge
|
|
||||||
.badge {
|
|
||||||
margin-top: 16px;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
margin-top: 24px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hover
|
|
||||||
&:hover {
|
|
||||||
.location__city {
|
|
||||||
color: $color-tertiary;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:after {
|
|
||||||
opacity: 1;
|
|
||||||
transform: scale(1) translate(-50%, -50%);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Shape on hover
|
|
||||||
&:after {
|
|
||||||
content: "";
|
|
||||||
pointer-events: none;
|
|
||||||
opacity: 0;
|
|
||||||
position: absolute;
|
|
||||||
z-index: 1;
|
|
||||||
top: 50%;
|
|
||||||
left: 50%;
|
|
||||||
transform: scale(0.85) translate(-50%, -50%) translateZ(0);
|
|
||||||
transform-origin: 0 0;
|
|
||||||
display: block;
|
|
||||||
width: 184px;
|
|
||||||
height: 184px;
|
|
||||||
background: rgba($color-lightpurple, 0.3);
|
|
||||||
border-radius: 50%;
|
|
||||||
transition: transform 0.3s $ease-quart, opacity 0.3s $ease-quart;
|
|
||||||
will-change: transform;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
width: 216px;
|
|
||||||
height: 216px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,113 +0,0 @@
|
|||||||
// Newsletter
|
|
||||||
.newsletter {
|
|
||||||
background-color: $color-primary-dark;
|
|
||||||
padding: 56px 0;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
padding: 96px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.wrapper {
|
|
||||||
@include breakpoint (md) {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
color: $color-secondary;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Text
|
|
||||||
&__text {
|
|
||||||
max-width: 400px;
|
|
||||||
margin: 0 auto 32px;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
margin-bottom: 40px;
|
|
||||||
}
|
|
||||||
@include breakpoint (md) {
|
|
||||||
margin-left: 0;
|
|
||||||
margin-right: 48px;
|
|
||||||
margin-bottom: 0;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
margin-bottom: 16px;
|
|
||||||
|
|
||||||
@include breakpoint (md) {
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Form
|
|
||||||
.form {
|
|
||||||
min-width: 270px;
|
|
||||||
max-width: 320px;
|
|
||||||
margin: 0 auto;
|
|
||||||
|
|
||||||
@include breakpoint (md) {
|
|
||||||
min-width: 320px;
|
|
||||||
max-width: 440px;
|
|
||||||
margin: 48px 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Title (if existing)
|
|
||||||
h2 {
|
|
||||||
margin-bottom: 24px;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
margin-bottom: 40px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Notice
|
|
||||||
&__notice {
|
|
||||||
margin-top: 16px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Variants
|
|
||||||
*/
|
|
||||||
// Centered column mode
|
|
||||||
&--column {
|
|
||||||
max-width: 360px;
|
|
||||||
margin: 0 auto;
|
|
||||||
padding: 0;
|
|
||||||
background: none;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
max-width: 444px;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Text
|
|
||||||
.newsletter__text {
|
|
||||||
max-width: 440px;
|
|
||||||
margin: 0 0 48px;
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
margin-bottom: 72px;
|
|
||||||
}
|
|
||||||
@include breakpoint (md) {
|
|
||||||
margin-bottom: 96px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Light version
|
|
||||||
&--light {
|
|
||||||
background: none;
|
|
||||||
|
|
||||||
.newsletter__notice {
|
|
||||||
p {
|
|
||||||
color: rgba($color-text, 0.5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,188 +0,0 @@
|
|||||||
.photo {
|
|
||||||
/*
|
|
||||||
** Location
|
|
||||||
*/
|
|
||||||
&__location {
|
|
||||||
margin-bottom: 32px;
|
|
||||||
|
|
||||||
@media (max-width: $screen-md) {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
margin-bottom: 56px;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Street name
|
|
||||||
h2 {
|
|
||||||
text-align: left;
|
|
||||||
|
|
||||||
@include breakpoint (xs) {
|
|
||||||
font-size: rem(40px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.line {
|
|
||||||
overflow: hidden;
|
|
||||||
margin: -12px 0 -16px;
|
|
||||||
padding: 12px 0;
|
|
||||||
display: block;
|
|
||||||
|
|
||||||
span {
|
|
||||||
position: relative;
|
|
||||||
display: block;
|
|
||||||
will-change: transform;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
p {
|
|
||||||
color: $color-lightgray;
|
|
||||||
margin-top: 16px;
|
|
||||||
will-change: opacity;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Image
|
|
||||||
*/
|
|
||||||
&__image {
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-start;
|
|
||||||
|
|
||||||
@include breakpoint (xs) {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Alignment (left or right for list view)
|
|
||||||
.align {
|
|
||||||
position: relative;
|
|
||||||
width: 100%;
|
|
||||||
max-width: 1180px;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
|
|
||||||
@media (min-aspect-ratio: 16/8) {
|
|
||||||
max-width: 976px;
|
|
||||||
}
|
|
||||||
@media (min-aspect-ratio: 16/10) {
|
|
||||||
max-width: 1024px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Image itself
|
|
||||||
&__picture {
|
|
||||||
overflow: hidden;
|
|
||||||
position: relative;
|
|
||||||
z-index: 2;
|
|
||||||
display: block;
|
|
||||||
width: 100%;
|
|
||||||
border-radius: 0;
|
|
||||||
background-color: #fff;
|
|
||||||
box-shadow: 0 8px 18px rgba(#715E4E, 0.2);
|
|
||||||
user-select: none;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
border-radius: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
display: block;
|
|
||||||
width: 100%;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
img {
|
|
||||||
display: block;
|
|
||||||
width: 100%;
|
|
||||||
height: auto;
|
|
||||||
will-change: transform, opacity;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Overlay
|
|
||||||
&:after {
|
|
||||||
opacity: 0;
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
z-index: 3;
|
|
||||||
display: block;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
bottom: 0;
|
|
||||||
right: 0;
|
|
||||||
background-color: $color-primary;
|
|
||||||
pointer-events: none;
|
|
||||||
transition: opacity 150ms $ease-inout;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hover
|
|
||||||
&:hover {
|
|
||||||
cursor: zoom-in;
|
|
||||||
|
|
||||||
&:after {
|
|
||||||
opacity: 0.6;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Date (on the side)
|
|
||||||
&__date {
|
|
||||||
display: block;
|
|
||||||
margin-top: 16px;
|
|
||||||
padding: 0 pxVW(128);
|
|
||||||
font-size: rem(14px);
|
|
||||||
color: $color-lightgray;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
position: absolute;
|
|
||||||
z-index: 3;
|
|
||||||
left: calc(100% + 30px);
|
|
||||||
bottom: 0;
|
|
||||||
transform: rotate(270deg);
|
|
||||||
transform-origin: 0 0;
|
|
||||||
white-space: nowrap;
|
|
||||||
line-height: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Photo number
|
|
||||||
&__number {
|
|
||||||
position: absolute;
|
|
||||||
bottom: -80px;
|
|
||||||
right: 24px;
|
|
||||||
font-family: $font-serif-extra;
|
|
||||||
color: rgba($color-tertiary, 0.5);
|
|
||||||
font-size: rem(124px);
|
|
||||||
pointer-events: none;
|
|
||||||
user-select: none;
|
|
||||||
|
|
||||||
span {
|
|
||||||
position: relative;
|
|
||||||
display: block;
|
|
||||||
will-change: transform;
|
|
||||||
}
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
z-index: 1;
|
|
||||||
top: 0;
|
|
||||||
right: 8%;
|
|
||||||
transform: translate(0, -25%);
|
|
||||||
font-size: pxVW(300);
|
|
||||||
}
|
|
||||||
@include breakpoint (md) {
|
|
||||||
top: 50%;
|
|
||||||
right: 0;
|
|
||||||
bottom: auto;
|
|
||||||
transform: translate(26.5vw, -50%);
|
|
||||||
width: 50%;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
@include breakpoint (lg) {
|
|
||||||
transform: translate(28vw, -50%);
|
|
||||||
}
|
|
||||||
@include breakpoint (xxl) {
|
|
||||||
font-size: rem(300px);
|
|
||||||
transform: translate(70%, -50%);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,352 +0,0 @@
|
|||||||
// Carousel
|
|
||||||
.carousel {
|
|
||||||
background-color: $color-primary;
|
|
||||||
will-change: transform, opacity;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
overflow: visible;
|
|
||||||
}
|
|
||||||
|
|
||||||
.wrap {
|
|
||||||
max-width: 1280px;
|
|
||||||
padding: 0;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
max-width: 80%;
|
|
||||||
}
|
|
||||||
@include breakpoint (1680px) {
|
|
||||||
max-width: 1424px;
|
|
||||||
}
|
|
||||||
@media (min-aspect-ratio: 16/10) {
|
|
||||||
max-width: 70%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Gallery
|
|
||||||
*/
|
|
||||||
.gallery {
|
|
||||||
position: relative;
|
|
||||||
z-index: 2;
|
|
||||||
margin: 0 auto;
|
|
||||||
cursor: grab;
|
|
||||||
|
|
||||||
&:active {
|
|
||||||
cursor: grabbing;
|
|
||||||
}
|
|
||||||
|
|
||||||
@include breakpoint (xl) {
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Variables
|
|
||||||
$scale: 0.9;
|
|
||||||
$angle: 1deg;
|
|
||||||
$angleHover: 1.25deg;
|
|
||||||
$distance: 9%;
|
|
||||||
$distanceHover: 10%;
|
|
||||||
$radius: 8px;
|
|
||||||
|
|
||||||
// Images
|
|
||||||
&__images {
|
|
||||||
position: relative;
|
|
||||||
height: 0;
|
|
||||||
padding-bottom: calc(100% / 1.5); // Ratio 3.2
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Photo
|
|
||||||
&__photo {
|
|
||||||
$duration: 1s;
|
|
||||||
opacity: 0;
|
|
||||||
position: absolute;
|
|
||||||
z-index: -1;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
transform: scale($scale) translateZ(0);
|
|
||||||
transition: transform $duration $ease-quart, opacity ($duration / 2) $ease-quart;
|
|
||||||
pointer-events: none;
|
|
||||||
@extend %willchange;
|
|
||||||
|
|
||||||
// Visible photos
|
|
||||||
&.is-active, &.is-prev, &.is-next {
|
|
||||||
opacity: 1;
|
|
||||||
pointer-events: auto;
|
|
||||||
|
|
||||||
picture {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Active photo
|
|
||||||
&.is-active {
|
|
||||||
z-index: 10;
|
|
||||||
transform: scale(1) translateZ(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Previous & next photo
|
|
||||||
&.is-prev, &.is-next {
|
|
||||||
picture:before {
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
opacity: 0.4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Previous photo
|
|
||||||
&.is-prev {
|
|
||||||
z-index: 9;
|
|
||||||
transform: translate(-40%, 0) scale(0.85) translateZ(0);
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
z-index: 8;
|
|
||||||
transform: translate(-$distance, -1%) rotate(-$angle) scale($scale) translateZ(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hover
|
|
||||||
&.hover {
|
|
||||||
transform: translate(-$distanceHover, -1%) rotate(-$angleHover) scale($scale) translateZ(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Next photo
|
|
||||||
&.is-next {
|
|
||||||
z-index: 8;
|
|
||||||
transform: translate(40%, 0) scale(0.85) translateZ(0);
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
z-index: 9;
|
|
||||||
transform: translate($distance, -1%) rotate($angle) scale($scale) translateZ(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hover
|
|
||||||
&.hover {
|
|
||||||
transform: translate($distanceHover, -1%) rotate($angleHover) scale($scale) translateZ(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Picture
|
|
||||||
&__picture {
|
|
||||||
opacity: 0;
|
|
||||||
position: relative;
|
|
||||||
display: block;
|
|
||||||
overflow: hidden;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
box-shadow: 0 pxVW(15) pxVW(60) rgba(#000, 0.3);
|
|
||||||
transition: opacity 1s $ease-quart;
|
|
||||||
will-change: opacity;
|
|
||||||
@extend %willchange;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
border-radius: $radius;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Overlay
|
|
||||||
&:before {
|
|
||||||
opacity: 0;
|
|
||||||
content: "";
|
|
||||||
display: block;
|
|
||||||
position: absolute;
|
|
||||||
z-index: 2;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
background-color: $color-primary;
|
|
||||||
}
|
|
||||||
|
|
||||||
img {
|
|
||||||
position: relative;
|
|
||||||
z-index: 1;
|
|
||||||
display: block;
|
|
||||||
width: 100%;
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Performance
|
|
||||||
%willchange {
|
|
||||||
will-change: transform, opacity;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Controls (arrows)
|
|
||||||
*/
|
|
||||||
&__controls {
|
|
||||||
display: none;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
position: absolute;
|
|
||||||
z-index: 11;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
|
||||||
box-shadow: 0 2px 20px rgba(#000, 0.15);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hover and clicking area
|
|
||||||
&__area {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
width: 12%;
|
|
||||||
height: 100%;
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
&--prev {
|
|
||||||
margin-left: -6%;
|
|
||||||
}
|
|
||||||
&--next {
|
|
||||||
margin-right: -6%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Informations
|
|
||||||
*/
|
|
||||||
&__infos {
|
|
||||||
position: relative;
|
|
||||||
z-index: 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Locations
|
|
||||||
&__locations {
|
|
||||||
position: relative;
|
|
||||||
min-height: 80px;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
min-height: 128px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Location
|
|
||||||
&__location {
|
|
||||||
$distance: 40%;
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
opacity: 0;
|
|
||||||
margin-top: 32px;
|
|
||||||
padding-bottom: 4px;
|
|
||||||
text-align: center;
|
|
||||||
pointer-events: none;
|
|
||||||
transition: transform 0.9s $ease-quart, opacity 0.9s $ease-quart;
|
|
||||||
will-change: transform, opacity;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
margin-top: pxVW(80);
|
|
||||||
}
|
|
||||||
@include breakpoint (xl) {
|
|
||||||
margin-top: 72px;
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: rgba($color-tertiary, 0.5);
|
|
||||||
text-decoration: none;
|
|
||||||
transition: color 150ms $ease-inout;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: rgba($color-tertiary, 0.8);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// State
|
|
||||||
.state {
|
|
||||||
margin-top: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
// States
|
|
||||||
&.is-prev {
|
|
||||||
transform: translateY(-$distance) translateZ(0);
|
|
||||||
}
|
|
||||||
&.is-active {
|
|
||||||
transform: translateY(0) translateZ(0);
|
|
||||||
opacity: 1;
|
|
||||||
pointer-events: auto;
|
|
||||||
}
|
|
||||||
&.is-next {
|
|
||||||
transform: translateY($distance) translateZ(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Dots for slider (mobile)
|
|
||||||
*/
|
|
||||||
&__dots {
|
|
||||||
display: none;
|
|
||||||
position: relative;
|
|
||||||
z-index: 3;
|
|
||||||
|
|
||||||
@include breakpoint (xs) {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
margin-top: 32px;
|
|
||||||
|
|
||||||
li {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
padding: 4px;
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
&, button {
|
|
||||||
transition: all 0.6s $ease-quart;
|
|
||||||
will-change: transform, width, height, padding;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Active
|
|
||||||
&.active button {
|
|
||||||
background-color: $color-secondary;
|
|
||||||
transform: scale(1.25) translateZ(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Small dot
|
|
||||||
&.small button {
|
|
||||||
transform: scale(0.6) translateZ(0);
|
|
||||||
opacity: 0.5;
|
|
||||||
}
|
|
||||||
// Hidden
|
|
||||||
&.hidden {
|
|
||||||
padding: 0;
|
|
||||||
transform: scale(0) translateZ(0);
|
|
||||||
opacity: 0;
|
|
||||||
width: 0;
|
|
||||||
height: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hover
|
|
||||||
&:hover:not(.active) {
|
|
||||||
button {
|
|
||||||
background-color: lighten($color-lightpurple, 10);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
|
||||||
display: block;
|
|
||||||
width: 8px;
|
|
||||||
height: 8px;
|
|
||||||
padding: 0;
|
|
||||||
background-color: $color-lightpurple;
|
|
||||||
border-radius: 50%;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,132 +0,0 @@
|
|||||||
/* ==========================================================================
|
|
||||||
FOOTER
|
|
||||||
========================================================================== */
|
|
||||||
.footer {
|
|
||||||
background-color: $color-primary-darker;
|
|
||||||
|
|
||||||
.wrap {
|
|
||||||
display: block;
|
|
||||||
padding-top: 48px;
|
|
||||||
padding-bottom: 32px;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
height: 120px;
|
|
||||||
padding-top: 0;
|
|
||||||
padding-bottom: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Left part
|
|
||||||
&__left {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
margin-bottom: 40px;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Right part
|
|
||||||
&__right {
|
|
||||||
font-size: 14px;
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
& > ul {
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
padding-top: 6px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
li {
|
|
||||||
display: block;
|
|
||||||
text-align: center;
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
& > ul {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
margin-bottom: 32px;
|
|
||||||
margin-top: 3px;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
margin-bottom: 0;
|
|
||||||
margin-right: 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
li {
|
|
||||||
margin-right: 20px;
|
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
margin-right: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
a {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
position: relative;
|
|
||||||
color: #fff;
|
|
||||||
text-decoration: none;
|
|
||||||
transition: color 85ms $ease-inout;
|
|
||||||
|
|
||||||
img, svg {
|
|
||||||
margin-right: 8px;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
margin-right: 16px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hover
|
|
||||||
&:hover, &.is-active {
|
|
||||||
color: $color-secondary;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Instagram
|
|
||||||
.instagram {
|
|
||||||
a {
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
svg {
|
|
||||||
display: block;
|
|
||||||
transition: fill 275ms $ease-cubic;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hover
|
|
||||||
a:hover svg {
|
|
||||||
fill: $color-secondary;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Made by
|
|
||||||
.by {
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
img {
|
|
||||||
display: block;
|
|
||||||
height: 22px;
|
|
||||||
width: auto;
|
|
||||||
margin: 0 auto;
|
|
||||||
transition: transform 400ms $ease-quart;
|
|
||||||
will-change: transform;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hover
|
|
||||||
a:hover img {
|
|
||||||
transform: scale(1.05);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,87 +0,0 @@
|
|||||||
.fullscreen {
|
|
||||||
position: fixed;
|
|
||||||
z-index: 200;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
overflow: hidden;
|
|
||||||
pointer-events: none;
|
|
||||||
user-select: none;
|
|
||||||
|
|
||||||
&, * {
|
|
||||||
will-change: transform, opacity;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Photo
|
|
||||||
&__image {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
overflow-x: auto;
|
|
||||||
opacity: 0;
|
|
||||||
transform: scale(1.1);
|
|
||||||
background: $color-primary;
|
|
||||||
transition: transform 0.8s $ease-quart, opacity 0.8s $ease-quart;
|
|
||||||
|
|
||||||
img {
|
|
||||||
position: relative;
|
|
||||||
z-index: 200;
|
|
||||||
display: block;
|
|
||||||
height: 100%;
|
|
||||||
width: auto;
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Open
|
|
||||||
&.is-open {
|
|
||||||
opacity: 1;
|
|
||||||
transform: scale(1);
|
|
||||||
pointer-events: auto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Controls
|
|
||||||
&__close {
|
|
||||||
position: fixed;
|
|
||||||
z-index: 201;
|
|
||||||
bottom: 24px;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
opacity: 0;
|
|
||||||
transform: scale(1.1) translateY(24px) translateZ(0);
|
|
||||||
transition: transform 0.8s $ease-quart, opacity 0.8s $ease-quart;
|
|
||||||
|
|
||||||
// Visible state
|
|
||||||
&.is-visible {
|
|
||||||
opacity: 1;
|
|
||||||
transform: scale(1) translateY(0) translateZ(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Loading
|
|
||||||
&__loading {
|
|
||||||
position: absolute;
|
|
||||||
z-index: 202;
|
|
||||||
top: 50%;
|
|
||||||
left: 50%;
|
|
||||||
opacity: 1;
|
|
||||||
transform: translate(-50%, -50%) translateZ(0);
|
|
||||||
transform-origin: 50% 50%;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
width: 80px;
|
|
||||||
height: 80px;
|
|
||||||
background-color: $color-primary;
|
|
||||||
border-radius: 50%;
|
|
||||||
transition: transform 0.8s $ease-quart, opacity 0.8s $ease-quart;
|
|
||||||
|
|
||||||
// Hidden state
|
|
||||||
&.is-hidden {
|
|
||||||
transform: scale(1.05) translate(-50%, -50%) translateZ(0);
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
.browse {
|
|
||||||
width: 100%;
|
|
||||||
overflow: hidden;
|
|
||||||
margin-bottom: 56px;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
margin-top: 120px;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Description
|
|
||||||
&__description {
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
margin-bottom: 32px;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
margin-bottom: 40px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Continents
|
|
||||||
&__continents {
|
|
||||||
display: flex;
|
|
||||||
flex-flow: row wrap;
|
|
||||||
justify-content: center;
|
|
||||||
margin-bottom: 8px;
|
|
||||||
|
|
||||||
li {
|
|
||||||
display: block;
|
|
||||||
margin: 0 4px;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
margin: 0 8px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Locations
|
|
||||||
&__locations {
|
|
||||||
min-height: 120px;
|
|
||||||
margin-top: 72px;
|
|
||||||
|
|
||||||
@include breakpoint (600px) {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(2, 1fr);
|
|
||||||
}
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
grid-template-columns: repeat(3, 1fr);
|
|
||||||
grid-column-gap: pxVW(96);
|
|
||||||
grid-row-gap: pxVW(96);
|
|
||||||
min-height: 200px;
|
|
||||||
margin-top: 112px;
|
|
||||||
margin-bottom: pxVW(72);
|
|
||||||
}
|
|
||||||
@include breakpoint (xl) {
|
|
||||||
grid-column-gap: 96px;
|
|
||||||
grid-row-gap: 96px;
|
|
||||||
// max-width: 1024px;
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
margin-bottom: 72px;
|
|
||||||
|
|
||||||
// To apply when having 4 locations:
|
|
||||||
grid-template-columns: repeat(4, 1fr);
|
|
||||||
max-width: 1200px;
|
|
||||||
// grid-column-gap: 120px;
|
|
||||||
// grid-row-gap: 120px;
|
|
||||||
// Works well but fucks with the FLIP animations
|
|
||||||
// grid-auto-flow: column;
|
|
||||||
// grid-template-columns: repeat(auto-fit, minmax(min-content, 1fr));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,121 +0,0 @@
|
|||||||
// Pagination
|
|
||||||
.pagination {
|
|
||||||
position: relative;
|
|
||||||
padding: 64px 0 72px;
|
|
||||||
background-color: $color-tertiary;
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
padding-top: pxVW(120);
|
|
||||||
padding-bottom: pxVW(120);
|
|
||||||
}
|
|
||||||
@include breakpoint (xl) {
|
|
||||||
padding-top: 120px;
|
|
||||||
padding-bottom: 120px;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pages
|
|
||||||
&__page {
|
|
||||||
position: relative;
|
|
||||||
display: inline-flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
margin: 0 auto;
|
|
||||||
font-family: $font-serif-extra;
|
|
||||||
font-size: rem(72px);
|
|
||||||
color: rgba($color-text, 0.15);
|
|
||||||
line-height: 1;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: color 250ms $ease-cubic;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
font-size: rem(120px);
|
|
||||||
}
|
|
||||||
@include breakpoint (md) {
|
|
||||||
font-size: rem(160px);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hover
|
|
||||||
&:hover {
|
|
||||||
color: rgba($color-text, 0.25);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Numbers
|
|
||||||
&__numbers {
|
|
||||||
overflow: hidden;
|
|
||||||
height: 62px;
|
|
||||||
margin-right: 4px;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
height: 102px;
|
|
||||||
}
|
|
||||||
@include breakpoint (md) {
|
|
||||||
height: 136px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scroll {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
transform: translate(0, 0) translateZ(0);
|
|
||||||
text-align: right;
|
|
||||||
line-height: 0.85;
|
|
||||||
transition: transform 325ms $ease-cubic;
|
|
||||||
will-change: transform;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Info
|
|
||||||
&__info {
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
left: 50%;
|
|
||||||
transform: translate(-50%, -72%) translateZ(0);
|
|
||||||
font-family: $font-serif;
|
|
||||||
font-size: rem(18px);
|
|
||||||
color: $color-secondary-bright;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
font-size: rem(32px);
|
|
||||||
}
|
|
||||||
@include breakpoint (md) {
|
|
||||||
font-size: rem(40px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Caption
|
|
||||||
&__caption {
|
|
||||||
max-width: 420px;
|
|
||||||
margin: 0 auto;
|
|
||||||
font-size: 10px;
|
|
||||||
color: $color-lightgray;
|
|
||||||
letter-spacing: 2px;
|
|
||||||
line-height: 1.6;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Message
|
|
||||||
&__message {
|
|
||||||
// Newsletter
|
|
||||||
.newsletter {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
padding: 24px 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Title
|
|
||||||
h2 {
|
|
||||||
font-size: rem(32px);
|
|
||||||
|
|
||||||
@include breakpoint (md) {
|
|
||||||
font-size: rem(40px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,248 +0,0 @@
|
|||||||
.photos {
|
|
||||||
position: relative;
|
|
||||||
margin-top: -22px;
|
|
||||||
background-color: #fff;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
margin-top: -128px;
|
|
||||||
padding-top: 88px;
|
|
||||||
}
|
|
||||||
@include breakpoint (xl) {
|
|
||||||
padding-top: 72px;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sidebar
|
|
||||||
&__side {
|
|
||||||
display: none;
|
|
||||||
|
|
||||||
@include breakpoint (md) {
|
|
||||||
display: flex;
|
|
||||||
position: absolute;
|
|
||||||
z-index: 5;
|
|
||||||
left: 24px;
|
|
||||||
flex-direction: row-reverse;
|
|
||||||
align-items: flex-end;
|
|
||||||
transform-origin: left top;
|
|
||||||
transform: rotate(-90deg) translateX(-100%);
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
font-size: rem(12px);
|
|
||||||
color: $color-lightgray;
|
|
||||||
margin-right: 24px;
|
|
||||||
|
|
||||||
strong {
|
|
||||||
font-weight: 600;
|
|
||||||
display: block;
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Container
|
|
||||||
&__sidewrap {
|
|
||||||
@include breakpoint (md) {
|
|
||||||
position: sticky;
|
|
||||||
z-index: 10;
|
|
||||||
top: 32px;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Each photo
|
|
||||||
.photo {
|
|
||||||
position: relative;
|
|
||||||
z-index: 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** List view
|
|
||||||
*/
|
|
||||||
&--list {
|
|
||||||
.photos__view {
|
|
||||||
max-width: 100%;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Photo
|
|
||||||
.photo {
|
|
||||||
padding-bottom: 80px;
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
padding-bottom: 120px;
|
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
padding-bottom: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Title
|
|
||||||
h2 {
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
max-width: 840px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Even photos
|
|
||||||
&:nth-child(even) {
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
// Location
|
|
||||||
.photo__location, h2 {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
h2 {
|
|
||||||
margin-left: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Image
|
|
||||||
.photo {
|
|
||||||
&__image {
|
|
||||||
justify-content: flex-end;
|
|
||||||
}
|
|
||||||
&__date {
|
|
||||||
right: 100%;
|
|
||||||
left: -30px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Number
|
|
||||||
.photo__number {
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
right: auto;
|
|
||||||
left: 8%;
|
|
||||||
}
|
|
||||||
@include breakpoint (md) {
|
|
||||||
right: auto;
|
|
||||||
left: 0;
|
|
||||||
transform: translate(-23vw, -50%);
|
|
||||||
}
|
|
||||||
@include breakpoint (lg) {
|
|
||||||
transform: translate(-26vw, -50%);
|
|
||||||
}
|
|
||||||
@include breakpoint (xl) {
|
|
||||||
transform: translate(-66%, -50%);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Number
|
|
||||||
&__number {
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
will-change: transform;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pagination
|
|
||||||
.pagination {
|
|
||||||
margin-top: 24px;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
margin-top: -64px;
|
|
||||||
padding-top: pxVW(240);
|
|
||||||
padding-bottom: pxVW(120);
|
|
||||||
}
|
|
||||||
@include breakpoint (md) {
|
|
||||||
padding-top: pxVW(200);
|
|
||||||
}
|
|
||||||
@include breakpoint (xl) {
|
|
||||||
padding-top: 200px;
|
|
||||||
padding-bottom: 120px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Grid view
|
|
||||||
*/
|
|
||||||
&--grid {
|
|
||||||
.photos__view {
|
|
||||||
@include breakpoint (md) {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(2, 1fr);
|
|
||||||
grid-column-gap: 48px;
|
|
||||||
grid-row-gap: 72px;
|
|
||||||
padding-left: 192px;
|
|
||||||
padding-right: 64px;
|
|
||||||
}
|
|
||||||
@include breakpoint (xxl) {
|
|
||||||
padding-left: 192px;
|
|
||||||
}
|
|
||||||
@include breakpoint (1776px) {
|
|
||||||
padding-right: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Photo
|
|
||||||
.photo {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column-reverse;
|
|
||||||
margin-bottom: 40px;
|
|
||||||
|
|
||||||
@include breakpoint (mob) {
|
|
||||||
margin-bottom: pxVW(176);
|
|
||||||
}
|
|
||||||
@include breakpoint (md) {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Every second (on column 2)
|
|
||||||
&--odd {
|
|
||||||
@include breakpoint (md) {
|
|
||||||
transform: translateY(-64px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.wrap, .wrapper {
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Location
|
|
||||||
&__location {
|
|
||||||
text-align: left;
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
font-size: rem(28px);
|
|
||||||
margin-top: 24px;
|
|
||||||
white-space: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
font-size: rem(12px);
|
|
||||||
margin-top: 8px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Image informations
|
|
||||||
&__img {
|
|
||||||
border-radius: 8px;
|
|
||||||
}
|
|
||||||
&__number {
|
|
||||||
font-size: rem(96px);
|
|
||||||
bottom: -88px;
|
|
||||||
right: 24px;
|
|
||||||
z-index: 1;
|
|
||||||
transform: none;
|
|
||||||
top: auto;
|
|
||||||
left: auto;
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
&__date {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pagination
|
|
||||||
.pagination {
|
|
||||||
margin-top: 64px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,138 +0,0 @@
|
|||||||
// Introduction
|
|
||||||
.intro {
|
|
||||||
background-color: $color-tertiary;
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
// Title
|
|
||||||
.title-parallax {
|
|
||||||
margin-top: -#{pxVW(160)};
|
|
||||||
margin-left: -#{pxVW(160)};
|
|
||||||
|
|
||||||
@include breakpoint (1920px) {
|
|
||||||
margin-top: -160px;
|
|
||||||
margin-left: auto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Description
|
|
||||||
&__description {
|
|
||||||
margin-top: 14vw;
|
|
||||||
margin-bottom: 72px;
|
|
||||||
padding: 0 32px;
|
|
||||||
color: $color-text;
|
|
||||||
|
|
||||||
@include breakpoint (600px) {
|
|
||||||
margin-top: 72px;
|
|
||||||
}
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
margin-bottom: 120px;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
margin-bottom: 40px;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
margin-bottom: 72px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Carousel
|
|
||||||
.carousel {
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
// Beige background under
|
|
||||||
&:after {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
z-index: 0;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
display: block;
|
|
||||||
width: 100%;
|
|
||||||
height: pxVW(768);
|
|
||||||
background-color: $color-tertiary;
|
|
||||||
|
|
||||||
@include breakpoint (xxl) {
|
|
||||||
height: 820px;
|
|
||||||
}
|
|
||||||
@media (min-aspect-ratio: 16/10) {
|
|
||||||
height: 36vw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Photos
|
|
||||||
.gallery__picture:before {
|
|
||||||
background-color: $color-secondary;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Explore
|
|
||||||
.explore--homepage {
|
|
||||||
margin-top: pxVW(248);
|
|
||||||
|
|
||||||
@include breakpoint (lg) {
|
|
||||||
margin-top: 248px;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Description
|
|
||||||
.style-description {
|
|
||||||
color: $color-tertiary;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Globe
|
|
||||||
// .globe {
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Browse
|
|
||||||
.browse {
|
|
||||||
margin-top: 4vw;
|
|
||||||
|
|
||||||
@include breakpoint (xl) {
|
|
||||||
margin-top: 72px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Of text
|
|
||||||
.of {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
margin-bottom: pxVW(224);
|
|
||||||
font-family: $font-serif-extra;
|
|
||||||
font-size: pxVW(248);
|
|
||||||
line-height: 1;
|
|
||||||
color: $color-lightpurple;
|
|
||||||
text-transform: uppercase;
|
|
||||||
user-select: none;
|
|
||||||
pointer-events: none;
|
|
||||||
|
|
||||||
@include breakpoint (lg) {
|
|
||||||
margin-bottom: 200px;
|
|
||||||
font-size: rem(248px);
|
|
||||||
}
|
|
||||||
|
|
||||||
span {
|
|
||||||
will-change: transform;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Massive title
|
|
||||||
.anim-title {
|
|
||||||
margin-top: -#{pxVW(224)};
|
|
||||||
margin-left: -60px;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
margin-top: -184px;
|
|
||||||
}
|
|
||||||
|
|
||||||
span:nth-of-type(1) {
|
|
||||||
letter-spacing: -6vw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,106 +0,0 @@
|
|||||||
.page {
|
|
||||||
overflow-x: hidden;
|
|
||||||
min-height: 100vh;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: space-between;
|
|
||||||
|
|
||||||
// Page part
|
|
||||||
&__part {
|
|
||||||
will-change: transform, opacity;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Top part
|
|
||||||
&__top {
|
|
||||||
margin-top: 96px;
|
|
||||||
margin-bottom: 56px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
margin-top: 120px;
|
|
||||||
margin-bottom: 96px;
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
position: absolute;
|
|
||||||
top: -64px;
|
|
||||||
|
|
||||||
@include breakpoint (sm){
|
|
||||||
top: 50%;
|
|
||||||
left: 0;
|
|
||||||
transform: translateY(-50%);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Description
|
|
||||||
&__description {
|
|
||||||
max-width: 312px;
|
|
||||||
margin: 0 auto;
|
|
||||||
margin-bottom: 72px;
|
|
||||||
color: $color-tertiary;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
max-width: 472px;
|
|
||||||
margin-bottom: 120px;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Some margins
|
|
||||||
h1 + p {
|
|
||||||
margin-top: 24px;
|
|
||||||
}
|
|
||||||
p + .button {
|
|
||||||
margin-top: 40px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Category
|
|
||||||
&__category {
|
|
||||||
margin-bottom: 96px;
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
margin-bottom: 56px;
|
|
||||||
}
|
|
||||||
dl {
|
|
||||||
margin-bottom: 40px;
|
|
||||||
}
|
|
||||||
dt {
|
|
||||||
margin-bottom: 4px;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
margin-bottom: 8px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dd {
|
|
||||||
width: 65%;
|
|
||||||
max-width: 560px;
|
|
||||||
min-width: 232px;
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Globe
|
|
||||||
.globe--part {
|
|
||||||
margin-top: 72px;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
margin-top: 136px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Credit page
|
|
||||||
*/
|
|
||||||
&--credits {
|
|
||||||
z-index: 120;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,200 +0,0 @@
|
|||||||
// Place section
|
|
||||||
.place {
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
// Title
|
|
||||||
&__title {
|
|
||||||
position: relative;
|
|
||||||
z-index: 2;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
max-height: 768px;
|
|
||||||
padding: pxVW(350) 0 pxVW(200);
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
@media screen and (orientation: portrait) and (max-width: $screen-xs) {
|
|
||||||
height: 144vw;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: flex-end;
|
|
||||||
padding: pxVW(240) 0 pxVW(288); // 528
|
|
||||||
height: auto;
|
|
||||||
max-height: none;
|
|
||||||
}
|
|
||||||
@include breakpoint (xxl) {
|
|
||||||
padding-top: 240px;
|
|
||||||
padding-bottom: 280px;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
--offset: #{pxVW(72)};
|
|
||||||
position: relative;
|
|
||||||
z-index: 2;
|
|
||||||
display: inline-block;
|
|
||||||
text-align: center;
|
|
||||||
padding-left: 3vw;
|
|
||||||
pointer-events: none;
|
|
||||||
|
|
||||||
.anim-translate {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
@include breakpoint (xl) {
|
|
||||||
--offset: 72px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&_top {
|
|
||||||
margin-left: calc(-1 * var(--offset));
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
&_bottom {
|
|
||||||
text-align: right;
|
|
||||||
margin-left: var(--offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Switcher button
|
|
||||||
.button-control {
|
|
||||||
z-index: 1;
|
|
||||||
margin: 32px auto 0;
|
|
||||||
flex-shrink: 0;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
margin-left: -24px;
|
|
||||||
margin-right: 0;
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Description
|
|
||||||
&__description {
|
|
||||||
position: relative;
|
|
||||||
z-index: 2;
|
|
||||||
padding-top: pxVW(200);
|
|
||||||
padding-bottom: 72px;
|
|
||||||
background-color: $color-tertiary;
|
|
||||||
will-change: transform, opacity;
|
|
||||||
|
|
||||||
@include breakpoint (mob) {
|
|
||||||
padding-bottom: 96px;
|
|
||||||
}
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
padding-bottom: pxVW(240);
|
|
||||||
}
|
|
||||||
@include breakpoint (md) {
|
|
||||||
border-radius: 8px 0 0 8px;
|
|
||||||
}
|
|
||||||
@include breakpoint (xxl) {
|
|
||||||
padding-top: 200px;
|
|
||||||
padding-bottom: 240px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.wrapper {
|
|
||||||
margin: 0;
|
|
||||||
max-width: 1280px;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
font-size: rem(18px);
|
|
||||||
font-family: $font-sans-light;
|
|
||||||
line-height: 1.64;
|
|
||||||
color: $color-text;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
font-size: rem(22px);
|
|
||||||
}
|
|
||||||
@include breakpoint (lg) {
|
|
||||||
font-size: 1rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Updated notice
|
|
||||||
.updated {
|
|
||||||
font-size: rem(12px);
|
|
||||||
margin-top: 32px;
|
|
||||||
|
|
||||||
strong {
|
|
||||||
font-family: $font-sans-sb;
|
|
||||||
color: rgba($color-text, 0.4);
|
|
||||||
}
|
|
||||||
|
|
||||||
@include breakpoint (md) {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Toggle
|
|
||||||
.toggle {
|
|
||||||
display: none;
|
|
||||||
|
|
||||||
@include breakpoint (md) {
|
|
||||||
display: inline-flex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Right side background completion
|
|
||||||
&:after {
|
|
||||||
content: "";
|
|
||||||
display: block;
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
right: -49.9vw;
|
|
||||||
width: 50vw;
|
|
||||||
height: 100%;
|
|
||||||
background-color: $color-tertiary;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wrap
|
|
||||||
&__wrap {
|
|
||||||
padding: 0;
|
|
||||||
|
|
||||||
@include breakpoint (md) {
|
|
||||||
padding-left: 128px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Background illustration
|
|
||||||
&__illustration {
|
|
||||||
position: absolute;
|
|
||||||
z-index: 0;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
will-change: transform, opacity;
|
|
||||||
|
|
||||||
.parallax {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
max-width: 1760px;
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
&_img {
|
|
||||||
position: relative;
|
|
||||||
left: 50%;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
transform: translateX(-50%);
|
|
||||||
transform-origin: 0 0;
|
|
||||||
background-image: var(--url-mobile);
|
|
||||||
background-position: 0 0;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-size: 100% auto;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
background-image: var(--url-desktop);
|
|
||||||
}
|
|
||||||
@media (min-width: $screen-sm) and (-webkit-min-device-pixel-ratio: 2),
|
|
||||||
(min-width: $screen-sm) and (min-resolution: 192dpi) {
|
|
||||||
background-image: var(--url-desktop-2x);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,182 +0,0 @@
|
|||||||
// Viewer
|
|
||||||
.viewer {
|
|
||||||
position: relative;
|
|
||||||
height: 100vh;
|
|
||||||
min-height: 560px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: space-between;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
width: 100%;
|
|
||||||
padding-top: 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Top part
|
|
||||||
*/
|
|
||||||
&__top {
|
|
||||||
position: relative;
|
|
||||||
z-index: 10;
|
|
||||||
margin-top: 16px;
|
|
||||||
padding-left: 24px;
|
|
||||||
padding-right: 16px;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
flex-flow: row wrap;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
justify-content: center;
|
|
||||||
margin-bottom: 24px;
|
|
||||||
}
|
|
||||||
@include breakpoint (lg) {
|
|
||||||
margin-top: 24px;
|
|
||||||
margin-bottom: 48px;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tip message
|
|
||||||
.tip {
|
|
||||||
font-family: $font-sans-sb;
|
|
||||||
font-size: rem(10px);
|
|
||||||
text-transform: uppercase;
|
|
||||||
color: rgba($color-tertiary, 0.4);
|
|
||||||
letter-spacing: 1px;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Buttons
|
|
||||||
&__buttons {
|
|
||||||
display: flex;
|
|
||||||
|
|
||||||
a {
|
|
||||||
margin-left: 16px;
|
|
||||||
|
|
||||||
&:first-child {
|
|
||||||
margin-left: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Carousel
|
|
||||||
*/
|
|
||||||
.carousel {
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
@include breakpoint (xs) {
|
|
||||||
margin-top: 20%;
|
|
||||||
}
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
margin: auto;
|
|
||||||
}
|
|
||||||
// Landscape
|
|
||||||
@media screen and (min-width: $screen-sm) and (max-width: $screen-lg) and (orientation: landscape) {
|
|
||||||
width: 95%;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wrap
|
|
||||||
.wrap {
|
|
||||||
@include breakpoint (xs) {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Gallery
|
|
||||||
.gallery {
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
|
|
||||||
&__images {
|
|
||||||
@include breakpoint (xs) {
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Specific box shadow for images
|
|
||||||
&__photo {
|
|
||||||
box-shadow: 0 pxVW(16) pxVW(40) rgba(#2e025c, 0.4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Informations
|
|
||||||
&__infos {
|
|
||||||
margin-top: 32px;
|
|
||||||
margin-bottom: 16px;
|
|
||||||
padding: 0 24px;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Location
|
|
||||||
&__locations {
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
width: 75%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&__location {
|
|
||||||
margin-top: 0;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Date
|
|
||||||
&__date {
|
|
||||||
font-size: rem(12px);
|
|
||||||
color: rgba($color-tertiary, 0.5);
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
font-size: rem(14px);
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Photo number
|
|
||||||
&__number {
|
|
||||||
position: absolute;
|
|
||||||
z-index: 1;
|
|
||||||
left: 0;
|
|
||||||
top: -28vw;
|
|
||||||
width: 100%;
|
|
||||||
height: 40vw;
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
|
||||||
top: auto;
|
|
||||||
right: 8vw;
|
|
||||||
left: auto;
|
|
||||||
bottom: -14.5vw;
|
|
||||||
width: auto;
|
|
||||||
height: 16.8vw;
|
|
||||||
font-size: 21vw;
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
@include breakpoint (md) {
|
|
||||||
bottom: -180px;
|
|
||||||
height: 232px;
|
|
||||||
font-size: rem(300px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dots
|
|
||||||
&__dots {
|
|
||||||
position: relative;
|
|
||||||
z-index: 20;
|
|
||||||
margin-top: 24px;
|
|
||||||
margin-bottom: 24px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,54 +1,36 @@
|
|||||||
@charset "UTF-8";
|
@charset "UTF-8";
|
||||||
|
|
||||||
|
// Dependencies
|
||||||
|
@import "sanitize.css/sanitize";
|
||||||
|
|
||||||
// Tools
|
// Tools
|
||||||
@import "variables";
|
@import "variables";
|
||||||
@import "tools/mixins";
|
@import "tools/mixins";
|
||||||
@import "tools/functions";
|
@import "tools/functions";
|
||||||
@import "tools/helpers";
|
@import "tools/helpers";
|
||||||
|
|
||||||
// Dependencies
|
|
||||||
@import "normalize.css/normalize";
|
|
||||||
|
|
||||||
// Base
|
// Base
|
||||||
@import "base";
|
@import "base";
|
||||||
@import "fonts";
|
@import "fonts";
|
||||||
|
@import "typography";
|
||||||
|
|
||||||
|
// Layout
|
||||||
|
@import "layout/grid";
|
||||||
|
|
||||||
|
|
||||||
|
// Atomic Design System
|
||||||
// Atoms
|
// Atoms
|
||||||
@import "atoms/button";
|
// @import "atoms/atom";
|
||||||
@import "atoms/button-outline";
|
|
||||||
@import "atoms/button-control";
|
|
||||||
@import "atoms/icon-globe";
|
|
||||||
@import "atoms/toggle";
|
|
||||||
@import "atoms/link";
|
|
||||||
@import "atoms/switcher";
|
|
||||||
@import "atoms/counter";
|
|
||||||
@import "atoms/badge";
|
|
||||||
@import "atoms/inputs";
|
|
||||||
|
|
||||||
// Molecules
|
// Molecules
|
||||||
@import "molecules/location";
|
// @import "molecules/molecule";
|
||||||
@import "molecules/photo";
|
|
||||||
@import "molecules/globe";
|
|
||||||
@import "molecules/newsletter";
|
|
||||||
@import "molecules/form";
|
|
||||||
|
|
||||||
// Organisms
|
// Organisms
|
||||||
@import "organisms/carousel";
|
// @import "organisms/organism";
|
||||||
@import "organisms/photos";
|
|
||||||
@import "organisms/fullscreen";
|
|
||||||
@import "organisms/locations";
|
|
||||||
@import "organisms/pagination";
|
|
||||||
@import "organisms/footer";
|
|
||||||
|
|
||||||
// Layouts
|
|
||||||
@import "layouts/main";
|
|
||||||
@import "layouts/explore";
|
|
||||||
|
|
||||||
// Pages
|
// Pages
|
||||||
@import "pages/page";
|
// @import "pages/page";
|
||||||
@import "pages/homepage";
|
|
||||||
@import "pages/viewer";
|
|
||||||
@import "pages/place";
|
|
||||||
|
|
||||||
// Animations
|
// Misc
|
||||||
@import "animations";
|
// @import "animations";
|
||||||
@@ -1,17 +1,19 @@
|
|||||||
|
@use "sass:math";
|
||||||
|
|
||||||
/* PX to REM
|
/* PX to REM
|
||||||
========================================================================== */
|
========================================================================== */
|
||||||
@function rem($target, $context: $base-font-size) {
|
@function rem($target, $context: $base-font-size) {
|
||||||
@if $target == 0 { @return 0 }
|
@if $target == 0 { @return 0 }
|
||||||
$size: $target / $context;
|
$size: math.div($target, $context);
|
||||||
@return round($size * 1000) / 1000 + rem;
|
@return math.div(round($size * 1000), 1000) + rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* PX to VW
|
/* PX to VW
|
||||||
========================================================================== */
|
========================================================================== */
|
||||||
@function pxVW($value, $base: $base-width) {
|
@function pxVW($value, $base: $base-width) {
|
||||||
@if $value == 0 { @return 0; }
|
@if $value == 0 { @return 0 }
|
||||||
@return ($value / $base) * 100 + vw;
|
@return math.div($value, $base) * 100 + vw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -19,7 +21,7 @@
|
|||||||
========================================================================== */
|
========================================================================== */
|
||||||
@function vwPX($value, $base: $base-width) {
|
@function vwPX($value, $base: $base-width) {
|
||||||
@if $value == 0 { @return 0; }
|
@if $value == 0 { @return 0; }
|
||||||
@return ($value * $base) / 100 + px;
|
@return math.div(($value * $base), 100) + px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -32,3 +34,10 @@
|
|||||||
@return "h#{$from}," + headings($from + 1, $to);
|
@return "h#{$from}," + headings($from + 1, $to);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* HEX color to RGB
|
||||||
|
========================================================================== */
|
||||||
|
@function hexToRGB($color) {
|
||||||
|
@return red($color), green($color), blue($color);
|
||||||
|
}
|
||||||
@@ -27,13 +27,13 @@
|
|||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding: 0 16px;
|
padding: 0 16px;
|
||||||
|
|
||||||
@include breakpoint (mob) {
|
@include bp (mob) {
|
||||||
padding: 0 24px;
|
padding: 0 24px;
|
||||||
}
|
}
|
||||||
@include breakpoint (sm) {
|
@include bp (sm) {
|
||||||
padding: 0 60px;
|
padding: 0 60px;
|
||||||
}
|
}
|
||||||
@include breakpoint (md) {
|
@include bp (md) {
|
||||||
padding: 0 128px;
|
padding: 0 128px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -44,10 +44,10 @@
|
|||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding: 0 pxVW(128);
|
padding: 0 pxVW(128);
|
||||||
|
|
||||||
@include breakpoint (sm) {
|
@include bp (sm) {
|
||||||
padding: 0 pxVW(224);
|
padding: 0 pxVW(224);
|
||||||
}
|
}
|
||||||
@include breakpoint (xxl) {
|
@include bp (xxl) {
|
||||||
padding: 0 224px;
|
padding: 0 224px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user