From 7777235104e2cfd1e11f92555fa815b61ed43dea Mon Sep 17 00:00:00 2001 From: saiminh Date: Tue, 10 Feb 2026 18:06:34 +0100 Subject: [PATCH] layout, new work, analytics --- .gitignore | 3 + package-lock.json | 746 ++++++++++++++---- package.json | 5 +- src/lib/components/Carousel.svelte | 200 +++++ src/lib/components/Faq.svelte | 67 +- src/lib/components/Header.svelte | 4 +- src/lib/components/HomeIlluShapes.svelte | 4 +- src/lib/components/Loader.svelte | 93 +-- src/lib/components/Logo.svelte | 44 +- src/lib/components/MainNav.svelte | 70 +- src/lib/styles/{global.scss => global.css} | 193 +++-- src/lib/utils/stores.ts | 2 +- src/routes/+layout.svelte | 62 +- src/routes/+page.svelte | 339 ++++---- src/routes/+page.ts | 7 +- src/routes/contact/+page.svelte | 195 +---- .../ethical-webdevelopment/+page.svelte | 4 + src/routes/service/+page.svelte | 99 +-- src/routes/service/+page.ts | 7 +- src/routes/service/ServiceCanvas.svelte | 71 +- src/routes/work/+page.server.ts | 7 +- src/routes/work/+page.svelte | 124 ++- src/routes/work/[slug]/+page.server.ts | 17 +- src/routes/work/[slug]/+page.svelte | 471 +++-------- src/routes/work/md/adidas.md | 5 +- src/routes/work/md/aqr.md | 28 + src/routes/work/md/booking.md | 5 +- src/routes/work/md/etosis.md | 7 +- src/routes/work/md/formo.md | 5 +- src/routes/work/md/hatetracker.md | 5 +- src/routes/work/md/jpl.md | 5 +- src/routes/work/md/letshost.md | 5 +- src/routes/work/md/peak.md | 11 +- src/routes/work/md/uncommon.md | 3 + src/routes/work/md/zya.md | 27 + src/routes/work/work.scss | 93 --- vite.config.ts | 3 +- 37 files changed, 1722 insertions(+), 1314 deletions(-) create mode 100644 src/lib/components/Carousel.svelte rename src/lib/styles/{global.scss => global.css} (57%) create mode 100644 src/routes/work/md/aqr.md create mode 100644 src/routes/work/md/zya.md delete mode 100644 src/routes/work/work.scss diff --git a/.gitignore b/.gitignore index cf92117..364c0c1 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,6 @@ vite.config.ts.timestamp-* # Local Netlify folder .netlify + +# IDE files +.idea \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 2fef559..00e11b7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,6 +21,7 @@ "@sveltejs/adapter-node": "^5.0.0", "@sveltejs/kit": "^2.0.0", "@sveltejs/vite-plugin-svelte": "^5.1.1", + "@tailwindcss/vite": "^4.1.18", "@types/node": "^20.5.1", "@typescript-eslint/eslint-plugin": "^5.45.0", "@typescript-eslint/parser": "^5.45.0", @@ -29,11 +30,11 @@ "eslint-plugin-svelte": "^3.0.0", "prettier": "^3.0.0", "prettier-plugin-svelte": "^3.0.0", - "sass": "^1.64.2", "sharp": "^0.32.5", "svelte": "^5.0.0", "svelte-check": "^4.0.0", "svelte-preprocess": "^6.0.3", + "tailwindcss": "^4.1.18", "tslib": "^2.4.1", "typescript": "^5.0.0", "vanilla-lazyload": "^17.8.4", @@ -1357,6 +1358,278 @@ "vite": "^6.0.0" } }, + "node_modules/@tailwindcss/node": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.18.tgz", + "integrity": "sha512-DoR7U1P7iYhw16qJ49fgXUlry1t4CpXeErJHnQ44JgTSKMaZUdf17cfn5mHchfJ4KRBZRFA/Coo+MUF5+gOaCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.4", + "enhanced-resolve": "^5.18.3", + "jiti": "^2.6.1", + "lightningcss": "1.30.2", + "magic-string": "^0.30.21", + "source-map-js": "^1.2.1", + "tailwindcss": "4.1.18" + } + }, + "node_modules/@tailwindcss/oxide": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.18.tgz", + "integrity": "sha512-EgCR5tTS5bUSKQgzeMClT6iCY3ToqE1y+ZB0AKldj809QXk1Y+3jB0upOYZrn9aGIzPtUsP7sX4QQ4XtjBB95A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "@tailwindcss/oxide-android-arm64": "4.1.18", + "@tailwindcss/oxide-darwin-arm64": "4.1.18", + "@tailwindcss/oxide-darwin-x64": "4.1.18", + "@tailwindcss/oxide-freebsd-x64": "4.1.18", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.18", + "@tailwindcss/oxide-linux-arm64-gnu": "4.1.18", + "@tailwindcss/oxide-linux-arm64-musl": "4.1.18", + "@tailwindcss/oxide-linux-x64-gnu": "4.1.18", + "@tailwindcss/oxide-linux-x64-musl": "4.1.18", + "@tailwindcss/oxide-wasm32-wasi": "4.1.18", + "@tailwindcss/oxide-win32-arm64-msvc": "4.1.18", + "@tailwindcss/oxide-win32-x64-msvc": "4.1.18" + } + }, + "node_modules/@tailwindcss/oxide-android-arm64": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.18.tgz", + "integrity": "sha512-dJHz7+Ugr9U/diKJA0W6N/6/cjI+ZTAoxPf9Iz9BFRF2GzEX8IvXxFIi/dZBloVJX/MZGvRuFA9rqwdiIEZQ0Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-darwin-arm64": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.18.tgz", + "integrity": "sha512-Gc2q4Qhs660bhjyBSKgq6BYvwDz4G+BuyJ5H1xfhmDR3D8HnHCmT/BSkvSL0vQLy/nkMLY20PQ2OoYMO15Jd0A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-darwin-x64": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.18.tgz", + "integrity": "sha512-FL5oxr2xQsFrc3X9o1fjHKBYBMD1QZNyc1Xzw/h5Qu4XnEBi3dZn96HcHm41c/euGV+GRiXFfh2hUCyKi/e+yw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-freebsd-x64": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.18.tgz", + "integrity": "sha512-Fj+RHgu5bDodmV1dM9yAxlfJwkkWvLiRjbhuO2LEtwtlYlBgiAT4x/j5wQr1tC3SANAgD+0YcmWVrj8R9trVMA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.18.tgz", + "integrity": "sha512-Fp+Wzk/Ws4dZn+LV2Nqx3IilnhH51YZoRaYHQsVq3RQvEl+71VGKFpkfHrLM/Li+kt5c0DJe/bHXK1eHgDmdiA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.18.tgz", + "integrity": "sha512-S0n3jboLysNbh55Vrt7pk9wgpyTTPD0fdQeh7wQfMqLPM/Hrxi+dVsLsPrycQjGKEQk85Kgbx+6+QnYNiHalnw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-musl": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.18.tgz", + "integrity": "sha512-1px92582HkPQlaaCkdRcio71p8bc8i/ap5807tPRDK/uw953cauQBT8c5tVGkOwrHMfc2Yh6UuxaH4vtTjGvHg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-gnu": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.18.tgz", + "integrity": "sha512-v3gyT0ivkfBLoZGF9LyHmts0Isc8jHZyVcbzio6Wpzifg/+5ZJpDiRiUhDLkcr7f/r38SWNe7ucxmGW3j3Kb/g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-musl": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.18.tgz", + "integrity": "sha512-bhJ2y2OQNlcRwwgOAGMY0xTFStt4/wyU6pvI6LSuZpRgKQwxTec0/3Scu91O8ir7qCR3AuepQKLU/kX99FouqQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.18.tgz", + "integrity": "sha512-LffYTvPjODiP6PT16oNeUQJzNVyJl1cjIebq/rWWBF+3eDst5JGEFSc5cWxyRCJ0Mxl+KyIkqRxk1XPEs9x8TA==", + "bundleDependencies": [ + "@napi-rs/wasm-runtime", + "@emnapi/core", + "@emnapi/runtime", + "@tybys/wasm-util", + "@emnapi/wasi-threads", + "tslib" + ], + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1", + "@emnapi/wasi-threads": "^1.1.0", + "@napi-rs/wasm-runtime": "^1.1.0", + "@tybys/wasm-util": "^0.10.1", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.18.tgz", + "integrity": "sha512-HjSA7mr9HmC8fu6bdsZvZ+dhjyGCLdotjVOgLA2vEqxEBZaQo9YTX4kwgEvPCpRh8o4uWc4J/wEoFzhEmjvPbA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-win32-x64-msvc": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.18.tgz", + "integrity": "sha512-bJWbyYpUlqamC8dpR7pfjA0I7vdF6t5VpUGMWRkXVE3AXgIZjYUYAK7II1GNaxR8J1SSrSrppRar8G++JekE3Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/vite": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.1.18.tgz", + "integrity": "sha512-jVA+/UpKL1vRLg6Hkao5jldawNmRo7mQYrZtNHMIVpLfLhDml5nMRUo/8MwoX2vNXvnaXNNMedrMfMugAVX1nA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tailwindcss/node": "4.1.18", + "@tailwindcss/oxide": "4.1.18", + "tailwindcss": "4.1.18" + }, + "peerDependencies": { + "vite": "^5.2.0 || ^6 || ^7" + } + }, "node_modules/@types/cookie": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", @@ -1701,19 +1974,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -1878,15 +2138,6 @@ } ] }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/bl": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", @@ -1972,42 +2223,19 @@ } }, "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], + "license": "MIT", "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" + "readdirp": "^4.0.1" }, "engines": { - "node": ">= 8.10.0" + "node": ">= 14.16.0" }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chokidar/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" + "funding": { + "url": "https://paulmillr.com/funding/" } }, "node_modules/chownr": { @@ -2224,10 +2452,11 @@ } }, "node_modules/detect-libc": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz", - "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=8" } @@ -2272,6 +2501,20 @@ "once": "^1.4.0" } }, + "node_modules/enhanced-resolve": { + "version": "5.19.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.19.0.tgz", + "integrity": "sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.3.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/esbuild": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", @@ -2868,6 +3111,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, "node_modules/graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", @@ -2931,12 +3181,6 @@ "node": ">= 4" } }, - "node_modules/immutable": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.2.tgz", - "integrity": "sha512-oGXzbEDem9OOpDWZu88jGiYCvIsLHMvGw+8OXlpsvTFvIQplQbjg1B1cvKg8f7Hoch6+NGjpPsH1Fr+Mc2D1aA==", - "dev": true - }, "node_modules/import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", @@ -3001,18 +3245,6 @@ "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", "dev": true }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/is-core-module": { "version": "2.16.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", @@ -3108,6 +3340,16 @@ "resolved": "https://registry.npmjs.org/ismobilejs/-/ismobilejs-1.1.1.tgz", "integrity": "sha512-VaFW53yt8QO61k2WJui0dHf4SlL8lxBofUuUmwBo0ljPk0Drz2TiuDW4jo3wDcv41qy/SxrJ+VAzJ/qYqsmzRw==" }, + "node_modules/jiti": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", + "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, "node_modules/js-binary-schema-parser": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/js-binary-schema-parser/-/js-binary-schema-parser-2.0.3.tgz", @@ -3169,6 +3411,267 @@ "node": ">= 0.8.0" } }, + "node_modules/lightningcss": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.2.tgz", + "integrity": "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.30.2", + "lightningcss-darwin-arm64": "1.30.2", + "lightningcss-darwin-x64": "1.30.2", + "lightningcss-freebsd-x64": "1.30.2", + "lightningcss-linux-arm-gnueabihf": "1.30.2", + "lightningcss-linux-arm64-gnu": "1.30.2", + "lightningcss-linux-arm64-musl": "1.30.2", + "lightningcss-linux-x64-gnu": "1.30.2", + "lightningcss-linux-x64-musl": "1.30.2", + "lightningcss-win32-arm64-msvc": "1.30.2", + "lightningcss-win32-x64-msvc": "1.30.2" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.30.2.tgz", + "integrity": "sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.2.tgz", + "integrity": "sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.2.tgz", + "integrity": "sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.2.tgz", + "integrity": "sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.2.tgz", + "integrity": "sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.2.tgz", + "integrity": "sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.2.tgz", + "integrity": "sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.2.tgz", + "integrity": "sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.2.tgz", + "integrity": "sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.2.tgz", + "integrity": "sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.2.tgz", + "integrity": "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, "node_modules/lilconfig": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", @@ -3378,15 +3881,6 @@ "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==", "dev": true }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -3894,15 +4388,17 @@ } }, "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, + "license": "MIT", "engines": { - "node": ">=8.10.0" + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" } }, "node_modules/resolve": { @@ -4060,23 +4556,6 @@ } ] }, - "node_modules/sass": { - "version": "1.64.2", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.64.2.tgz", - "integrity": "sha512-TnDlfc+CRnUAgLO9D8cQLFu/GIjJIzJCGkE7o4ekIGQOH7T3GetiRR/PsTWJUHhkzcSPrARkPI+gNWn5alCzDg==", - "dev": true, - "dependencies": { - "chokidar": ">=3.0.0 <4.0.0", - "immutable": "^4.0.0", - "source-map-js": ">=0.6.2 <2.0.0" - }, - "bin": { - "sass": "sass.js" - }, - "engines": { - "node": ">=14.0.0" - } - }, "node_modules/semver": { "version": "7.7.3", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", @@ -4367,36 +4846,6 @@ "typescript": ">=5.0.0" } }, - "node_modules/svelte-check/node_modules/chokidar": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", - "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "readdirp": "^4.0.1" - }, - "engines": { - "node": ">= 14.16.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/svelte-check/node_modules/readdirp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", - "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 14.18.0" - }, - "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/svelte-cloudinary": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/svelte-cloudinary/-/svelte-cloudinary-1.3.2.tgz", @@ -4567,6 +5016,27 @@ "@types/estree": "^1.0.6" } }, + "node_modules/tailwindcss": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.18.tgz", + "integrity": "sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw==", + "dev": true, + "license": "MIT" + }, + "node_modules/tapable": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", + "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, "node_modules/tar-fs": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.1.tgz", diff --git a/package.json b/package.json index bee8488..e8c01e4 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "@sveltejs/adapter-node": "^5.0.0", "@sveltejs/kit": "^2.0.0", "@sveltejs/vite-plugin-svelte": "^5.1.1", + "@tailwindcss/vite": "^4.1.18", "@types/node": "^20.5.1", "@typescript-eslint/eslint-plugin": "^5.45.0", "@typescript-eslint/parser": "^5.45.0", @@ -26,11 +27,11 @@ "eslint-plugin-svelte": "^3.0.0", "prettier": "^3.0.0", "prettier-plugin-svelte": "^3.0.0", - "sass": "^1.64.2", "sharp": "^0.32.5", "svelte": "^5.0.0", "svelte-check": "^4.0.0", "svelte-preprocess": "^6.0.3", + "tailwindcss": "^4.1.18", "tslib": "^2.4.1", "typescript": "^5.0.0", "vanilla-lazyload": "^17.8.4", @@ -40,8 +41,8 @@ "dependencies": { "gsap": "^3.13.0", "mdsvex": "^0.11.0", - "pixi.js": "^8.15.0", "pixi-filters": "^6.1.5", + "pixi.js": "^8.15.0", "superjson": "^1.13.1", "svelte-cloudinary": "^1.1.0" } diff --git a/src/lib/components/Carousel.svelte b/src/lib/components/Carousel.svelte new file mode 100644 index 0000000..0c22f43 --- /dev/null +++ b/src/lib/components/Carousel.svelte @@ -0,0 +1,200 @@ + + + + + diff --git a/src/lib/components/Faq.svelte b/src/lib/components/Faq.svelte index 6a18a2d..1e49fd5 100644 --- a/src/lib/components/Faq.svelte +++ b/src/lib/components/Faq.svelte @@ -70,14 +70,13 @@ - \ No newline at end of file diff --git a/src/lib/components/Header.svelte b/src/lib/components/Header.svelte index f560154..d6e4b09 100644 --- a/src/lib/components/Header.svelte +++ b/src/lib/components/Header.svelte @@ -10,9 +10,9 @@ - \ No newline at end of file diff --git a/src/lib/components/Loader.svelte b/src/lib/components/Loader.svelte index 1390b12..0ca7119 100644 --- a/src/lib/components/Loader.svelte +++ b/src/lib/components/Loader.svelte @@ -3,66 +3,53 @@

Loading...

- \ No newline at end of file diff --git a/src/lib/components/Logo.svelte b/src/lib/components/Logo.svelte index eaf15a7..a9ac290 100644 --- a/src/lib/components/Logo.svelte +++ b/src/lib/components/Logo.svelte @@ -1,35 +1,21 @@ - - - \ No newline at end of file + } + \ No newline at end of file diff --git a/src/lib/components/MainNav.svelte b/src/lib/components/MainNav.svelte index 17c5a88..e38259d 100644 --- a/src/lib/components/MainNav.svelte +++ b/src/lib/components/MainNav.svelte @@ -48,7 +48,11 @@
- \ No newline at end of file diff --git a/src/lib/styles/global.scss b/src/lib/styles/global.css similarity index 57% rename from src/lib/styles/global.scss rename to src/lib/styles/global.css index 20b9c84..5d570e6 100644 --- a/src/lib/styles/global.scss +++ b/src/lib/styles/global.css @@ -1,9 +1,12 @@ -:root { +@import "tailwindcss"; + +@layer base { + :root { --spacing-outer: 5vw; --spacing-nav: 5vw; - --color-bg: rgb(207, 63, 70);; - --color-text: rgb(255, 234, 217); - --color-highlight: rgb(29, 12, 18); + --color-bg: rgb(0, 0, 90); + --color-text: rgb(255, 240, 240); + --color-highlight: rgb(250, 125, 0); --color-bg-variant-1: rgb(207, 63, 70); --color-text-variant-1: rgb(255, 234, 217); @@ -20,13 +23,13 @@ --color-bg-variant-4: rgb(238, 127, 1); --color-text-variant-4: rgb(253, 254, 255); --color-highlight-variant-4: rgb(0, 39, 67); - + --aspect-ratio-heroes: 1.5; - --font-size-p: clamp(20px, 1.6vw, 1.6vw); + --font-size-p: clamp(20px, 1.6vw, 125px); @media screen and (min-width: 768px) { --spacing-outer: 5vw; - --spacing-nav: 2.5vw; + --spacing-nav: 2.5vw; } } @@ -48,6 +51,7 @@ a:hover, input:hover, button:hover { cursor: url('/pointer.svg'), auto; } + body { cursor: url('/cursor.svg'), auto; font-family: stratos, sans-serif; @@ -61,47 +65,59 @@ body { overflow-x: hidden; transition: background-color .5s ease-in-out, color .5s ease-in-out; } + body * { box-sizing: border-box; -} -h1, h2, h3, h4, h5 { +} + +:where(h1, h2, h3, h4, h5) { font-size: 2em; line-height: 1.1; font-weight: 400; letter-spacing: -0.025em; } + h1 { font-size: 2.5em; } + h2 { font-size: 1.5em; } + h3 { font-size: 1.25em; } + ul, ol { padding-left: 0; } + ul { list-style: '▪︎ '; } + p, li { font-weight: 400; font-size: var(--font-size-p); line-height: 1.3; } + a { color: inherit; text-underline-offset: 0.25em; text-decoration-thickness: 0.066em; transition: all .3s cubic-bezier(0.175, 0.885, 0.32, 1.275); - &:hover { - text-underline-offset: 0.1em; - } } + +a:hover { + text-underline-offset: 0.1em; +} + .cta { font-size: clamp(20px, 1.6vw, 1.6vw); } + .button { font-weight: 800; font-style: italic; @@ -118,88 +134,99 @@ a { position: relative; z-index: 2; transition: all .3s cubic-bezier(0.175, 0.885, 0.32, 1.275); +} - &:hover { - color: var(--color-bg); - @media screen and (min-width: 768px) { - letter-spacing: 0.01em; - } - } - - &:before { - content: ''; - display: block; - position: absolute; - z-index: -1; - width: 100%; - height: 100%; - left: 0px; - bottom: 0; - border: 2px solid var(--color-text); - background-color: var(--color-bg); - box-sizing: border-box; - transition: all .3s cubic-bezier(0.175, 0.885, 0.32, 1.275); - } - &:hover:before { - background-color: var(--color-text); - width: calc(100% + 0.25em); - height: calc(100% + 10px); - left: -0.125em; - bottom: -5px; - transition: all .3s cubic-bezier(0.175, 0.885, 0.32, 1.275); - } - &.button--primary { - color: var(--color-text); +.button:hover { + color: var(--color-bg); +} - &:hover { - color: var(--color-highlight); - } - &:before { - background-color: var(--color-highlight); - border: 2px solid var(--color-highlight); - } - &:hover:before { - background-color: var(--color-text); - border: 2px solid var(--color-text); - } - } - &.button--xl { - font-size: clamp(24px, 3.2vw, 3.2vw); - padding: 0.5em; - letter-spacing: -0.02em; - margin: 0 auto; - text-align: center; - - &:hover { - letter-spacing: 0; - } +@media screen and (min-width: 768px) { + .button:hover { + letter-spacing: 0.01em; } } + +.button::before { + content: ''; + display: block; + position: absolute; + z-index: -1; + width: 100%; + height: 100%; + left: 0px; + bottom: 0; + border: 2px solid var(--color-text); + background-color: var(--color-bg); + box-sizing: border-box; + transition: all .3s cubic-bezier(0.175, 0.885, 0.32, 1.275); +} + +.button:hover::before { + background-color: var(--color-text); + width: calc(100% + 0.25em); + height: calc(100% + 10px); + left: -0.125em; + bottom: -5px; + transition: all .3s cubic-bezier(0.175, 0.885, 0.32, 1.275); +} + +.button.button--primary { + color: var(--color-text); +} + +.button.button--primary:hover { + color: var(--color-highlight); +} + +.button.button--primary::before { + background-color: var(--color-highlight); + border: 2px solid var(--color-highlight); +} + +.button.button--primary:hover::before { + background-color: var(--color-text); + border: 2px solid var(--color-text); +} + +.button.button--xl { + font-size: clamp(24px, 3.2vw, 3.2vw); + padding: 0.5em; + letter-spacing: -0.02em; + margin: 0 auto; + text-align: center; +} + +.button.button--xl:hover { + letter-spacing: 0; +} + .infobox { - // border-top: 2px solid var(--color-text); - // border-bottom: 2px solid var(--color-text); padding: 1.5em 0; font-size: var(--font-size-p); - - & li { - border-bottom: 1px solid; - padding: 0.5em 0; - } - - & > :first-child { - margin-top: 0; - } - & > :last-child { - margin-bottom: 0; - } } -.content{ + +.infobox li { + border-bottom: 1px solid; + padding: 0.5em 0; +} + +.infobox > :first-child { + margin-top: 0; +} + +.infobox > :last-child { + margin-bottom: 0; +} + +.content { position: absolute; top: 0; width: 100%; } -.hide-on-mobile { - @media screen and (orientation: portrait) and (max-width: 767px) { + +@media screen and (orientation: portrait) and (max-width: 767px) { + .hide-on-mobile { display: none; } -} \ No newline at end of file +} +} diff --git a/src/lib/utils/stores.ts b/src/lib/utils/stores.ts index a084d07..e7bd954 100644 --- a/src/lib/utils/stores.ts +++ b/src/lib/utils/stores.ts @@ -2,4 +2,4 @@ import { writable } from 'svelte/store'; export const workbulge = writable(0.25); export const loading = writable(false); -export const logotext = writable('Flöter'); \ No newline at end of file +export const logotext = writable('FlöTeR'); \ No newline at end of file diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index a3d996a..a932406 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -1,5 +1,5 @@ @@ -93,14 +74,13 @@ {page.data.title ? page.data.title : 'Simon Flöter, Designer and Creative Developer'} +
-
{#if showLoader} {/if} {@render children()} -
- \ No newline at end of file + \ No newline at end of file diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 7e36ea4..ad6dca9 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -22,6 +22,14 @@ gsap.registerPlugin( ScrollTrigger, ScrollToPlugin, SplitText ); const sections = document.querySelectorAll('section'); + const highlight = document.querySelector('h1 em'); + + gsap.to(highlight, { + duration: .5, + color: 'var(--color-highlight)', + ease: 'power4.out', + delay: 2 + }) sections.forEach( (section) => { if ( section.classList.contains('splash')){ @@ -93,210 +101,155 @@ -
-
-

I create digital experiences that stand out from the rest.

+
+
+

+ I'm Simon Flöter.
+ I create brands and websites that stand out. +

-
-
+ +
+
-

Creative Development

-

I create exquisitly tailored web experiences for discerning enterprises and their audiences.

-
- Services I provide - Contact me +

+ Creative Development +

+

+ I create exquisitly tailored web experiences for discerning enterprises and their audiences. +

+
-
-
+ +
+
-

Visual Design

-

I'm a seasoned designer, with a long list of succesful projects and happy clients.

-
- Work I've done - Contact me +

+ Visual Design +

+

+ I'm a seasoned designer, with a long list of succesful projects and happy clients. +

+
-
-

I am currently available for freelance work.

+ +
+
+ +
{#if mounted} -
(as of { currentMonth })
+
+ (as of {currentMonth}) +
{/if} -
- -
- - \ No newline at end of file + +
diff --git a/src/routes/+page.ts b/src/routes/+page.ts index ea1222f..9a078b7 100644 --- a/src/routes/+page.ts +++ b/src/routes/+page.ts @@ -2,6 +2,11 @@ export const prerender = true export function load() { return { title: 'Simon Flöter, creative developer and designer', - description: 'Simon Flöter is a creative developer and designer you can hire as a freelancer' + description: 'Simon Flöter is a creative developer and designer you can hire as a freelancer', + theme: { + bg: 'rgb(0, 0, 90)', + text: 'rgb(255, 240, 240)', + highlight: 'rgb(250, 125, 0)', + } } } \ No newline at end of file diff --git a/src/routes/contact/+page.svelte b/src/routes/contact/+page.svelte index f925690..2e261f0 100644 --- a/src/routes/contact/+page.svelte +++ b/src/routes/contact/+page.svelte @@ -78,9 +78,9 @@
-
-

Let's be strange,
not strangers.

-
+
+

Let's be strange,
not strangers.

+

Choose your flavour of contact:

  • Contact form
  • @@ -89,30 +89,27 @@
-
- ← Back -
-
-
diff --git a/src/routes/service/+page.ts b/src/routes/service/+page.ts index fbff7b6..1e9a1e5 100644 --- a/src/routes/service/+page.ts +++ b/src/routes/service/+page.ts @@ -1,6 +1,11 @@ export function load() { return { title: 'Services I provide', - description: 'A list of profesional webdevelopment and design services I provide' + description: 'A list of profesional webdevelopment and design services I provide', + theme: { + bg: '#00005A', + text: '#FFF0F0', + highlight: '#FA7D00', + } }; } \ No newline at end of file diff --git a/src/routes/service/ServiceCanvas.svelte b/src/routes/service/ServiceCanvas.svelte index 22d01b3..9863989 100644 --- a/src/routes/service/ServiceCanvas.svelte +++ b/src/routes/service/ServiceCanvas.svelte @@ -6,6 +6,8 @@ import { ScrollTrigger } from 'gsap/ScrollTrigger'; import { onMount } from 'svelte'; + let { theme } = $props(); + let canvas: HTMLCanvasElement; let introDone = false; @@ -17,11 +19,25 @@ (async () => { let highLightColor = window.getComputedStyle(document.body).getPropertyValue('--color-highlight'); + + if (theme) { + highLightColor = theme.highlight; + } else { + highLightColor = window.getComputedStyle(document.body).getPropertyValue('--color-highlight'); + } + let is_landscape = window.matchMedia('(orientation:landscape)').matches; let isDestroyed = false; gsap.registerPlugin(ScrollTrigger); + // Ensure Stratos is loaded before canvas text (fixes Firefox black blocks on long text) + try { + await document.fonts.load('bold italic 1em Stratos'); + } catch { + await document.fonts.ready; + } + let app = new PIXI.Application(); await app.init({ canvas: canvas, @@ -45,15 +61,17 @@ let fontSize = window.innerHeight / 3; + const isFirefox = typeof navigator !== 'undefined' && /Firefox/i.test(navigator.userAgent); + function createText(string: string): PIXI.Text { let text = getTextFromPool(); text.text = string; text.style = { fontFamily: 'Stratos', fontSize: fontSize, - fontWeight: '800', + fontWeight: 'bold', fontStyle: 'italic', - lineHeight: 0, + lineHeight: fontSize * 0.85, letterSpacing: -10, fill: highLightColor, padding: 0 @@ -63,6 +81,37 @@ return text } + /** Firefox renders long canvas text as a black block; use a container of shorter segments. */ + function createLongTextAsContainer(): PIXI.Container & { width: number; height: number } { + const parts = ['CONSULTATION ', 'DESIGN ', 'WEB ', 'DEVELOPMENT ']; + const container = new PIXI.Container() as PIXI.Container & { width: number; height: number }; + let x = 0; + for (const part of parts) { + const text = getTextFromPool(); + text.text = part; + text.style = { + fontFamily: 'Stratos', + fontSize: fontSize, + fontWeight: 'bold', + fontStyle: 'italic', + lineHeight: fontSize * 0.85, + letterSpacing: -10, + fill: highLightColor, + padding: 0 + }; + text.anchor.set(0); + text.x = x; + text.y = 0; + container.addChild(text); + x += text.width; + } + const bounds = container.getBounds(); + container.width = bounds.width; + container.height = bounds.height; + textgroup.addChild(container); + return container; + } + // Text object pool management function getTextFromPool(): PIXI.Text { if (textPool.length > 0) { @@ -75,11 +124,12 @@ textPool.push(text); } - let allTexts = [ + const longLine = 'CONSULTATION DESIGN WEB DEVELOPMENT '; + let allTexts: (PIXI.Text | (PIXI.Container & { width: number; height: number }))[] = [ createText('SERVICES SERVICES '), createText('SERVICES SERVICES '), - createText('CONSULTATION DESIGN WEB DEVELOPMENT '), createText('CONSULTATION DESIGN WEB DEVELOPMENT '), + isFirefox ? createLongTextAsContainer() : createText(longLine), isFirefox ? createLongTextAsContainer() : createText(longLine), createText('SERVICES SERVICES '), createText('SERVICES SERVICES '), - createText('CONSULTATION DESIGN WEB DEVELOPMENT '), createText('CONSULTATION DESIGN WEB DEVELOPMENT ') + isFirefox ? createLongTextAsContainer() : createText(longLine), isFirefox ? createLongTextAsContainer() : createText(longLine) ] let textRows = [ @@ -224,8 +274,15 @@ } }); - // Return objects to pools - allTexts.forEach(text => returnTextToPool(text)); + // Return objects to pools (containers: return child texts to pool, then destroy container) + allTexts.forEach((el) => { + if (el instanceof PIXI.Container && 'width' in el) { + el.children.forEach((child) => returnTextToPool(child as PIXI.Text)); + el.destroy(); + } else { + returnTextToPool(el as PIXI.Text); + } + }); // Now safe to destroy PixiJS app app.destroy(true, { children: true, texture: true }); } diff --git a/src/routes/work/+page.server.ts b/src/routes/work/+page.server.ts index 0f660f3..a0f038e 100644 --- a/src/routes/work/+page.server.ts +++ b/src/routes/work/+page.server.ts @@ -15,7 +15,12 @@ export async function load() { return { posts, title: 'Work References', - description: 'A few of the projects I have worked on' + description: 'A few of the projects I have worked on', + theme: { + bg: '#FA7D00', + text: '#FFFFFF', + highlight: '#00005A', + } } } catch (error) { console.error('Error loading work posts:', error) diff --git a/src/routes/work/+page.svelte b/src/routes/work/+page.svelte index a099244..f9e07b7 100644 --- a/src/routes/work/+page.svelte +++ b/src/routes/work/+page.svelte @@ -9,6 +9,18 @@ return a.meta.order - b.meta.order; })); + function getColorValue(cssValue: string): string { + // If it's a CSS variable reference, resolve it + if (cssValue.trim().startsWith('var(')) { + // Extract the variable name and resolve it + const varName = cssValue.match(/var\(([^)]+)\)/)?.[1]; + if (varName) { + return getComputedStyle(document.documentElement).getPropertyValue(varName.trim()).trim() || cssValue; + } + } + return cssValue.trim(); + } + onMount(() => { document.querySelectorAll('.workclone')?.forEach(clone => { clone.remove(); @@ -17,8 +29,20 @@ let isZoomed = false; - const currentBgColor = getComputedStyle(document.documentElement).getPropertyValue('--color-bg'); - const currentHighlightColor = getComputedStyle(document.documentElement).getPropertyValue('--color-highlight'); + // const currentBgColor = getComputedStyle(document.documentElement).getPropertyValue('--color-bg'); + // const currentHighlightColor = getComputedStyle(document.documentElement).getPropertyValue('--color-highlight'); + + // Read from data.theme if available, otherwise from CSS + let currentBgColor: string; + let currentHighlightColor: string; + + if (data.theme) { + currentBgColor = getColorValue(data.theme.bg); + currentHighlightColor = getColorValue(data.theme.highlight); + } else { + currentBgColor = getComputedStyle(document.documentElement).getPropertyValue('--color-bg').trim(); + currentHighlightColor = getComputedStyle(document.documentElement).getPropertyValue('--color-highlight').trim(); + } let works: Array = Array.from(document.querySelectorAll('.work')); for ( let i = 0; i < 40; i++ ){ @@ -241,4 +265,98 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/routes/work/[slug]/+page.server.ts b/src/routes/work/[slug]/+page.server.ts index 7a9e50b..4a58f0f 100644 --- a/src/routes/work/[slug]/+page.server.ts +++ b/src/routes/work/[slug]/+page.server.ts @@ -14,7 +14,10 @@ export async function load( { params }: { params: { slug: string }} ){ description = [], images = [], agency = '', - agencyName = '' + agencyName = '', + colorBg = 'var(--color-bg-variant-2)', + colorText = 'var(--color-text-variant-2)', + colorHighlight = 'var(--color-highlight-variant-2)', } = post.metadata // Don't pass the component - it's not serializable @@ -35,6 +38,18 @@ export async function load( { params }: { params: { slug: string }} ){ images, agency, agencyName, + colorBg, + colorText, + colorHighlight, + theme: [ + colorBg, + colorText, + colorHighlight, + ].every(Boolean) ? { + bg: colorBg, + text: colorText, + highlight: colorHighlight, + } : undefined, } } catch (error) { console.error(error) diff --git a/src/routes/work/[slug]/+page.svelte b/src/routes/work/[slug]/+page.svelte index 487e3fd..e8cc7d2 100644 --- a/src/routes/work/[slug]/+page.svelte +++ b/src/routes/work/[slug]/+page.svelte @@ -1,176 +1,167 @@ -
- -
- -