implemented vertical slider from Ecem Gokdogan

This commit is contained in:
Joshua Ashton
2024-12-21 16:05:49 -07:00
parent 874e88388a
commit 14c348af18
34 changed files with 1043 additions and 18502 deletions
Vendored
BIN
View File
Binary file not shown.
+21 -17
View File
@@ -1,20 +1,24 @@
# Created by https://www.toptal.com/developers/gitignore/api/react
# Edit at https://www.toptal.com/developers/gitignore?templates=react
### react ###
.DS_*
*.log
# Logs
logs
**/*.backup.*
**/*.back.*
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
public/node_modules
public/bower_components
node_modules
dist
dist-ssr
*.local
*.sublime*
psd
thumb
sketch
# End of https://www.toptal.com/developers/gitignore/api/react
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
+13
View File
@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Josh Ashton</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
</html>
+656
View File
@@ -0,0 +1,656 @@
{
"name": "portfolio",
"version": "0.0.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "portfolio",
"version": "0.0.1",
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0",
"swiper": "^10.0.0"
},
"devDependencies": {
"vite": "^4.0.4"
}
},
"node_modules/@esbuild/android-arm": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
"integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==",
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/android-arm64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz",
"integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/android-x64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz",
"integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/darwin-arm64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz",
"integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/darwin-x64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz",
"integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/freebsd-arm64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz",
"integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/freebsd-x64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz",
"integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-arm": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz",
"integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==",
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-arm64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz",
"integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-ia32": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz",
"integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==",
"cpu": [
"ia32"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-loong64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz",
"integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==",
"cpu": [
"loong64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-mips64el": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz",
"integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==",
"cpu": [
"mips64el"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-ppc64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz",
"integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==",
"cpu": [
"ppc64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-riscv64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz",
"integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==",
"cpu": [
"riscv64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-s390x": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz",
"integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==",
"cpu": [
"s390x"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-x64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz",
"integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/netbsd-x64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz",
"integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"netbsd"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/openbsd-x64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz",
"integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openbsd"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/sunos-x64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz",
"integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"sunos"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/win32-arm64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz",
"integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/win32-ia32": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz",
"integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==",
"cpu": [
"ia32"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/win32-x64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz",
"integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz",
"integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
"bin": {
"esbuild": "bin/esbuild"
},
"engines": {
"node": ">=12"
},
"optionalDependencies": {
"@esbuild/android-arm": "0.18.20",
"@esbuild/android-arm64": "0.18.20",
"@esbuild/android-x64": "0.18.20",
"@esbuild/darwin-arm64": "0.18.20",
"@esbuild/darwin-x64": "0.18.20",
"@esbuild/freebsd-arm64": "0.18.20",
"@esbuild/freebsd-x64": "0.18.20",
"@esbuild/linux-arm": "0.18.20",
"@esbuild/linux-arm64": "0.18.20",
"@esbuild/linux-ia32": "0.18.20",
"@esbuild/linux-loong64": "0.18.20",
"@esbuild/linux-mips64el": "0.18.20",
"@esbuild/linux-ppc64": "0.18.20",
"@esbuild/linux-riscv64": "0.18.20",
"@esbuild/linux-s390x": "0.18.20",
"@esbuild/linux-x64": "0.18.20",
"@esbuild/netbsd-x64": "0.18.20",
"@esbuild/openbsd-x64": "0.18.20",
"@esbuild/sunos-x64": "0.18.20",
"@esbuild/win32-arm64": "0.18.20",
"@esbuild/win32-ia32": "0.18.20",
"@esbuild/win32-x64": "0.18.20"
}
},
"node_modules/fsevents": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
}
},
"node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
"license": "MIT"
},
"node_modules/loose-envify": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
"license": "MIT",
"dependencies": {
"js-tokens": "^3.0.0 || ^4.0.0"
},
"bin": {
"loose-envify": "cli.js"
}
},
"node_modules/nanoid": {
"version": "3.3.8",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz",
"integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"license": "MIT",
"bin": {
"nanoid": "bin/nanoid.cjs"
},
"engines": {
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
}
},
"node_modules/picocolors": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
"dev": true,
"license": "ISC"
},
"node_modules/postcss": {
"version": "8.4.49",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz",
"integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==",
"dev": true,
"funding": [
{
"type": "opencollective",
"url": "https://opencollective.com/postcss/"
},
{
"type": "tidelift",
"url": "https://tidelift.com/funding/github/npm/postcss"
},
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"license": "MIT",
"dependencies": {
"nanoid": "^3.3.7",
"picocolors": "^1.1.1",
"source-map-js": "^1.2.1"
},
"engines": {
"node": "^10 || ^12 || >=14"
}
},
"node_modules/react": {
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
"integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
"license": "MIT",
"dependencies": {
"loose-envify": "^1.1.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/react-dom": {
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
"integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
"license": "MIT",
"dependencies": {
"loose-envify": "^1.1.0",
"scheduler": "^0.23.2"
},
"peerDependencies": {
"react": "^18.3.1"
}
},
"node_modules/rollup": {
"version": "3.29.5",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.5.tgz",
"integrity": "sha512-GVsDdsbJzzy4S/v3dqWPJ7EfvZJfCHiDqe80IyrF59LYuP+e6U1LJoUqeuqRbwAWoMNoXivMNeNAOf5E22VA1w==",
"dev": true,
"license": "MIT",
"bin": {
"rollup": "dist/bin/rollup"
},
"engines": {
"node": ">=14.18.0",
"npm": ">=8.0.0"
},
"optionalDependencies": {
"fsevents": "~2.3.2"
}
},
"node_modules/scheduler": {
"version": "0.23.2",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
"integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
"license": "MIT",
"dependencies": {
"loose-envify": "^1.1.0"
}
},
"node_modules/source-map-js": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
"dev": true,
"license": "BSD-3-Clause",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/swiper": {
"version": "10.3.1",
"resolved": "https://registry.npmjs.org/swiper/-/swiper-10.3.1.tgz",
"integrity": "sha512-24Wk3YUdZHxjc9faID97GTu6xnLNia+adMt6qMTZG/HgdSUt4fS0REsGUXJOgpTED0Amh/j+gRGQxsLayJUlBQ==",
"funding": [
{
"type": "patreon",
"url": "https://www.patreon.com/swiperjs"
},
{
"type": "open_collective",
"url": "http://opencollective.com/swiper"
}
],
"license": "MIT",
"engines": {
"node": ">= 4.7.0"
}
},
"node_modules/vite": {
"version": "4.5.5",
"resolved": "https://registry.npmjs.org/vite/-/vite-4.5.5.tgz",
"integrity": "sha512-ifW3Lb2sMdX+WU91s3R0FyQlAyLxOzCSCP37ujw0+r5POeHPwe6udWVIElKQq8gk3t7b8rkmvqC6IHBpCff4GQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"esbuild": "^0.18.10",
"postcss": "^8.4.27",
"rollup": "^3.27.1"
},
"bin": {
"vite": "bin/vite.js"
},
"engines": {
"node": "^14.18.0 || >=16.0.0"
},
"funding": {
"url": "https://github.com/vitejs/vite?sponsor=1"
},
"optionalDependencies": {
"fsevents": "~2.3.2"
},
"peerDependencies": {
"@types/node": ">= 14",
"less": "*",
"lightningcss": "^1.21.0",
"sass": "*",
"stylus": "*",
"sugarss": "*",
"terser": "^5.4.0"
},
"peerDependenciesMeta": {
"@types/node": {
"optional": true
},
"less": {
"optional": true
},
"lightningcss": {
"optional": true
},
"sass": {
"optional": true
},
"stylus": {
"optional": true
},
"sugarss": {
"optional": true
},
"terser": {
"optional": true
}
}
}
}
}
+17
View File
@@ -0,0 +1,17 @@
{
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0",
"swiper": "^10.0.0"
},
"devDependencies": {
"vite": "^4.0.4"
},
"name": "portfolio",
"version": "0.0.1",
"scripts": {
"build": "vite build",
"dev": "vite",
"start": "vite"
}
}
BIN
View File
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 739 KiB

-17564
View File
File diff suppressed because it is too large Load Diff
-32
View File
@@ -1,32 +0,0 @@
{
"name": "react.dev",
"version": "0.0.0",
"main": "/src/index.js",
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
},
"dependencies": {
"bootstrap": "^5.3.3",
"react": "19.0.0-rc-3edc000d-20240926",
"react-bootstrap": "^2.10.7",
"react-dom": "19.0.0-rc-3edc000d-20240926",
"react-icons": "^5.4.0",
"react-router": "^7.0.2",
"react-scripts": "^5.0.0"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

-11
View File
@@ -1,11 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Josh Ashton</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
-13
View File
@@ -1,13 +0,0 @@
import Navigation from './components/Navigation';
import Footer from './components/Footer';
import Splash from './components/Splash';
export default function About() {
return (
<>
<Navigation />
<Splash primaryText="Under Construction" />
<Footer />
</>
);
}
-13
View File
@@ -1,13 +0,0 @@
import Navigation from './components/Navigation';
import Footer from './components/Footer';
import Splash from './components/Splash';
export default function Blog() {
return (
<>
<Navigation />
<Splash primaryText="Under Construction" />
<Footer />
</>
);
}
-13
View File
@@ -1,13 +0,0 @@
import Navigation from './components/Navigation';
import Footer from './components/Footer';
import Splash from './components/Splash';
export default function Contact() {
return (
<>
<Navigation />
<Splash primaryText="Under Construction" />
<Footer />
</>
);
}
-34
View File
@@ -1,34 +0,0 @@
import Navigation from './components/Navigation';
import Splash from './components/Splash';
import ProjectCard from './components/ProjectCard';
import Footer from './components/Footer';
import FeaturedContent from './components/FeaturedContent';
export default function Home( {projects} ) {
const projectCards = projects.map((project) => {
// Create a new ProjectCard object for each project in the 'projects' array
return (
<ProjectCard
key={project.id} // Add a unique key for each ProjectCard
frontend={project.frontend}
backend={project.backend}
id={project.id}
name={project.name}
description={project.description}
url={project.url}
img={project.img}
/>
);
});
return (
<>
<Navigation />
<Splash primaryText="Hi, I'm Josh Ashton!" secondaryText="Junior full stack developer."/>
<div className="row custom-container cards">
<h3 className="light-text">Featured Projects</h3>
<FeaturedContent content={projectCards} />
</div>
<Footer />
</>
);
}
-13
View File
@@ -1,13 +0,0 @@
import Navigation from './components/Navigation';
import Splash from './components/Splash';
import Footer from './components/Footer';
export default function Home( {projects} ) {
return (
<>
<Navigation />
<Splash primaryText="404" secondaryText="This is not the page you're looking for."/>
<Footer />
</>
);
}
-35
View File
@@ -1,35 +0,0 @@
import Navigation from './components/Navigation';
import Footer from './components/Footer';
import ProjectCard from './components/ProjectCard';
/*
* The Projects page.
*
* @param String[] projects "An array of attributes, frontend, backend, id, name, description, url, img, and imgCaption"
*/
export default function Projects( {projects} ) {
const projectCards = projects.map((project) => {
// Create a new ProjectCard object for each project in the 'projects' array
return (
<ProjectCard
key={project.id} // Add a unique key for each ProjectCard
frontend={project.frontend}
backend={project.backend}
id={project.id}
name={project.name}
description={project.description}
url={project.url}
img={project.img}
/>
);
});
return (
<>
<Navigation />
<div className="project-grid">
{projectCards}
</div>
<Footer />
</>
);
}
-13
View File
@@ -1,13 +0,0 @@
import Navigation from './components/Navigation';
import Footer from './components/Footer';
import Splash from './components/Splash';
export default function Resume() {
return (
<>
<Navigation />
<Splash primaryText="Under Construction" />
<Footer />
</>
);
}
-21
View File
@@ -1,21 +0,0 @@
/*
* Expects an array of Cards to display in a responsive grid.
*
* @param ProjectCard[] content "An array of ProjectCards or other Cards."
* TODO: Need to implement dynamic grid layout.
* TODO: Need to implement dynamic number of content, based on content size.
*/
export default function FeaturedContent( {content} ) {
return (
<>
<div className="row flex-row">
<div className="col">
{content[0]}
</div>
<div className="col">
{content[1]}
</div>
</div>
</>
);
}
-43
View File
@@ -1,43 +0,0 @@
import { FaLinkedinIn } from 'react-icons/fa';
import { FaInstagram } from 'react-icons/fa';
import { FaTwitterinIn } from 'react-icons/fa';
import { FaThreadsIn } from 'react-icons/fa';
/**
*
*
* TODO: Need to add classes and styling.
* TODO: Need to add links.
*/
export default function Footer() {
return (
<footer className="footer">
<div className="footer-container">
<div className="row">
<div className="col-md-6">
<p>&copy; {new Date().getFullYear()} Josh Ashton</p>
</div>
<div className="col-md-6">
<ul className="social-links">
<li><a href="/">Home</a></li>
<li><a href="/projects">Projects</a></li>
<li><a href="/about">About</a></li>
<li><a href="/contact">Contact</a></li>
<li><a href="/resume">Resume</a></li>
<li><a href="/blog">Blog</a></li>
<li>
<a href="https://www.linkedin.com/in/joshuatashton/" target="_blank" rel="noopener noreferrer">
<FaLinkedinIn />
</a>
</li>
<li>
<a href="https://www.instagram.com/joshuatashton/" target="_blank" rel="noopener noreferrer">
<FaInstagram />
</a>
</li>
</ul>
</div>
</div>
</div>
</footer>
);
}
-47
View File
@@ -1,47 +0,0 @@
import React, { useState } from 'react';
import Nav from 'react-bootstrap/Nav';
import Button from 'react-bootstrap/Button';
/*
* Create a nav bar component.
*
* Use Bootstrap for styling.
*
* TODO: Add links as a prop.
*/
export default function Navigation() {
const [isNavbarCollapsed, setIsNavbarCollapsed] = useState(false);
const toggleNavbar = () => {
setIsNavbarCollapsed(!isNavbarCollapsed);
};
return (
<>
<nav className="navbar navbar-expand-lg navbar-light bg-light">
<a className="navbar-brand" href="/">Josh Ashton</a>
<button
className="navbar-toggler"
type="button"
onClick={toggleNavbar}
aria-controls="navbarNav"
aria-expanded={isNavbarCollapsed}
aria-label="Toggle navigation"
>
<span className="navbar-toggler-icon"></span>
</button>
<div
className={`collapse navbar-collapse ${isNavbarCollapsed ? 'show' : ''}`}
id="navbarNav"
>
<ul className="navbar-nav nav-fill w-100">
<a className="nav-link" href="/projects"><li className="nav-item">Projects</li></a>
<a className="nav-link" href="/about"><li className="nav-item">About</li></a>
<a className="nav-link" href="/contact"><li className="nav-item">Contact</li></a>
<a className="nav-link" href="/resume"><li className="nav-item">Resume</li></a>
<a className="nav-link" href="/blog"><li className="nav-item">Blog</li></a>
</ul>
</div>
</nav>
</>
);
}
-28
View File
@@ -1,28 +0,0 @@
/*
* Create a ProjectCard.
*
* @param String frontend "The frontend framework/library used for the project. Used for sorting/filtering."
* @param String backend "The backend framework/library used for the project. Used for sorting/filtering."
* @param String id "Lowercase string representation of the project name."
* @param String name "The name of the project."
* @param String description "A description of the project."
* @param String url "The URL for the repository of the project."
* @param String img "Path to an image."
* @param String imgCaption "Accessibile caption for the image."
*
* TODO: Add project keys.
*/
export default function ProjectCard( {frontend, backend, id, name, description, url, img, imgCaption} ) {
return (
<>
<div className={`card ${frontend} ${backend}`}>
<img className="card-img-top" src={img} alt={imgCaption}/>
<div className="card-body">
<h2 className="card-title dark-text">{name}</h2>
<p className="dark-text">{description}</p>
<a className = "btn btn-primary" target="_blank" href={url}>View Code on GitHub</a>
</div>
</div>
</>
);
}
-41
View File
@@ -1,41 +0,0 @@
import React, { useState } from 'react';
import Button from 'react-bootstrap/Button';
/*
* Create a clickable frame which expands to expose additional information on click.
*
* @param String id "Lowercase string representation of the project name."
* @param String name "The name of the project."
* @param String description "A description of the project."
* @param String url "The URL for the repository of the project."
*
* TODO: Need to implement onClick
*/
export default function ProjectDisplay( {frontend, backend, id, name, description, url} ) {
const [isDisplayCollapsed, setIsDisplayCollapsed] = useState(false);
const toggleDisplay = () => {
setIsDisplayCollapsed(!isDisplayCollapsed);
}
return (
<>
<div
className={`panel ${frontend} ${backend} ${isDisplayCollapsed ? 'open open-active' : ''}`}
id={id}
onClick={toggleDisplay}
aria-expanded={!isDisplayCollapsed} // Invert the condition for aria-expanded
>
<h3 className="label">{name}</h3>
{isDisplayCollapsed && ( // Conditionally render additional content
<>
<h4 className="label-text">{description}</h4>
<button type="button" className="btn btn-primary">
<a target="_blank" href={url}>
View Code on GitHub
</a>
</button>
</>
)}
</div>
</>
);
}
-18
View File
@@ -1,18 +0,0 @@
/*
* Create a splash screen.
*
* @param String primaryText "The headline (h1) text."
* @param String secondaryText "The byline (h2) text."
*
* TODO: Need to add classes and styling.
*/
export default function Splash( { primaryText, secondaryText }) {
return (
<>
<div className="custom-container" id="splash">
<h1 className="light-text">{primaryText}</h1>
<h2 className="light-text">{secondaryText}</h2>
</div>
</>
);
}
-79
View File
@@ -1,79 +0,0 @@
import React, { StrictMode } from "react";
import ReactDOM from "react-dom/client";
import { BrowserRouter, Routes, Route } from "react-router";
import 'bootstrap/dist/css/bootstrap.min.css';
import "./styles.css";
import Home from "./Home";
import Projects from "./Projects";
import Contact from "./Contact";
import About from "./About";
import Blog from "./Blog";
import Resume from "./Resume";
import PageNotFound from "./PageNotFound";
const root = document.getElementById("root");
/*
* TEMPLATE:
{
frontend: "",
backend: "",
id: "",
name: "",
description: "",
url: "",
img: "",
imgCaption: ""
},
*/
const projects = [
{
frontend: "java",
backend: "",
id: "graph",
name: "Graph",
description: "Interactive representation of a graph data structure.",
url: "https://github.com/quaxlyqueen/2420-graph-visualizer",
img: "/assets/img/graph.png",
imgCaption: "A screenshot of my graph data structure visualizer application."
},
{
frontend: "flutter",
backend: "go",
id: "one-ai",
name: "OneAI",
description: "An end-to-end deployment wrapper for Meta's Ollama.",
url: "https://github.com/quaxlyqueen/one-ai",
img: "/assets/img/one-ai.png",
imgCaption: "A screenshot of a conversation with a self-hosted artificial intelligence."
},
{
frontend: "java",
backend: "",
id: "dnd",
name: "D&D",
description: "A Dungeons and Dragons character builder app.",
url: "https://github.com/quaxlyqueen/dnd",
img: "/assets/img/dnd.png",
imgCaption: "A screenshot of my Dungeons and Dragons character builder application."
},
];
ReactDOM.createRoot(root).render(
<BrowserRouter>
<Routes>
<Route exact path="/" element={<Home projects={projects} />} />
<Route exact path="/projects" element={<Projects projects={projects} />} />
<Route exact path="/contact" element={<Contact />} />
<Route exact path="/about" element={<About />} />
<Route exact path="/blog" element={<Blog />} />
<Route exact path="/resume" element={<Resume />} />
<Route
path="*"
element={<PageNotFound />}
/>
</Routes>
</BrowserRouter>
);
-467
View File
@@ -1,467 +0,0 @@
:root {
--main-dark-color: #4A245E;
--main-offwhite-color: white;
--main-midtone-color: #9BC995;
--main-accent-color: #673283;
--secondary-accent-color: #98B9AB;
}
/* GENERAL */
body {
margin:0;
height:100vh;
background:
linear-gradient(
135deg,
hsl(279deg 33% 47%) 0%,
hsl(279deg 40% 33%) 39%,
hsl(279deg 62% 19%) 61%,
hsl(279deg 94% 7%) 100%
);
background-size:300% 100%,cover;
animation:change 4s linear infinite;
animation-direction: alternate;
background-attachment: fixed;
}
@keyframes change {
from {
background-position: right,center;
}
}
/* TEXT */
* {
font-family: Lato, sans-serif;
color: white;
}
h1, h2 {
font-weight: bold;
margin: 0;
}
h1 {
margin: 5vw 0 5vw 0;
font-size: 8vw;
}
h2 {
font-size: 4vw;
}
h3 {
font-size: 3vw;
}
h4 {
font-size: 2vw;
}
p {
font-size: 1vw;
}
.dark-text {
color: var(--main-dark-color);
}
.light-text {
color: var(--main-offwhite-color);
}
.label {
font-size: 2vw;
}
.label-text {
font-size: 1.5vw;
max-width: 80%;
text-align: center;
--white-space: nowrap;
--overflow: hidden;
--text-overflow: ellipsis;
}
/* NAV-BAR */
.bg-light {
background-color: white !important;
padding: 0;
}
.navbar-brand {
padding-left: .5vw;
color: var(--main-dark-color);
font-size: 2vw;
font-weight: bold;
animation: 500ms;
}
.navbar-toggler {
border: none;
}
.navbar-toggler:focus {
box-shadow: none;
border:none;
}
.navbar-light .navbar-toggler-icon {
background-image: url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(74, 36, 94, 1)' stroke-width='3.5' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E");
}
.navbar-brand:hover {
color: var(--main-dark-color);
}
.nav-link {
padding: 1.5vw;
}
.nav-link, .nav-link > .nav-item {
color: var(--main-dark-color);
font-size: 1.3vw;
animation: 500ms;
}
.nav-link:hover, .nav-link:hover > .nav-item {
color: var(--main-offwhite-color);
}
.nav-link:hover {
background-color: var(--main-dark-color);
}
.bar {
display: block;
width: 100%;
border-top: 5px var(--main-dark-color) solid;
padding-bottom: 1vw;
}
.carousel {
float: left;
margin-top: 5vw;
width: 55% !important;
}
input {
padding: 1em;
margin: .5em;
font-size: 1.2em;
}
.search {
padding: 1vw;
background-color: var(--main-dark-color);
color: var(--main-offwhite-color);
}
label, label {
display: inline-block;
border: 2px solid var(--main-offwhite-color);
border-radius: 5px;
text-align: center;
padding: .5em;
margin: 0 2em 1em 2em;
transition: 500ms;
}
input[type="radio"] {
opacity: 0;
position: fixed;
width: 0;
}
input[type="radio"]:checked + label {
background-color: var(--main-offwhite-color);
color: var(--main-dark-color);
}
input[type="radio"]:hover + label {
background-color: var(--main-offwhite-color);
color: var(--main-dark-color);
}
.panels {
flex: 1;
--overflow: hidden;
}
.panel {
max-height: 6.5vw;
background: var(--main-dark-color);
box-shadow: inset 0 0 0 5px rgba(255, 255, 255, 0.05);
color: var(--main-offwhite-color);
transition:
font-size 500ms,
flex 500ms,
padding 500ms,
max-height 750ms;
font-size: 2.5em;
background-position: center;
display: flex;
flex-direction: column;
overflow: hidden;
}
.panel > * {
width: 100%;
transition: transform 800ms;
flex: 1 0 auto;
display: flex;
justify-content: center;
align-items: center;
}
.panel > *:nth-child(2) {
transform: translateX(-1000%);
}
.panel.open-active > *:nth-child(2) {
transform: translateX(12.5%);
}
.panel > *:last-child {
transform: translateX(-1000%);
transition: 800ms;
}
.panel.open-active > *:last-child {
transform: translateX(50%);
transition: 800ms;
}
.panel h3 {
font-family: Lato, sans-serif;
color: var(--main-offwhite-color);
font-size: 1.3em;
padding-top: 1vw;
}
.panel.open-active {
max-height: 20vw;
}
.panel.open {
overflow: visible;
flex: 5;
font-size: 2em;
}
.panel .label-text, .panel .btn {
display: none;
}
.panel.open .label-text, .panel.open .btn {
display: block;
}
.carousel-wrapper {
flex: 0 0 40%;
padding-top: 5vw;
}
.carousel {
float: right;
margin-top: 5vw;
width: 55%;
}
/* MISC */
.custom-container {
align-content: center;
padding: 5vw;
width: 90% !important;
margin-left: auto;
margin-right: auto;
}
.card {
display: flex; /* Enable flexbox layout */
flex-direction: column; /* Stack items vertically */
align-items: center; /* Center items horizontally */
justify-content: center; /* Center items vertically */
margin: 1vw;
}
.card img {
max-width: 50vw;
max-height: 35vw;
object-fit: cover;
}
.card-body {
text-align: center;
}
.card-text {
font-size: 2vw;
}
.flex-row {
display: flex; /* Enable flexbox layout */
height: 100%; /* Set the height of the container */
}
.flex-row > .col {
display: flex;
flex-direction: column; /* Ensure content flows vertically */
height: 100%; /* Make each column fill the container's height */
}
/*Buttons*/
.btn {
padding: 0.5vw;
background-color: var(--main-dark-color);
border: 2px solid var(--main-offwhite-color);
transition: background-color 300ms;
width: 50%;
margin-bottom: 1vw;
}
.btn:hover {
background-color: var(--main-accent-color);
}
.btn > a {
text-decoration: none;
color: var(--main-offwhite-color);
}
.footer-container {
margin-left: auto;
margin-right: auto;
width: 80% !important;
}
.social-links {
list-style: none; /* Remove default list styling */
display: flex; /* Display list items as flex items */
justify-content: space-between; /* Space items evenly */
}
.social-links li {
margin: 0 10px; /* Add spacing between icons */
}
.social-links li a {
text-decoration: none;
color: var(--main-offwhite-color);
}
.project-grid {
display: flex;
flex-wrap: wrap;
justify-content: space-between; /* Distribute projects evenly */
margin: 2vw auto; /* Center grid horizontally */
}
/* Responsive Breakpoints */
@media (min-width: 992px) { /* Large Screens (3 columns) */
.project-grid {
width: 80%; /* Adjust width as needed */
}
.project-grid > * {
flex: 0 0 30%; /* Set a fixed width for each project */
}
.footer-container .social-links {
width: 80% !important;
margin: 0;
padding-left: 0; /* Remove any left padding on mobile */
padding-right: 0; /* Remove any right padding on mobile */
}
}
@media (min-width: 768px) and (max-width: 991px) { /* Medium Screens (2 columns) */
.project-grid {
width: 80%; /* Adjust width as needed */
}
.project-grid > * {
flex: 0 0 40%; /* Set a fixed width for each project */
}
.footer-container .social-links {
width: 80% !important;
margin: 0;
padding-left: 0; /* Remove any left padding on mobile */
padding-right: 0; /* Remove any right padding on mobile */
}
}
@media (max-width: 767px) { /* Small Screens (1 column) */
.project-grid {
width: 80%;
}
.project-grid > * {
flex: 1 1 80%; /* Set full width for each project */
}
.footer-container .social-links {
width: 80% !important;
margin: 0;
padding-left: 0; /* Remove any left padding on mobile */
padding-right: 0; /* Remove any right padding on mobile */
}
.social-links li a {
font-size: 2vw;
}
h1 {
font-size: 8vw;
}
h2 {
font-size: 6vw;
}
h3, .navbar-brand {
font-size: 5vw;
}
h4 {
font-size: 3vw;
}
p, .nav-link, .nav-link > .nav-item {
font-size: 2vw;
}
}
@media (max-width: 991px) {
h1 {
font-size: 12vw;
}
h2 {
font-size: 8vw;
}
h3, .navbar-brand {
font-size: 6vw;
}
h4 {
font-size: 4vw;
}
p, .nav-link, .nav-link > .nav-item {
font-size: 3vw;
}
.nav-link > .nav-item {
font-weight: bold;
}
}
+22
View File
@@ -0,0 +1,22 @@
import React, { useRef, useState } from "react";
import VerticalSlider from "./components/VerticalSlider";
import "./styles.css";
export default function App() {
const data = [
{
title: "Test Header",
description: "A description of some length. Lorem ipsum this shit.",
color: "purple",
image: "/images/landscape.jpg",
alt: "A pretty background.",
},
{
title: "Another one",
description: "A description of some length. Lorem ipsum this shit.",
color: "purple",
image: "/images/landscape.jpg",
alt: "A pretty background.",
},
];
return <VerticalSlider slideData={data} />;
}
+47
View File
@@ -0,0 +1,47 @@
import React, { useRef, useState } from "react";
import { Swiper, SwiperSlide } from "swiper/react";
import { Mousewheel, Pagination } from "swiper/modules";
import "swiper/css";
import "swiper/css/pagination";
import "../styles.css";
export default function VerticalSlider({ slideData }) {
return (
<>
<Swiper
modules={[Mousewheel, Pagination]}
direction={"vertical"}
speed={800}
loop={true}
pagination={{
clickable: true,
}}
mousewheel={{
thresholdDelta: 50,
sensitivity: 1,
}}
>
{slideData.map((slide, index) => (
<SwiperSlide key={index}>
{({ isActive }) => (
<div className="slide-container">
<div className="info">
<h1 data-color={slide.color}>{slide.title}</h1>
<p>{slide.description}</p>
</div>
<div className="item">
<div
className={`circle ${isActive ? "animated-circle" : ""}`}
data-item={slide.color}
></div>
<img src={slide.image} alt={slide.alt} />
</div>
</div>
)}
</SwiperSlide>
))}
</Swiper>
</>
);
}
+6
View File
@@ -0,0 +1,6 @@
import React from "react";
import ReactDOM from "react-dom";
import App from "./App.jsx";
ReactDOM.render(<App />, document.getElementById("app"));
+261
View File
@@ -0,0 +1,261 @@
@import url("https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,100;0,300;0,400;0,700;0,900;1,100;1,300;1,400;1,700;1,900&display=swap");
:root {
--width: 480px;
}
*,
*::before,
*::after {
padding: 0;
margin: 0;
box-sizing: border-box;
font-family: "Lato", sans-serif;
}
html,
body {
position: relative;
height: 100%;
background: #222;
}
.swiper {
width: 100%;
height: 100vh;
overflow: hidden;
}
.swiper-slide .slide-container {
display: grid;
grid-template-columns: 48% 50%;
grid-template-rows: 100%;
column-gap: 30px;
height: 100%;
}
.info {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding-left: 120px;
text-align: center;
opacity: 0;
}
.info h1 {
font-size: clamp(2.25rem, 3.5vw, 8rem);
font-weight: 600;
letter-spacing: 2px;
width: max-content;
margin-bottom: 32px;
opacity: 0;
}
[data-color="purple"] {
color: #7385ca;
}
.info p {
font-size: clamp(1.1rem, 2vw, 1.5rem);
color: #bfbec1;
font-weight: 300;
line-height: 1.5;
opacity: 0;
}
.swiper-slide-active .info {
opacity: 1;
}
.swiper-slide-active .info h1,
.swiper-slide-active .info p {
animation: moveDown 0.8s ease-in forwards;
}
.swiper-slide-active .info h1 {
animation-delay: 0.2s;
}
.swiper-slide-active .info p {
animation-delay: 1s;
}
@keyframes moveDown {
0% {
transform: translateY(-20px);
opacity: 0;
}
100% {
transform: translateY(0);
opacity: 1;
}
}
.item {
position: relative;
display: flex;
align-items: center;
justify-content: center;
width: var(--width);
aspect-ratio: 1/1;
margin: auto;
}
.circle {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
border-radius: 50%;
overflow: hidden;
}
.circle[data-item="purple"] {
border: 1px solid #8092d9;
}
.circle::before {
content: "";
position: absolute;
left: 0;
width: 100%;
height: 0;
z-index: -1;
}
.circle[data-item="purple"]::before {
background: linear-gradient(
to left bottom,
#8092d9,
#677abf,
#4e63a6,
#344d8d,
#163875
);
}
.animated-circle::before {
animation: colorTransition 2s linear forwards;
}
@keyframes colorTransition {
0% {
height: 0;
top: -50%;
}
100% {
height: 100%;
top: 0%;
}
}
.swiper-slide img {
display: block;
width: calc(var(--width) / 2);
filter: drop-shadow(5px 6px 5px rgba(36, 36, 42, 0.5));
user-select: none;
opacity: 0;
z-index: 1;
}
.swiper-slide-active img {
animation: itemMoveDown 0.8s ease-in forwards 1.4s;
}
@keyframes itemMoveDown {
0% {
transform: translateY(calc(var(--width) / -5));
opacity: 0;
}
100% {
transform: translateY(0);
opacity: 1;
}
}
.swiper-paginatino-bullet {
width: 18px;
height: 18px;
background-color: #7e7e7e;
border-radius: 50%;
transition: all 0.6s ease-in-out;
}
.swiper-pagination-bullet-active {
height: 36px;
background-color: #717271;
border-radius: 14px;
}
@media (max-width: 1250px) {
.info {
padding-left: 90px;
}
}
@media (max-width: 1075px) {
:root {
--width: 400px;
}
.swiper-slide .slide-container {
column-gap: 20px;
}
.info {
padding-left: 60px;
}
}
@media (max-width: 990px) {
:root {
--width: 360px;
}
.info {
padding-left: 30px;
}
}
@media (max-width: 790px) {
.swiper-slide .slide-container {
grid-template-columns: 100%;
grid-template-rows: 60% 35%;
column-gap: 0;
grid-template-areas:
"item"
"info";
padding: 30px;
}
.item {
grid-area: item;
}
.info {
grid-area: info;
}
.info h1 {
margin-bottom: 16px;
width: unset;
line-height: 1.1;
}
.swiper-pagination-bullet {
width: 14px;
height: 14px;
}
.swiper-pagination-bullet-active {
height: 28px;
}
}
@media (max-width: 485px) {
:root {
--width: 280px;
}
.info p {
line-height: 1.4;
}
}