Initial Commit
@@ -1,11 +1,24 @@
|
|||||||
# ---> Vue
|
# Logs
|
||||||
# gitignore template for Vue.js projects
|
logs
|
||||||
#
|
*.log
|
||||||
# Recommended template: Node.gitignore
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
# TODO: where does this rule come from?
|
node_modules
|
||||||
docs/_book
|
dist
|
||||||
|
dist-ssr
|
||||||
# TODO: where does this rule come from?
|
*.local
|
||||||
test/
|
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/extensions.json
|
||||||
|
.idea
|
||||||
|
.DS_Store
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
||||||
|
|||||||
@@ -1,2 +1,5 @@
|
|||||||
# vue_portfolio
|
# Vue 3 + Vite
|
||||||
|
|
||||||
|
This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
|
||||||
|
|
||||||
|
Learn more about IDE Support for Vue in the [Vue Docs Scaling up Guide](https://vuejs.org/guide/scaling-up/tooling.html#ide-support).
|
||||||
|
|||||||
@@ -0,0 +1,294 @@
|
|||||||
|
{
|
||||||
|
"lockfileVersion": 1,
|
||||||
|
"workspaces": {
|
||||||
|
"": {
|
||||||
|
"name": "portfolio",
|
||||||
|
"dependencies": {
|
||||||
|
"@tailwindcss/vite": "^4.1.11",
|
||||||
|
"aos": "^2.3.4",
|
||||||
|
"emailjs-com": "^3.2.0",
|
||||||
|
"tailwindcss": "^4.1.11",
|
||||||
|
"vue": "^3.5.18",
|
||||||
|
"vue-toast-notification": "^3",
|
||||||
|
"vue3-carousel": "^0.16.0",
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@vitejs/plugin-vue": "^6.0.1",
|
||||||
|
"vite": "^7.1.2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"packages": {
|
||||||
|
"@ampproject/remapping": ["@ampproject/[email protected]", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw=="],
|
||||||
|
|
||||||
|
"@babel/helper-string-parser": ["@babel/[email protected]", "", {}, "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA=="],
|
||||||
|
|
||||||
|
"@babel/helper-validator-identifier": ["@babel/[email protected]", "", {}, "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow=="],
|
||||||
|
|
||||||
|
"@babel/parser": ["@babel/[email protected]", "", { "dependencies": { "@babel/types": "^7.28.0" }, "bin": "./bin/babel-parser.js" }, "sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g=="],
|
||||||
|
|
||||||
|
"@babel/types": ["@babel/[email protected]", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1" } }, "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ=="],
|
||||||
|
|
||||||
|
"@esbuild/aix-ppc64": ["@esbuild/[email protected]", "", { "os": "aix", "cpu": "ppc64" }, "sha512-OaGtL73Jck6pBKjNIe24BnFE6agGl+6KxDtTfHhy1HmhthfKouEcOhqpSL64K4/0WCtbKFLOdzD/44cJ4k9opA=="],
|
||||||
|
|
||||||
|
"@esbuild/android-arm": ["@esbuild/[email protected]", "", { "os": "android", "cpu": "arm" }, "sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ=="],
|
||||||
|
|
||||||
|
"@esbuild/android-arm64": ["@esbuild/[email protected]", "", { "os": "android", "cpu": "arm64" }, "sha512-IDrddSmpSv51ftWslJMvl3Q2ZT98fUSL2/rlUXuVqRXHCs5EUF1/f+jbjF5+NG9UffUDMCiTyh8iec7u8RlTLg=="],
|
||||||
|
|
||||||
|
"@esbuild/android-x64": ["@esbuild/[email protected]", "", { "os": "android", "cpu": "x64" }, "sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw=="],
|
||||||
|
|
||||||
|
"@esbuild/darwin-arm64": ["@esbuild/[email protected]", "", { "os": "darwin", "cpu": "arm64" }, "sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg=="],
|
||||||
|
|
||||||
|
"@esbuild/darwin-x64": ["@esbuild/[email protected]", "", { "os": "darwin", "cpu": "x64" }, "sha512-jhHfBzjYTA1IQu8VyrjCX4ApJDnH+ez+IYVEoJHeqJm9VhG9Dh2BYaJritkYK3vMaXrf7Ogr/0MQ8/MeIefsPQ=="],
|
||||||
|
|
||||||
|
"@esbuild/freebsd-arm64": ["@esbuild/[email protected]", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-z93DmbnY6fX9+KdD4Ue/H6sYs+bhFQJNCPZsi4XWJoYblUqT06MQUdBCpcSfuiN72AbqeBFu5LVQTjfXDE2A6Q=="],
|
||||||
|
|
||||||
|
"@esbuild/freebsd-x64": ["@esbuild/[email protected]", "", { "os": "freebsd", "cpu": "x64" }, "sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg=="],
|
||||||
|
|
||||||
|
"@esbuild/linux-arm": ["@esbuild/[email protected]", "", { "os": "linux", "cpu": "arm" }, "sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw=="],
|
||||||
|
|
||||||
|
"@esbuild/linux-arm64": ["@esbuild/[email protected]", "", { "os": "linux", "cpu": "arm64" }, "sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw=="],
|
||||||
|
|
||||||
|
"@esbuild/linux-ia32": ["@esbuild/[email protected]", "", { "os": "linux", "cpu": "ia32" }, "sha512-e7S3MOJPZGp2QW6AK6+Ly81rC7oOSerQ+P8L0ta4FhVi+/j/v2yZzx5CqqDaWjtPFfYz21Vi1S0auHrap3Ma3A=="],
|
||||||
|
|
||||||
|
"@esbuild/linux-loong64": ["@esbuild/[email protected]", "", { "os": "linux", "cpu": "none" }, "sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ=="],
|
||||||
|
|
||||||
|
"@esbuild/linux-mips64el": ["@esbuild/[email protected]", "", { "os": "linux", "cpu": "none" }, "sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA=="],
|
||||||
|
|
||||||
|
"@esbuild/linux-ppc64": ["@esbuild/[email protected]", "", { "os": "linux", "cpu": "ppc64" }, "sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w=="],
|
||||||
|
|
||||||
|
"@esbuild/linux-riscv64": ["@esbuild/[email protected]", "", { "os": "linux", "cpu": "none" }, "sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg=="],
|
||||||
|
|
||||||
|
"@esbuild/linux-s390x": ["@esbuild/[email protected]", "", { "os": "linux", "cpu": "s390x" }, "sha512-Mfiphvp3MjC/lctb+7D287Xw1DGzqJPb/J2aHHcHxflUo+8tmN/6d4k6I2yFR7BVo5/g7x2Monq4+Yew0EHRIA=="],
|
||||||
|
|
||||||
|
"@esbuild/linux-x64": ["@esbuild/[email protected]", "", { "os": "linux", "cpu": "x64" }, "sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg=="],
|
||||||
|
|
||||||
|
"@esbuild/netbsd-arm64": ["@esbuild/[email protected]", "", { "os": "none", "cpu": "arm64" }, "sha512-9jNJl6FqaUG+COdQMjSCGW4QiMHH88xWbvZ+kRVblZsWrkXlABuGdFJ1E9L7HK+T0Yqd4akKNa/lO0+jDxQD4Q=="],
|
||||||
|
|
||||||
|
"@esbuild/netbsd-x64": ["@esbuild/[email protected]", "", { "os": "none", "cpu": "x64" }, "sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g=="],
|
||||||
|
|
||||||
|
"@esbuild/openbsd-arm64": ["@esbuild/[email protected]", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-YaFBlPGeDasft5IIM+CQAhJAqS3St3nJzDEgsgFixcfZeyGPCd6eJBWzke5piZuZ7CtL656eOSYKk4Ls2C0FRQ=="],
|
||||||
|
|
||||||
|
"@esbuild/openbsd-x64": ["@esbuild/[email protected]", "", { "os": "openbsd", "cpu": "x64" }, "sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA=="],
|
||||||
|
|
||||||
|
"@esbuild/openharmony-arm64": ["@esbuild/[email protected]", "", { "os": "none", "cpu": "arm64" }, "sha512-4Xd0xNiMVXKh6Fa7HEJQbrpP3m3DDn43jKxMjxLLRjWnRsfxjORYJlXPO4JNcXtOyfajXorRKY9NkOpTHptErg=="],
|
||||||
|
|
||||||
|
"@esbuild/sunos-x64": ["@esbuild/[email protected]", "", { "os": "sunos", "cpu": "x64" }, "sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw=="],
|
||||||
|
|
||||||
|
"@esbuild/win32-arm64": ["@esbuild/[email protected]", "", { "os": "win32", "cpu": "arm64" }, "sha512-mGFrVJHmZiRqmP8xFOc6b84/7xa5y5YvR1x8djzXpJBSv/UsNK6aqec+6JDjConTgvvQefdGhFDAs2DLAds6gQ=="],
|
||||||
|
|
||||||
|
"@esbuild/win32-ia32": ["@esbuild/[email protected]", "", { "os": "win32", "cpu": "ia32" }, "sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww=="],
|
||||||
|
|
||||||
|
"@esbuild/win32-x64": ["@esbuild/[email protected]", "", { "os": "win32", "cpu": "x64" }, "sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ=="],
|
||||||
|
|
||||||
|
"@isaacs/fs-minipass": ["@isaacs/[email protected]", "", { "dependencies": { "minipass": "^7.0.4" } }, "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w=="],
|
||||||
|
|
||||||
|
"@jridgewell/gen-mapping": ["@jridgewell/[email protected]", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="],
|
||||||
|
|
||||||
|
"@jridgewell/resolve-uri": ["@jridgewell/[email protected]", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="],
|
||||||
|
|
||||||
|
"@jridgewell/sourcemap-codec": ["@jridgewell/[email protected]", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="],
|
||||||
|
|
||||||
|
"@jridgewell/trace-mapping": ["@jridgewell/[email protected]", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q=="],
|
||||||
|
|
||||||
|
"@rolldown/pluginutils": ["@rolldown/[email protected]", "", {}, "sha512-NIJgOsMjbxAXvoGq/X0gD7VPMQ8j9g0BiDaNjVNVjvl+iKXxL3Jre0v31RmBYeLEmkbj2s02v8vFTbUXi5XS2Q=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-android-arm-eabi": ["@rollup/[email protected]", "", { "os": "android", "cpu": "arm" }, "sha512-Zj3Hl6sN34xJtMv7Anwb5Gu01yujyE/cLBDB2gnHTAHaWS1Z38L7kuSG+oAh0giZMqG060f/YBStXtMH6FvPMA=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-android-arm64": ["@rollup/[email protected]", "", { "os": "android", "cpu": "arm64" }, "sha512-nTeCWY83kN64oQ5MGz3CgtPx8NSOhC5lWtsjTs+8JAJNLcP3QbLCtDDgUKQc/Ro/frpMq4SHUaHN6AMltcEoLQ=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-darwin-arm64": ["@rollup/[email protected]", "", { "os": "darwin", "cpu": "arm64" }, "sha512-HV7bW2Fb/F5KPdM/9bApunQh68YVDU8sO8BvcW9OngQVN3HHHkw99wFupuUJfGR9pYLLAjcAOA6iO+evsbBaPQ=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-darwin-x64": ["@rollup/[email protected]", "", { "os": "darwin", "cpu": "x64" }, "sha512-SSj8TlYV5nJixSsm/y3QXfhspSiLYP11zpfwp6G/YDXctf3Xkdnk4woJIF5VQe0of2OjzTt8EsxnJDCdHd2xMA=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-freebsd-arm64": ["@rollup/[email protected]", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-ZyrsG4TIT9xnOlLsSSi9w/X29tCbK1yegE49RYm3tu3wF1L/B6LVMqnEWyDB26d9Ecx9zrmXCiPmIabVuLmNSg=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-freebsd-x64": ["@rollup/[email protected]", "", { "os": "freebsd", "cpu": "x64" }, "sha512-pCgHFoOECwVCJ5GFq8+gR8SBKnMO+xe5UEqbemxBpCKYQddRQMgomv1104RnLSg7nNvgKy05sLsY51+OVRyiVw=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-arm-gnueabihf": ["@rollup/[email protected]", "", { "os": "linux", "cpu": "arm" }, "sha512-EtP8aquZ0xQg0ETFcxUbU71MZlHaw9MChwrQzatiE8U/bvi5uv/oChExXC4mWhjiqK7azGJBqU0tt5H123SzVA=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-arm-musleabihf": ["@rollup/[email protected]", "", { "os": "linux", "cpu": "arm" }, "sha512-qO7F7U3u1nfxYRPM8HqFtLd+raev2K137dsV08q/LRKRLEc7RsiDWihUnrINdsWQxPR9jqZ8DIIZ1zJJAm5PjQ=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-arm64-gnu": ["@rollup/[email protected]", "", { "os": "linux", "cpu": "arm64" }, "sha512-3dRaqLfcOXYsfvw5xMrxAk9Lb1f395gkoBYzSFcc/scgRFptRXL9DOaDpMiehf9CO8ZDRJW2z45b6fpU5nwjng=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-arm64-musl": ["@rollup/[email protected]", "", { "os": "linux", "cpu": "arm64" }, "sha512-fhHFTutA7SM+IrR6lIfiHskxmpmPTJUXpWIsBXpeEwNgZzZZSg/q4i6FU4J8qOGyJ0TR+wXBwx/L7Ho9z0+uDg=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-loongarch64-gnu": ["@rollup/[email protected]", "", { "os": "linux", "cpu": "none" }, "sha512-i7wfGFXu8x4+FRqPymzjD+Hyav8l95UIZ773j7J7zRYc3Xsxy2wIn4x+llpunexXe6laaO72iEjeeGyUFmjKeA=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-ppc64-gnu": ["@rollup/[email protected]", "", { "os": "linux", "cpu": "ppc64" }, "sha512-B/l0dFcHVUnqcGZWKcWBSV2PF01YUt0Rvlurci5P+neqY/yMKchGU8ullZvIv5e8Y1C6wOn+U03mrDylP5q9Yw=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-riscv64-gnu": ["@rollup/[email protected]", "", { "os": "linux", "cpu": "none" }, "sha512-32k4ENb5ygtkMwPMucAb8MtV8olkPT03oiTxJbgkJa7lJ7dZMr0GCFJlyvy+K8iq7F/iuOr41ZdUHaOiqyR3iQ=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-riscv64-musl": ["@rollup/[email protected]", "", { "os": "linux", "cpu": "none" }, "sha512-t5B2loThlFEauloaQkZg9gxV05BYeITLvLkWOkRXogP4qHXLkWSbSHKM9S6H1schf/0YGP/qNKtiISlxvfmmZw=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-s390x-gnu": ["@rollup/[email protected]", "", { "os": "linux", "cpu": "s390x" }, "sha512-YKjekwTEKgbB7n17gmODSmJVUIvj8CX7q5442/CK80L8nqOUbMtf8b01QkG3jOqyr1rotrAnW6B/qiHwfcuWQA=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-x64-gnu": ["@rollup/[email protected]", "", { "os": "linux", "cpu": "x64" }, "sha512-Jj5a9RUoe5ra+MEyERkDKLwTXVu6s3aACP51nkfnK9wJTraCC8IMe3snOfALkrjTYd2G1ViE1hICj0fZ7ALBPA=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-x64-musl": ["@rollup/[email protected]", "", { "os": "linux", "cpu": "x64" }, "sha512-7kX69DIrBeD7yNp4A5b81izs8BqoZkCIaxQaOpumcJ1S/kmqNFjPhDu1LHeVXv0SexfHQv5cqHsxLOjETuqDuA=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-win32-arm64-msvc": ["@rollup/[email protected]", "", { "os": "win32", "cpu": "arm64" }, "sha512-wiJWMIpeaak/jsbaq2HMh/rzZxHVW1rU6coyeNNpMwk5isiPjSTx0a4YLSlYDwBH/WBvLz+EtsNqQScZTLJy3g=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-win32-ia32-msvc": ["@rollup/[email protected]", "", { "os": "win32", "cpu": "ia32" }, "sha512-gBgaUDESVzMgWZhcyjfs9QFK16D8K6QZpwAaVNJxYDLHWayOta4ZMjGm/vsAEy3hvlS2GosVFlBlP9/Wb85DqQ=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-win32-x64-msvc": ["@rollup/[email protected]", "", { "os": "win32", "cpu": "x64" }, "sha512-CvUo2ixeIQGtF6WvuB87XWqPQkoFAFqW+HUo/WzHwuHDvIwZCtjdWXoYCcr06iKGydiqTclC4jU/TNObC/xKZg=="],
|
||||||
|
|
||||||
|
"@tailwindcss/node": ["@tailwindcss/[email protected]", "", { "dependencies": { "@ampproject/remapping": "^2.3.0", "enhanced-resolve": "^5.18.1", "jiti": "^2.4.2", "lightningcss": "1.30.1", "magic-string": "^0.30.17", "source-map-js": "^1.2.1", "tailwindcss": "4.1.11" } }, "sha512-yzhzuGRmv5QyU9qLNg4GTlYI6STedBWRE7NjxP45CsFYYq9taI0zJXZBMqIC/c8fViNLhmrbpSFS57EoxUmD6Q=="],
|
||||||
|
|
||||||
|
"@tailwindcss/oxide": ["@tailwindcss/[email protected]", "", { "dependencies": { "detect-libc": "^2.0.4", "tar": "^7.4.3" }, "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.1.11", "@tailwindcss/oxide-darwin-arm64": "4.1.11", "@tailwindcss/oxide-darwin-x64": "4.1.11", "@tailwindcss/oxide-freebsd-x64": "4.1.11", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.11", "@tailwindcss/oxide-linux-arm64-gnu": "4.1.11", "@tailwindcss/oxide-linux-arm64-musl": "4.1.11", "@tailwindcss/oxide-linux-x64-gnu": "4.1.11", "@tailwindcss/oxide-linux-x64-musl": "4.1.11", "@tailwindcss/oxide-wasm32-wasi": "4.1.11", "@tailwindcss/oxide-win32-arm64-msvc": "4.1.11", "@tailwindcss/oxide-win32-x64-msvc": "4.1.11" } }, "sha512-Q69XzrtAhuyfHo+5/HMgr1lAiPP/G40OMFAnws7xcFEYqcypZmdW8eGXaOUIeOl1dzPJBPENXgbjsOyhg2nkrg=="],
|
||||||
|
|
||||||
|
"@tailwindcss/oxide-android-arm64": ["@tailwindcss/[email protected]", "", { "os": "android", "cpu": "arm64" }, "sha512-3IfFuATVRUMZZprEIx9OGDjG3Ou3jG4xQzNTvjDoKmU9JdmoCohQJ83MYd0GPnQIu89YoJqvMM0G3uqLRFtetg=="],
|
||||||
|
|
||||||
|
"@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/[email protected]", "", { "os": "darwin", "cpu": "arm64" }, "sha512-ESgStEOEsyg8J5YcMb1xl8WFOXfeBmrhAwGsFxxB2CxY9evy63+AtpbDLAyRkJnxLy2WsD1qF13E97uQyP1lfQ=="],
|
||||||
|
|
||||||
|
"@tailwindcss/oxide-darwin-x64": ["@tailwindcss/[email protected]", "", { "os": "darwin", "cpu": "x64" }, "sha512-EgnK8kRchgmgzG6jE10UQNaH9Mwi2n+yw1jWmof9Vyg2lpKNX2ioe7CJdf9M5f8V9uaQxInenZkOxnTVL3fhAw=="],
|
||||||
|
|
||||||
|
"@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/[email protected]", "", { "os": "freebsd", "cpu": "x64" }, "sha512-xdqKtbpHs7pQhIKmqVpxStnY1skuNh4CtbcyOHeX1YBE0hArj2romsFGb6yUmzkq/6M24nkxDqU8GYrKrz+UcA=="],
|
||||||
|
|
||||||
|
"@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/[email protected]", "", { "os": "linux", "cpu": "arm" }, "sha512-ryHQK2eyDYYMwB5wZL46uoxz2zzDZsFBwfjssgB7pzytAeCCa6glsiJGjhTEddq/4OsIjsLNMAiMlHNYnkEEeg=="],
|
||||||
|
|
||||||
|
"@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/[email protected]", "", { "os": "linux", "cpu": "arm64" }, "sha512-mYwqheq4BXF83j/w75ewkPJmPZIqqP1nhoghS9D57CLjsh3Nfq0m4ftTotRYtGnZd3eCztgbSPJ9QhfC91gDZQ=="],
|
||||||
|
|
||||||
|
"@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/[email protected]", "", { "os": "linux", "cpu": "arm64" }, "sha512-m/NVRFNGlEHJrNVk3O6I9ggVuNjXHIPoD6bqay/pubtYC9QIdAMpS+cswZQPBLvVvEF6GtSNONbDkZrjWZXYNQ=="],
|
||||||
|
|
||||||
|
"@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/[email protected]", "", { "os": "linux", "cpu": "x64" }, "sha512-YW6sblI7xukSD2TdbbaeQVDysIm/UPJtObHJHKxDEcW2exAtY47j52f8jZXkqE1krdnkhCMGqP3dbniu1Te2Fg=="],
|
||||||
|
|
||||||
|
"@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/[email protected]", "", { "os": "linux", "cpu": "x64" }, "sha512-e3C/RRhGunWYNC3aSF7exsQkdXzQ/M+aYuZHKnw4U7KQwTJotnWsGOIVih0s2qQzmEzOFIJ3+xt7iq67K/p56Q=="],
|
||||||
|
|
||||||
|
"@tailwindcss/oxide-wasm32-wasi": ["@tailwindcss/[email protected]", "", { "dependencies": { "@emnapi/core": "^1.4.3", "@emnapi/runtime": "^1.4.3", "@emnapi/wasi-threads": "^1.0.2", "@napi-rs/wasm-runtime": "^0.2.11", "@tybys/wasm-util": "^0.9.0", "tslib": "^2.8.0" }, "cpu": "none" }, "sha512-Xo1+/GU0JEN/C/dvcammKHzeM6NqKovG+6921MR6oadee5XPBaKOumrJCXvopJ/Qb5TH7LX/UAywbqrP4lax0g=="],
|
||||||
|
|
||||||
|
"@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/[email protected]", "", { "os": "win32", "cpu": "arm64" }, "sha512-UgKYx5PwEKrac3GPNPf6HVMNhUIGuUh4wlDFR2jYYdkX6pL/rn73zTq/4pzUm8fOjAn5L8zDeHp9iXmUGOXZ+w=="],
|
||||||
|
|
||||||
|
"@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/[email protected]", "", { "os": "win32", "cpu": "x64" }, "sha512-YfHoggn1j0LK7wR82TOucWc5LDCguHnoS879idHekmmiR7g9HUtMw9MI0NHatS28u/Xlkfi9w5RJWgz2Dl+5Qg=="],
|
||||||
|
|
||||||
|
"@tailwindcss/vite": ["@tailwindcss/[email protected]", "", { "dependencies": { "@tailwindcss/node": "4.1.11", "@tailwindcss/oxide": "4.1.11", "tailwindcss": "4.1.11" }, "peerDependencies": { "vite": "^5.2.0 || ^6 || ^7" } }, "sha512-RHYhrR3hku0MJFRV+fN2gNbDNEh3dwKvY8XJvTxCSXeMOsCRSr+uKvDWQcbizrHgjML6ZmTE5OwMrl5wKcujCw=="],
|
||||||
|
|
||||||
|
"@types/estree": ["@types/[email protected]", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="],
|
||||||
|
|
||||||
|
"@vitejs/plugin-vue": ["@vitejs/[email protected]", "", { "dependencies": { "@rolldown/pluginutils": "1.0.0-beta.29" }, "peerDependencies": { "vite": "^5.0.0 || ^6.0.0 || ^7.0.0", "vue": "^3.2.25" } }, "sha512-+MaE752hU0wfPFJEUAIxqw18+20euHHdxVtMvbFcOEpjEyfqXH/5DCoTHiVJ0J29EhTJdoTkjEv5YBKU9dnoTw=="],
|
||||||
|
|
||||||
|
"@vue/compiler-core": ["@vue/[email protected]", "", { "dependencies": { "@babel/parser": "^7.28.0", "@vue/shared": "3.5.18", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.1" } }, "sha512-3slwjQrrV1TO8MoXgy3aynDQ7lslj5UqDxuHnrzHtpON5CBinhWjJETciPngpin/T3OuW3tXUf86tEurusnztw=="],
|
||||||
|
|
||||||
|
"@vue/compiler-dom": ["@vue/[email protected]", "", { "dependencies": { "@vue/compiler-core": "3.5.18", "@vue/shared": "3.5.18" } }, "sha512-RMbU6NTU70++B1JyVJbNbeFkK+A+Q7y9XKE2EM4NLGm2WFR8x9MbAtWxPPLdm0wUkuZv9trpwfSlL6tjdIa1+A=="],
|
||||||
|
|
||||||
|
"@vue/compiler-sfc": ["@vue/[email protected]", "", { "dependencies": { "@babel/parser": "^7.28.0", "@vue/compiler-core": "3.5.18", "@vue/compiler-dom": "3.5.18", "@vue/compiler-ssr": "3.5.18", "@vue/shared": "3.5.18", "estree-walker": "^2.0.2", "magic-string": "^0.30.17", "postcss": "^8.5.6", "source-map-js": "^1.2.1" } }, "sha512-5aBjvGqsWs+MoxswZPoTB9nSDb3dhd1x30xrrltKujlCxo48j8HGDNj3QPhF4VIS0VQDUrA1xUfp2hEa+FNyXA=="],
|
||||||
|
|
||||||
|
"@vue/compiler-ssr": ["@vue/[email protected]", "", { "dependencies": { "@vue/compiler-dom": "3.5.18", "@vue/shared": "3.5.18" } }, "sha512-xM16Ak7rSWHkM3m22NlmcdIM+K4BMyFARAfV9hYFl+SFuRzrZ3uGMNW05kA5pmeMa0X9X963Kgou7ufdbpOP9g=="],
|
||||||
|
|
||||||
|
"@vue/reactivity": ["@vue/[email protected]", "", { "dependencies": { "@vue/shared": "3.5.18" } }, "sha512-x0vPO5Imw+3sChLM5Y+B6G1zPjwdOri9e8V21NnTnlEvkxatHEH5B5KEAJcjuzQ7BsjGrKtfzuQ5eQwXh8HXBg=="],
|
||||||
|
|
||||||
|
"@vue/runtime-core": ["@vue/[email protected]", "", { "dependencies": { "@vue/reactivity": "3.5.18", "@vue/shared": "3.5.18" } }, "sha512-DUpHa1HpeOQEt6+3nheUfqVXRog2kivkXHUhoqJiKR33SO4x+a5uNOMkV487WPerQkL0vUuRvq/7JhRgLW3S+w=="],
|
||||||
|
|
||||||
|
"@vue/runtime-dom": ["@vue/[email protected]", "", { "dependencies": { "@vue/reactivity": "3.5.18", "@vue/runtime-core": "3.5.18", "@vue/shared": "3.5.18", "csstype": "^3.1.3" } }, "sha512-YwDj71iV05j4RnzZnZtGaXwPoUWeRsqinblgVJwR8XTXYZ9D5PbahHQgsbmzUvCWNF6x7siQ89HgnX5eWkr3mw=="],
|
||||||
|
|
||||||
|
"@vue/server-renderer": ["@vue/[email protected]", "", { "dependencies": { "@vue/compiler-ssr": "3.5.18", "@vue/shared": "3.5.18" }, "peerDependencies": { "vue": "3.5.18" } }, "sha512-PvIHLUoWgSbDG7zLHqSqaCoZvHi6NNmfVFOqO+OnwvqMz/tqQr3FuGWS8ufluNddk7ZLBJYMrjcw1c6XzR12mA=="],
|
||||||
|
|
||||||
|
"@vue/shared": ["@vue/[email protected]", "", {}, "sha512-cZy8Dq+uuIXbxCZpuLd2GJdeSO/lIzIspC2WtkqIpje5QyFbvLaI5wZtdUjLHjGZrlVX6GilejatWwVYYRc8tA=="],
|
||||||
|
|
||||||
|
"aos": ["[email protected]", "", { "dependencies": { "classlist-polyfill": "^1.0.3", "lodash.debounce": "^4.0.6", "lodash.throttle": "^4.0.1" } }, "sha512-zh/ahtR2yME4I51z8IttIt4lC1Nw0ktsFtmeDzID1m9naJnWXhCoARaCgNOGXb5CLy3zm+wqmRAEgMYB5E2HUw=="],
|
||||||
|
|
||||||
|
"chownr": ["[email protected]", "", {}, "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g=="],
|
||||||
|
|
||||||
|
"classlist-polyfill": ["[email protected]", "", {}, "sha512-GzIjNdcEtH4ieA2S8NmrSxv7DfEV5fmixQeyTmqmRmRJPGpRBaSnA2a0VrCjyT8iW8JjEdMbKzDotAJf+ajgaQ=="],
|
||||||
|
|
||||||
|
"csstype": ["[email protected]", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],
|
||||||
|
|
||||||
|
"detect-libc": ["[email protected]", "", {}, "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA=="],
|
||||||
|
|
||||||
|
"emailjs-com": ["[email protected]", "", {}, "sha512-Prbz3E1usiAwGjMNYRv6EsJ5c373cX7/AGnZQwOfrpNJrygQJ15+E9OOq4pU8yC977Z5xMetRfc3WmDX6RcjAA=="],
|
||||||
|
|
||||||
|
"enhanced-resolve": ["[email protected]", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" } }, "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww=="],
|
||||||
|
|
||||||
|
"entities": ["[email protected]", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
|
||||||
|
|
||||||
|
"esbuild": ["[email protected]", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.9", "@esbuild/android-arm": "0.25.9", "@esbuild/android-arm64": "0.25.9", "@esbuild/android-x64": "0.25.9", "@esbuild/darwin-arm64": "0.25.9", "@esbuild/darwin-x64": "0.25.9", "@esbuild/freebsd-arm64": "0.25.9", "@esbuild/freebsd-x64": "0.25.9", "@esbuild/linux-arm": "0.25.9", "@esbuild/linux-arm64": "0.25.9", "@esbuild/linux-ia32": "0.25.9", "@esbuild/linux-loong64": "0.25.9", "@esbuild/linux-mips64el": "0.25.9", "@esbuild/linux-ppc64": "0.25.9", "@esbuild/linux-riscv64": "0.25.9", "@esbuild/linux-s390x": "0.25.9", "@esbuild/linux-x64": "0.25.9", "@esbuild/netbsd-arm64": "0.25.9", "@esbuild/netbsd-x64": "0.25.9", "@esbuild/openbsd-arm64": "0.25.9", "@esbuild/openbsd-x64": "0.25.9", "@esbuild/openharmony-arm64": "0.25.9", "@esbuild/sunos-x64": "0.25.9", "@esbuild/win32-arm64": "0.25.9", "@esbuild/win32-ia32": "0.25.9", "@esbuild/win32-x64": "0.25.9" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g=="],
|
||||||
|
|
||||||
|
"estree-walker": ["[email protected]", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="],
|
||||||
|
|
||||||
|
"fdir": ["[email protected]", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w=="],
|
||||||
|
|
||||||
|
"fsevents": ["[email protected]", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
|
||||||
|
|
||||||
|
"graceful-fs": ["[email protected]", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="],
|
||||||
|
|
||||||
|
"jiti": ["[email protected]", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w=="],
|
||||||
|
|
||||||
|
"lightningcss": ["[email protected]", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-darwin-arm64": "1.30.1", "lightningcss-darwin-x64": "1.30.1", "lightningcss-freebsd-x64": "1.30.1", "lightningcss-linux-arm-gnueabihf": "1.30.1", "lightningcss-linux-arm64-gnu": "1.30.1", "lightningcss-linux-arm64-musl": "1.30.1", "lightningcss-linux-x64-gnu": "1.30.1", "lightningcss-linux-x64-musl": "1.30.1", "lightningcss-win32-arm64-msvc": "1.30.1", "lightningcss-win32-x64-msvc": "1.30.1" } }, "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg=="],
|
||||||
|
|
||||||
|
"lightningcss-darwin-arm64": ["[email protected]", "", { "os": "darwin", "cpu": "arm64" }, "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ=="],
|
||||||
|
|
||||||
|
"lightningcss-darwin-x64": ["[email protected]", "", { "os": "darwin", "cpu": "x64" }, "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA=="],
|
||||||
|
|
||||||
|
"lightningcss-freebsd-x64": ["[email protected]", "", { "os": "freebsd", "cpu": "x64" }, "sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig=="],
|
||||||
|
|
||||||
|
"lightningcss-linux-arm-gnueabihf": ["[email protected]", "", { "os": "linux", "cpu": "arm" }, "sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q=="],
|
||||||
|
|
||||||
|
"lightningcss-linux-arm64-gnu": ["[email protected]", "", { "os": "linux", "cpu": "arm64" }, "sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw=="],
|
||||||
|
|
||||||
|
"lightningcss-linux-arm64-musl": ["[email protected]", "", { "os": "linux", "cpu": "arm64" }, "sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ=="],
|
||||||
|
|
||||||
|
"lightningcss-linux-x64-gnu": ["[email protected]", "", { "os": "linux", "cpu": "x64" }, "sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw=="],
|
||||||
|
|
||||||
|
"lightningcss-linux-x64-musl": ["[email protected]", "", { "os": "linux", "cpu": "x64" }, "sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ=="],
|
||||||
|
|
||||||
|
"lightningcss-win32-arm64-msvc": ["[email protected]", "", { "os": "win32", "cpu": "arm64" }, "sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA=="],
|
||||||
|
|
||||||
|
"lightningcss-win32-x64-msvc": ["[email protected]", "", { "os": "win32", "cpu": "x64" }, "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg=="],
|
||||||
|
|
||||||
|
"lodash.debounce": ["[email protected]", "", {}, "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow=="],
|
||||||
|
|
||||||
|
"lodash.throttle": ["[email protected]", "", {}, "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ=="],
|
||||||
|
|
||||||
|
"magic-string": ["[email protected]", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" } }, "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA=="],
|
||||||
|
|
||||||
|
"minipass": ["[email protected]", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="],
|
||||||
|
|
||||||
|
"minizlib": ["[email protected]", "", { "dependencies": { "minipass": "^7.1.2" } }, "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA=="],
|
||||||
|
|
||||||
|
"mkdirp": ["[email protected]", "", { "bin": { "mkdirp": "dist/cjs/src/bin.js" } }, "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg=="],
|
||||||
|
|
||||||
|
"nanoid": ["[email protected]", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
|
||||||
|
|
||||||
|
"picocolors": ["[email protected]", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
|
||||||
|
|
||||||
|
"picomatch": ["[email protected]", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="],
|
||||||
|
|
||||||
|
"postcss": ["[email protected]", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="],
|
||||||
|
|
||||||
|
"rollup": ["[email protected]", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.46.2", "@rollup/rollup-android-arm64": "4.46.2", "@rollup/rollup-darwin-arm64": "4.46.2", "@rollup/rollup-darwin-x64": "4.46.2", "@rollup/rollup-freebsd-arm64": "4.46.2", "@rollup/rollup-freebsd-x64": "4.46.2", "@rollup/rollup-linux-arm-gnueabihf": "4.46.2", "@rollup/rollup-linux-arm-musleabihf": "4.46.2", "@rollup/rollup-linux-arm64-gnu": "4.46.2", "@rollup/rollup-linux-arm64-musl": "4.46.2", "@rollup/rollup-linux-loongarch64-gnu": "4.46.2", "@rollup/rollup-linux-ppc64-gnu": "4.46.2", "@rollup/rollup-linux-riscv64-gnu": "4.46.2", "@rollup/rollup-linux-riscv64-musl": "4.46.2", "@rollup/rollup-linux-s390x-gnu": "4.46.2", "@rollup/rollup-linux-x64-gnu": "4.46.2", "@rollup/rollup-linux-x64-musl": "4.46.2", "@rollup/rollup-win32-arm64-msvc": "4.46.2", "@rollup/rollup-win32-ia32-msvc": "4.46.2", "@rollup/rollup-win32-x64-msvc": "4.46.2", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-WMmLFI+Boh6xbop+OAGo9cQ3OgX9MIg7xOQjn+pTCwOkk+FNDAeAemXkJ3HzDJrVXleLOFVa1ipuc1AmEx1Dwg=="],
|
||||||
|
|
||||||
|
"source-map-js": ["[email protected]", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
|
||||||
|
|
||||||
|
"tailwindcss": ["[email protected]", "", {}, "sha512-2E9TBm6MDD/xKYe+dvJZAmg3yxIEDNRc0jwlNyDg/4Fil2QcSLjFKGVff0lAf1jjeaArlG/M75Ey/EYr/OJtBA=="],
|
||||||
|
|
||||||
|
"tapable": ["[email protected]", "", {}, "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg=="],
|
||||||
|
|
||||||
|
"tar": ["[email protected]", "", { "dependencies": { "@isaacs/fs-minipass": "^4.0.0", "chownr": "^3.0.0", "minipass": "^7.1.2", "minizlib": "^3.0.1", "mkdirp": "^3.0.1", "yallist": "^5.0.0" } }, "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw=="],
|
||||||
|
|
||||||
|
"tinyglobby": ["[email protected]", "", { "dependencies": { "fdir": "^6.4.4", "picomatch": "^4.0.2" } }, "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ=="],
|
||||||
|
|
||||||
|
"vite": ["[email protected]", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.6", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.14" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-J0SQBPlQiEXAF7tajiH+rUooJPo0l8KQgyg4/aMunNtrOa7bwuZJsJbDWzeljqQpgftxuq5yNJxQ91O9ts29UQ=="],
|
||||||
|
|
||||||
|
"vue": ["[email protected]", "", { "dependencies": { "@vue/compiler-dom": "3.5.18", "@vue/compiler-sfc": "3.5.18", "@vue/runtime-dom": "3.5.18", "@vue/server-renderer": "3.5.18", "@vue/shared": "3.5.18" }, "peerDependencies": { "typescript": "*" }, "optionalPeers": ["typescript"] }, "sha512-7W4Y4ZbMiQ3SEo+m9lnoNpV9xG7QVMLa+/0RFwwiAVkeYoyGXqWE85jabU4pllJNUzqfLShJ5YLptewhCWUgNA=="],
|
||||||
|
|
||||||
|
"vue-toast-notification": ["[email protected]", "", { "peerDependencies": { "vue": "^3.0" } }, "sha512-XNyWqwLIGBFfX5G9sK+clq3N3IPlhDjzNdbZaXkEElcotPlWs0wWZailk1vqhdtLYT/93Y4FHAVuzyatLmPZRA=="],
|
||||||
|
|
||||||
|
"vue3-carousel": ["[email protected]", "", { "peerDependencies": { "vue": "^3.5.0" } }, "sha512-IKRKtvHP8gNDRHSzINXwFbJ/Zy2HS+Gv2lXPnAEop6pxsvB17+fz2WQlNZ6ytilLkM5DOu/jXPoDQi/xy17bjg=="],
|
||||||
|
|
||||||
|
"yallist": ["[email protected]", "", {}, "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw=="],
|
||||||
|
|
||||||
|
"@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/[email protected]", "", { "dependencies": { "@emnapi/wasi-threads": "1.0.4", "tslib": "^2.4.0" }, "bundled": true }, "sha512-XsLw1dEOpkSX/WucdqUhPWP7hDxSvZiY+fsUC14h+FtQ2Ifni4znbBt8punRX+Uj2JG/uDb8nEHVKvrVlvdZ5Q=="],
|
||||||
|
|
||||||
|
"@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/[email protected]", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-++LApOtY0pEEz1zrd9vy1/zXVaVJJ/EbAF3u0fXIzPJEDtnITsBGbbK0EkM72amhl/R5b+5xx0Y/QhcVOpuulg=="],
|
||||||
|
|
||||||
|
"@tailwindcss/oxide-wasm32-wasi/@emnapi/wasi-threads": ["@emnapi/[email protected]", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-PJR+bOmMOPH8AtcTGAyYNiuJ3/Fcoj2XN/gBEWzDIKh254XO+mM9XoXHk5GNEhodxeMznbg7BlRojVbKN+gC6g=="],
|
||||||
|
|
||||||
|
"@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/[email protected]", "", { "dependencies": { "@emnapi/core": "^1.4.3", "@emnapi/runtime": "^1.4.3", "@tybys/wasm-util": "^0.10.0" }, "bundled": true }, "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ=="],
|
||||||
|
|
||||||
|
"@tailwindcss/oxide-wasm32-wasi/@tybys/wasm-util": ["@tybys/[email protected]", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw=="],
|
||||||
|
|
||||||
|
"@tailwindcss/oxide-wasm32-wasi/tslib": ["[email protected]", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
||||||
|
|
||||||
|
"@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime/@tybys/wasm-util": ["@tybys/[email protected]", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-VyyPYFlOMNylG45GoAe0xDoLwWuowvf92F9kySqzYh8vmYm7D2u4iUJKa1tOUpS70Ku13ASrOkS4ScXFsTaCNQ=="],
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"recommendations": ["Vue.volar"]
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<link rel="icon" type="image/svg+xml" href="/src/assets/logo.svg" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Fernando Videira's Portfolio</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<script type="module" src="/src/main.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"name": "portfolio",
|
||||||
|
"private": true,
|
||||||
|
"version": "0.0.0",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "vite build",
|
||||||
|
"preview": "vite preview"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@tailwindcss/vite": "^4.1.11",
|
||||||
|
"aos": "^2.3.4",
|
||||||
|
"emailjs-com": "^3.2.0",
|
||||||
|
"tailwindcss": "^4.1.11",
|
||||||
|
"vue": "^3.5.18",
|
||||||
|
"vue-toast-notification": "^3",
|
||||||
|
"vue3-carousel": "^0.16.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@vitejs/plugin-vue": "^6.0.1",
|
||||||
|
"vite": "^7.1.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|
||||||
|
After Width: | Height: | Size: 1.5 KiB |
@@ -0,0 +1,57 @@
|
|||||||
|
<template>
|
||||||
|
<div class="font-logo bg-gray-950 min-h-screen">
|
||||||
|
<Suspense>
|
||||||
|
<template #default>
|
||||||
|
<div>
|
||||||
|
<NavBar />
|
||||||
|
<Hero />
|
||||||
|
<Services />
|
||||||
|
<About />
|
||||||
|
<Skills />
|
||||||
|
<Projects />
|
||||||
|
<!-- <Testimonials /> -->
|
||||||
|
<Contact />
|
||||||
|
<Footer />
|
||||||
|
<BackToTop />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template #fallback>
|
||||||
|
<div class="flex justify-center items-center min-h-screen">
|
||||||
|
<LoadingSpinner />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</Suspense>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { defineAsyncComponent } from "vue";
|
||||||
|
|
||||||
|
const NavBar = defineAsyncComponent(() => import("@/components/Navbar.vue"));
|
||||||
|
const Hero = defineAsyncComponent(() => import("@/components/Hero.vue"));
|
||||||
|
const Services = defineAsyncComponent(() =>
|
||||||
|
import("@/components/Services.vue")
|
||||||
|
);
|
||||||
|
const About = defineAsyncComponent(() => import("@/components/About.vue"));
|
||||||
|
const Skills = defineAsyncComponent(() => import("@/components/Skills.vue"));
|
||||||
|
const Projects = defineAsyncComponent(() =>
|
||||||
|
import("@/components/Projects.vue")
|
||||||
|
);
|
||||||
|
// const Testimonials = defineAsyncComponent(() =>
|
||||||
|
// import("@/components/Testemonial.vue")
|
||||||
|
// );
|
||||||
|
const Contact = defineAsyncComponent(() => import("@/components/Contact.vue"));
|
||||||
|
const Footer = defineAsyncComponent(() => import("@/components/Footer.vue"));
|
||||||
|
const BackToTop = defineAsyncComponent(() =>
|
||||||
|
import("@/components/BackToTop.vue")
|
||||||
|
);
|
||||||
|
|
||||||
|
import LoadingSpinner from "@/components/LoadingSpinner.vue";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
scrollbar-width: thin;
|
||||||
|
scrollbar-color: #111827 #f1f1f1;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
After Width: | Height: | Size: 85 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 9.2 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="500" zoomAndPan="magnify" viewBox="0 0 375 374.999991" height="500" preserveAspectRatio="xMidYMid meet" version="1.0"><defs><clipPath id="dfb47b435a"><path d="M 82 90.4375 L 293.351562 90.4375 L 293.351562 284.6875 L 82 284.6875 Z M 82 90.4375 " clip-rule="nonzero"/></clipPath></defs><rect x="-37.5" width="450" fill="#ffffff" y="-37.499999" height="449.999989" fill-opacity="1"/><rect x="-37.5" width="450" fill="#000000" y="-37.499999" height="449.999989" fill-opacity="1"/><g clip-path="url(#dfb47b435a)"><path fill="#ffffff" d="M 256.140625 90.4375 C 256.230469 153.992188 256.226562 176.601562 256.226562 199.214844 C 256.226562 200.023438 256.0625 200.832031 255.910156 202.296875 C 255.910156 202.296875 255.90625 202.292969 255.90625 202.292969 L 236.234375 185.234375 C 219.777344 170.863281 203.328125 156.480469 186.835938 142.148438 C 186.53125 141.882812 186.152344 141.648438 185.75 141.460938 L 169.835938 127.660156 C 171.527344 127.496094 173.25 127.386719 175.007812 127.347656 C 182.699219 127.171875 190.394531 127.117188 240.265625 127.121094 L 240.265625 90.558594 C 190.644531 90.472656 183.191406 90.492188 175.746094 90.523438 C 154.546875 90.597656 135.253906 96.671875 118.527344 109.757812 C 95.390625 127.84375 82.710938 151.675781 82.285156 181.164062 C 81.890625 208.75 82.082031 236.34375 82.128906 284.558594 L 119.011719 284.558594 C 119.011719 253.054688 119.011719 240.308594 119.011719 227.570312 C 119.011719 224.382812 119.027344 224.378906 122.160156 224.378906 C 148.136719 224.378906 174.117188 224.378906 200.09375 224.378906 C 200.898438 224.378906 201.707031 224.378906 202.507812 224.378906 C 202.675781 224.101562 202.839844 223.820312 203.007812 223.542969 C 202.375 223.125 201.6875 222.773438 201.121094 222.28125 C 188.414062 211.238281 175.710938 200.195312 163.042969 189.109375 C 161.785156 188.007812 160.496094 187.574219 158.824219 187.582031 C 146.578125 187.636719 134.335938 187.613281 122.085938 187.605469 C 119.101562 187.605469 119.039062 187.601562 118.988281 184.527344 C 118.835938 175.164062 120.652344 166.214844 125.175781 157.96875 C 127.730469 153.316406 130.617188 149.183594 133.832031 145.570312 L 176.632812 182.691406 C 196.023438 199.566406 215.417969 216.445312 234.789062 233.335938 C 253.65625 249.785156 272.492188 266.277344 291.34375 282.738281 C 291.730469 283.078125 292.203125 283.3125 293.0625 283.875 C 293.0625 282.738281 293.0625 282.0625 293.0625 281.382812 C 293.0625 231.375 293.066406 181.375 293.066406 90.425781 L 256.140625 90.425781 Z M 256.140625 90.4375 " fill-opacity="1" fill-rule="nonzero"/></g></svg>
|
||||||
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 79 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 161 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>
|
||||||
|
After Width: | Height: | Size: 496 B |
@@ -0,0 +1,114 @@
|
|||||||
|
<template>
|
||||||
|
<section class="text-white mt-18" id="about">
|
||||||
|
<div class="absolute z-0 top-[93rem] inset-x-0 h-64 flex items-start">
|
||||||
|
<div
|
||||||
|
class="h-24 w-64 bg-gradient-to-br from-primary via-secondary blur-2xl to-[#570cac] opacity-20"
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="md:grid md:grid-cols-2 gap-8 items-center py-8 px-4 xl:gap-16 sm:py-16 xl:px-16 z-1"
|
||||||
|
>
|
||||||
|
<div data-aos="flip-right">
|
||||||
|
<h2 class="text-4xl font-bold text-white text-left mb-8">
|
||||||
|
My Education
|
||||||
|
</h2>
|
||||||
|
<div class="space-y-8 py-8">
|
||||||
|
<div
|
||||||
|
v-for="el in education"
|
||||||
|
:key="el.id"
|
||||||
|
class="flex items-center md:w-[80%] w-full rounded-xl bg-gray-900 shadow-lg border border-[#1f1641]"
|
||||||
|
>
|
||||||
|
<div class="w-1/4 items-center justify-center flex">
|
||||||
|
<img
|
||||||
|
src="https://img.icons8.com/ios-glyphs/60/ffffff/graduation-cap--v1.png"
|
||||||
|
alt="graduation-cap--v1"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="w-3/4 pl-4 py-2">
|
||||||
|
<h3
|
||||||
|
class="text-2xl font-semibold uppercase text-transparent bg-clip-text bg-gradient-to-r from-primary to-secondary lg:text-xl"
|
||||||
|
>
|
||||||
|
{{ el.institution }}
|
||||||
|
</h3>
|
||||||
|
<p class="text-white">{{ el.course }}</p>
|
||||||
|
<p class="text-gray-400">{{ el.year }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="mt-4 md:mt-0 text-left flex flex-col z-10 h-full"
|
||||||
|
data-aos="flip-right"
|
||||||
|
>
|
||||||
|
<h2 class="text-4xl font-bold text-white md:text-center text-left mb-4">
|
||||||
|
More
|
||||||
|
<span
|
||||||
|
class="text-transparent bg-clip-text bg-gradient-to-r from-primary to-secondary"
|
||||||
|
>About</span
|
||||||
|
>
|
||||||
|
Me
|
||||||
|
</h2>
|
||||||
|
<p class="text-base lg:text-lg mt-8 py-8 text-justify">
|
||||||
|
I am a Software Engineering student from Portugal with 4+ years of
|
||||||
|
experience from my internships and Self Learning + Personal Projects.
|
||||||
|
I am passionate about technology and always eager to learn more. I am
|
||||||
|
currently pursuing my Bachelor's on Software Engineering after having
|
||||||
|
completed a CTeSP in programming, where I gained a solid foundation in
|
||||||
|
C, .NET, PHP, Java, and MySQL. In my free time I've taken a few online
|
||||||
|
courses on Unity 3D, Swift/SwiftUI, Cypress, Git, React, Golang. I've
|
||||||
|
also had the pleasure to be a QA/QC Intern at VOID Software in Leiria
|
||||||
|
for five months. There, I contributed to the testing and quality
|
||||||
|
assurance of several projects, using Cypress and Cucumber to automate
|
||||||
|
and streamline the testing process and Git to manage the source code
|
||||||
|
and collaborate with the development team. I am always looking for new
|
||||||
|
challenges and opportunities to grow as a developer.
|
||||||
|
</p>
|
||||||
|
<div class="grid grid-cols-3 gap-4 max-w-lg pt-8">
|
||||||
|
<div
|
||||||
|
class="text-center rounded-xl bg-gray-900 shadow-lg border border-[#1f1641] p-3"
|
||||||
|
>
|
||||||
|
<h3 class="text-white font-bold text-xl sm:text-2xl lg:text-3xl">
|
||||||
|
+200
|
||||||
|
</h3>
|
||||||
|
<p class="text-sm sm:text-base text-gray-300">Happy Clients</p>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="text-center rounded-xl bg-gray-900 shadow-lg border border-[#1f1641] p-3"
|
||||||
|
>
|
||||||
|
<h3 class="text-white font-bold text-xl sm:text-2xl lg:text-3xl">
|
||||||
|
+4
|
||||||
|
</h3>
|
||||||
|
<p class="text-sm sm:text-base text-gray-300">Years Experience</p>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="text-center rounded-xl bg-gray-900 shadow-lg border border-[#1f1641] p-3"
|
||||||
|
>
|
||||||
|
<h3 class="text-white font-bold text-xl sm:text-2xl lg:text-3xl">
|
||||||
|
+300
|
||||||
|
</h3>
|
||||||
|
<p class="text-sm sm:text-base text-gray-300">Projects</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref } from "vue";
|
||||||
|
|
||||||
|
const education = ref([
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
course: "CTeSP in Programing and IT",
|
||||||
|
institution: "Polytechnic of Leiria",
|
||||||
|
year: "2023",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
course: "Bachelor's Degree in Software Engineering",
|
||||||
|
institution: "Polytechnic of Leiria",
|
||||||
|
year: "2026 (Expected)",
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
<template>
|
||||||
|
<button
|
||||||
|
v-if="isVisible"
|
||||||
|
@click="scrollToTop"
|
||||||
|
class="fixed bottom-4 right-4 bg-gradient-to-r from-primary to-pink-500 text-white rounded-full w-12 h-12 flex items-center justify-center text-xl cursor-pointer transition-opacity duration-300 hover:bg-blue-600"
|
||||||
|
>
|
||||||
|
↑
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { ref, onMounted, onUnmounted } from "vue";
|
||||||
|
|
||||||
|
const isVisible = ref(false);
|
||||||
|
|
||||||
|
const handleScroll = () => {
|
||||||
|
isVisible.value = window.scrollY > 300;
|
||||||
|
};
|
||||||
|
|
||||||
|
const scrollToTop = () => {
|
||||||
|
window.scrollTo({
|
||||||
|
top: 0,
|
||||||
|
behavior: "smooth",
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
window.addEventListener("scroll", handleScroll);
|
||||||
|
});
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
window.removeEventListener("scroll", handleScroll);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,203 @@
|
|||||||
|
<template>
|
||||||
|
<section class="text-white mt-20" id="contact">
|
||||||
|
<h2 class="text-4xl font-bold text-white text-left mb-4 px-4 xl:pl-16">
|
||||||
|
Let's Connect
|
||||||
|
</h2>
|
||||||
|
<div
|
||||||
|
class="grid md:grid-cols-2 gap-4 relative px-4 xl:px-16 mt-8"
|
||||||
|
data-aos="zoom-in-up"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<p class="text-[#ADB7BE]">
|
||||||
|
Check my email and linkedin or send a message here to get in touch!
|
||||||
|
</p>
|
||||||
|
<div class="col-lg-4 col-md-4 mb-lg-0 mt-5">
|
||||||
|
<div class="flex mb-10 items-center">
|
||||||
|
<div
|
||||||
|
class="p-2"
|
||||||
|
style="
|
||||||
|
background: #111a3e;
|
||||||
|
width: 50px;
|
||||||
|
height: 46px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
border-radius: 50%;
|
||||||
|
overflow: hidden;
|
||||||
|
border: 1px solid #111a3e;
|
||||||
|
backdrop-filter: blur(9px);
|
||||||
|
-webkit-backdrop-filter: blur(9px);
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src="https://img.icons8.com/metro/50/ffffff/new-post.png"
|
||||||
|
alt="new-post"
|
||||||
|
class="w-6"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="ml-5 text-white">
|
||||||
|
<h4>Email</h4>
|
||||||
|
<p class="text-[#ADB7BE]">info@fernandovideira.com</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex mb-10 items-center">
|
||||||
|
<div
|
||||||
|
class="p-2"
|
||||||
|
style="
|
||||||
|
background: #111a3e;
|
||||||
|
width: 50px;
|
||||||
|
height: 46px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
border-radius: 50%;
|
||||||
|
overflow: hidden;
|
||||||
|
border: 1px solid #111a3e;
|
||||||
|
backdrop-filter: blur(9px);
|
||||||
|
-webkit-backdrop-filter: blur(9px);
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src="https://img.icons8.com/ios-filled/50/ffffff/phone.png"
|
||||||
|
alt="new-post"
|
||||||
|
class="w-6"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="ml-5 text-white">
|
||||||
|
<h4>Phone</h4>
|
||||||
|
<p class="text-[#ADB7BE]">(+351) 923-543-517</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex mb-10 items-center">
|
||||||
|
<div
|
||||||
|
class="p-2"
|
||||||
|
style="
|
||||||
|
background: #111a3e;
|
||||||
|
width: 50px;
|
||||||
|
height: 46px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
border-radius: 50%;
|
||||||
|
overflow: hidden;
|
||||||
|
border: 1px solid #111a3e;
|
||||||
|
backdrop-filter: blur(9px);
|
||||||
|
-webkit-backdrop-filter: blur(9px);
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src="https://img.icons8.com/ios-filled/50/ffffff/linkedin.png"
|
||||||
|
alt="new-post"
|
||||||
|
class="w-6"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="ml-5 text-white">
|
||||||
|
<h4>Linkedin</h4>
|
||||||
|
<a href="https://www.linkedin.com/in/fernando-videira-info/"
|
||||||
|
><p class="text-[#ADB7BE]">Fernando Videira</p></a
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="p-6"
|
||||||
|
style="
|
||||||
|
background: #101828;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
border-radius: 20px;
|
||||||
|
overflow: hidden;
|
||||||
|
border: 1px solid #111a3e;
|
||||||
|
backdrop-filter: blur(9px);
|
||||||
|
-webkit-backdrop-filter: blur(9px);
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<form
|
||||||
|
ref="form"
|
||||||
|
class="flex flex-col p-2"
|
||||||
|
data-aos="zoom-in-up"
|
||||||
|
@submit.prevent="sendEmail"
|
||||||
|
>
|
||||||
|
<div class="mb-6">
|
||||||
|
<label for="email" class="text-white block mb-2 text-sm font-medium"
|
||||||
|
>Email</label
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
type="email"
|
||||||
|
id="email"
|
||||||
|
class="bg-gray-950 placeholder:[#9CA2A9] text-gray-100 text-sm rounded-lg block w-full p-2.5"
|
||||||
|
placeholder="[email protected]"
|
||||||
|
name="email"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="mb-6">
|
||||||
|
<label
|
||||||
|
for="subject"
|
||||||
|
class="text-white block mb-2 text-sm font-medium"
|
||||||
|
>Subject</label
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
id="subject"
|
||||||
|
class="bg-gray-950 placeholder:[#9CA2A9] text-gray-100 text-sm rounded-lg block w-full p-2.5"
|
||||||
|
placeholder="Subject"
|
||||||
|
name="subject"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="mb-6">
|
||||||
|
<label
|
||||||
|
for="message"
|
||||||
|
class="text-white block mb-2 text-sm font-medium"
|
||||||
|
>Message</label
|
||||||
|
>
|
||||||
|
<textarea
|
||||||
|
id="message"
|
||||||
|
rows="4"
|
||||||
|
class="bg-gray-950 placeholder:[#9CA2A9] text-gray-100 text-sm rounded-lg block w-full p-2.5"
|
||||||
|
placeholder="Message"
|
||||||
|
name="message"
|
||||||
|
></textarea>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
class="z-1 w-[100%!important] px-6 md:px-7 py-3 rounded-full sm:w-max flex justify-center text-white bg-primary border-2 border-transparent"
|
||||||
|
>
|
||||||
|
Send Message
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="bg-gradient-to-tr opacity-25 from-[#570cac] to-primary blur-2xl h-20 w-80 z-0 absolute -top-1/2 -left-4 transform -translate-x-2/3 -translate-1/2"
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { ref } from "vue";
|
||||||
|
import emailjs from "emailjs-com";
|
||||||
|
import { useToast } from "vue-toast-notification";
|
||||||
|
|
||||||
|
const $toast = useToast();
|
||||||
|
const form = ref(null);
|
||||||
|
|
||||||
|
const sendEmail = async () => {
|
||||||
|
const isEmpty = [...form.value.elements].some(
|
||||||
|
(el) => el.tagName !== "BUTTON" && el.type !== "submit" && !el.value.trim()
|
||||||
|
);
|
||||||
|
if (isEmpty) {
|
||||||
|
$toast.warning("Please fill in all fields");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const result = await emailjs.sendForm(
|
||||||
|
"service_0oh6s0e",
|
||||||
|
"template_4s8pg7r",
|
||||||
|
form.value,
|
||||||
|
"fSghIDn2dawqKYyH7"
|
||||||
|
);
|
||||||
|
$toast.success("Email sent successfully!");
|
||||||
|
form.value.reset();
|
||||||
|
} catch (err) {
|
||||||
|
$toast.error("Error sending email. Try again later.");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
<template>
|
||||||
|
<footer
|
||||||
|
class="mt-8 border z-10 border-[#33353F] border-l-transparent border-r-transparent text-white"
|
||||||
|
>
|
||||||
|
<div class="container p-12 flex justify-between">
|
||||||
|
<div>
|
||||||
|
<img src="@/assets/logo.png" alt="Logo" width="40" height="40" />
|
||||||
|
</div>
|
||||||
|
<p class="text-slate-600">© All rights reserved.</p>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
<template>
|
||||||
|
<section class="relative w-full" data-aos="zoom-in-up">
|
||||||
|
<div class="absolute top-0 inset-x-0 h-64 flex items-start">
|
||||||
|
<div
|
||||||
|
class="h-24 w-2/3 bg-gradient-to-br from-[#570cac] blur-2xl invisible opacity-40"
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
class="h-20 w-3/5 bg-gradient-to-r from-[#670ccf] opacity-40 blur-2xl"
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="w-full px-5 sm:px-8 md:px-12 max-w-screen-lg lg:max-w-screen-xl mx-auto relative"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="grid lg:grid-cols-2 gap-10 xl:gap-14 relative pt-24 lg:max-w-none max-w-2xl md:max-w-3xl mx-auto"
|
||||||
|
>
|
||||||
|
<div class="lg:py-6">
|
||||||
|
<div class="text-center lg:text-left">
|
||||||
|
<h1
|
||||||
|
class="pt-4 text-white font-bold text-4xl md:text-5xl lg:text-6xl"
|
||||||
|
>
|
||||||
|
Hi, I'm
|
||||||
|
<span
|
||||||
|
class="text-transparent bg-clip-text bg-gradient-to-r from-primary to-pink-500"
|
||||||
|
>Fernando</span
|
||||||
|
>🧑🏻💻
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<p
|
||||||
|
class="text-gray-300 pt-8 text-center lg:text-left mx-auto max-w-xl"
|
||||||
|
>
|
||||||
|
I'm a passionate Software Engineering student and Entrepreneur
|
||||||
|
always looking for new challenges!
|
||||||
|
</p>
|
||||||
|
<div
|
||||||
|
class="flex items-center gap-3 pt-9 flex-col sm:flex-row sm:w-max sm:mx-auto lg:mx-0"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
class="px-6 md:px-7 py-3 rounded-full relative group w-full sm:w-max flex justify-center"
|
||||||
|
>
|
||||||
|
<a href="#contact" class="absolute z-1 inset-0 rounded-3xl"></a>
|
||||||
|
<span
|
||||||
|
class="absolute inset-0 rounded-3xl group-hover:scale-105 origin-center transition-all ease-in-out bg-primary border-2 border-transparent"
|
||||||
|
></span>
|
||||||
|
<span class="relative flex items-center justify-center text-white"
|
||||||
|
>Hire Me</span
|
||||||
|
>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="border border-primary px-6 md:px-7 py-3 rounded-full relative group w-full sm:w-max flex justify-center"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="hover:scale-105 transition-all ease-in-out flex justify-center items-center relative"
|
||||||
|
>
|
||||||
|
<div class="svg-container">
|
||||||
|
<svg
|
||||||
|
class="download-icon"
|
||||||
|
width="18"
|
||||||
|
height="22"
|
||||||
|
viewBox="0 0 18 22"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
class="download-arrow"
|
||||||
|
d="M13 9L9 13M9 13L5 9M9 13V1"
|
||||||
|
stroke="#f59e0b"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M1 17V18C1 18.7956 1.31607 19.5587 1.87868 20.1213C2.44129 20.6839 3.20435 21 4 21H14C14.7956 21 15.5587 20.6839 16.1213 20.1213C16.6839 19.5587 17 18.7956 17 18V17"
|
||||||
|
stroke="#f59e0b"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
<div class="download-loader text-white hidden2"></div>
|
||||||
|
</div>
|
||||||
|
<a
|
||||||
|
href="/resume.pdf"
|
||||||
|
download="resume.pdf"
|
||||||
|
class="pl-2 text-primary"
|
||||||
|
>Download Resume</a
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="lg:h-full md:flex">
|
||||||
|
<div
|
||||||
|
class="flex w-full h-96 min-h-[24rem] lg:min-h-[none] lg:w-full lg:h-full items-center relative"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="absolute z-0 top-1/2 -translate-y-1/2 w-5/6 right-0 h-[calc(80%+20px)] bg-gradient-to-tr opacity-25 from-[#570cac] to-primary blur-2xl"
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
class="absolute h-full z-10 p-2 -translate-y-1/2 top-1/2 lg:right-3 md:right-40 sm:right-16 rounded-full shadow-lg border border-primary"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src="@/assets/profile_image.jpg"
|
||||||
|
alt="hero picture"
|
||||||
|
width="500"
|
||||||
|
height="auto"
|
||||||
|
loading="lazy"
|
||||||
|
class="w-full h-full rounded-full object-cover"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import AOS from "aos";
|
||||||
|
import "aos/dist/aos.css";
|
||||||
|
|
||||||
|
AOS.init();
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
<template>
|
||||||
|
<div class="flex justify-center items-center h-full">
|
||||||
|
<svg
|
||||||
|
class="animate-spin h-16 w-16 text-white"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<defs>
|
||||||
|
<linearGradient id="gradient1" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0%" style="stop-color: #f59e0b" />
|
||||||
|
<stop offset="100%" style="stop-color: #ec4899" />
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
<circle
|
||||||
|
class="opacity-25"
|
||||||
|
cx="12"
|
||||||
|
cy="12"
|
||||||
|
r="10"
|
||||||
|
stroke="url(#gradient1)"
|
||||||
|
stroke-width="4"
|
||||||
|
fill="none"
|
||||||
|
></circle>
|
||||||
|
<path
|
||||||
|
fill="#f59e0b"
|
||||||
|
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup></script>
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
<template>
|
||||||
|
<header
|
||||||
|
class="flex justify-between items-center p-6 bg-opacity-50 relative z-20"
|
||||||
|
>
|
||||||
|
<div class="text-white text-3xl font-bold">
|
||||||
|
<div class="flex flex-row items-center">
|
||||||
|
<img src="@/assets/logo.png" alt="Logo" width="60" height="60" />
|
||||||
|
<h1>Portfolio</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- Mobile Toggle Button -->
|
||||||
|
<div class="md:hidden z-30">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="block focus:outline-none"
|
||||||
|
@click="isMenuOpen = !isMenuOpen"
|
||||||
|
>
|
||||||
|
<span v-if="isMenuOpen" class="text-5xl">
|
||||||
|
<img
|
||||||
|
src="https://img.icons8.com/ios-filled/100/ffffff/delete-sign.png"
|
||||||
|
alt="close"
|
||||||
|
width="50"
|
||||||
|
height="50"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
<span v-else class="text-5xl">
|
||||||
|
<img
|
||||||
|
src="https://img.icons8.com/ios-filled/100/ffffff/menu--v6.png"
|
||||||
|
alt="menu"
|
||||||
|
width="50"
|
||||||
|
height="50"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<!-- Navbar Links -->
|
||||||
|
<nav
|
||||||
|
:class="[
|
||||||
|
'fixed inset-0 z-20 flex flex-col items-center justify-center bg-[#111827] md:relative md:bg-transparent md:flex md:justify-between md:flex-row',
|
||||||
|
isMenuOpen ? 'block' : 'hidden',
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<ul
|
||||||
|
class="flex flex-col items-center space-y-5 md:flex-row md:space-x-5 md:space-y-0"
|
||||||
|
>
|
||||||
|
<li v-for="item in Menu" :key="item.name">
|
||||||
|
<a
|
||||||
|
:href="item.href"
|
||||||
|
class="block text-white hover:text-primary ease-linear text-2xl md:text-lg"
|
||||||
|
@click2="scrollToSection(item.href)"
|
||||||
|
>
|
||||||
|
{{ item.name }}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref } from "vue";
|
||||||
|
|
||||||
|
const Menu = ref([
|
||||||
|
{ name: "Services", href: "#services" },
|
||||||
|
{ name: "About Me", href: "#about" },
|
||||||
|
{ name: "Skills", href: "#skills" },
|
||||||
|
{ name: "Projects", href: "#projects" },
|
||||||
|
// { name: "Testimonials", href: "#testimonials" },
|
||||||
|
{ name: "Contact", href: "#contact" },
|
||||||
|
]);
|
||||||
|
|
||||||
|
const isMenuOpen = ref(false);
|
||||||
|
const scrollToSection = (href) => {
|
||||||
|
isMenuOpen.value = false;
|
||||||
|
const section = document.querySelector(href);
|
||||||
|
if (section) {
|
||||||
|
section.scrollIntoView({ behavior: "smooth" });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,277 @@
|
|||||||
|
<template>
|
||||||
|
<section class="text-white mt-20" id="projects">
|
||||||
|
<div class="px-4 xl:pl-16">
|
||||||
|
<div class="mb-4 md:flex md:justify-between xl:pr-16">
|
||||||
|
<h2 class="text-4xl font-bold text-white">My Projects</h2>
|
||||||
|
<div class="flex space-x-4 mb-4 mt-5 md:mt-0">
|
||||||
|
<button
|
||||||
|
class="hover:text-primary z-10"
|
||||||
|
v-for="cat in ['All', 'Academic', 'Personal']"
|
||||||
|
:key="cat"
|
||||||
|
@click="() => (selectedCategory = cat)"
|
||||||
|
>
|
||||||
|
{{ cat }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ul
|
||||||
|
class="px-4 sm:py-16 xl:pr-16 grid grid-cols-1 gap-6 pt-10 sm:grid-cols-2 md:gap-10 md:pt-12 lg:grid-cols-3"
|
||||||
|
data-aos="fade-right"
|
||||||
|
>
|
||||||
|
<div v-for="p in filteredProjects" :key="p.id">
|
||||||
|
<div
|
||||||
|
class="h-52 md:h-[24rem] rounded-t-xl relative group"
|
||||||
|
:style="{
|
||||||
|
backgroundImage: 'url(' + p.image + ')',
|
||||||
|
backgroundSize: 'cover',
|
||||||
|
backgroundRepeat: 'no-repeat',
|
||||||
|
backgroundPosition: 'center',
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="overlay items-center justify-center absolute top-0 left-0 w-full h-full bg-[#181818] bg-opacity-0 hidden group-hover:flex group-hover:bg-opacity-80 transition-all duration-50"
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
v-if="p.webURL"
|
||||||
|
:href="p.webURL"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener"
|
||||||
|
class="h-14 w-14 mr-2 border-2 relative rounded-full border-[#ADB7BE] hover:border-white group/link"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke-width="1.5"
|
||||||
|
stroke="currentColor"
|
||||||
|
aria-hidden="true"
|
||||||
|
data-slot="icon"
|
||||||
|
class="h-10 w-10 text-[#ADB7BE] absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 cursor-pointer group-hover/link:text-white"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
d="M2.036 12.322a1.012 1.012 0 0 1 0-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178Z"
|
||||||
|
></path>
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
<span
|
||||||
|
v-else
|
||||||
|
class="h-14 w-14 mr-2 border-2 relative rounded-full border-gray-600 opacity-40 cursor-not-allowed flex items-center justify-center"
|
||||||
|
aria-disabled="true"
|
||||||
|
title="Live demo unavailable"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke-width="1.5"
|
||||||
|
stroke="currentColor"
|
||||||
|
aria-hidden="true"
|
||||||
|
data-slot="icon"
|
||||||
|
class="h-10 w-10 text-[#ADB7BE] absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 cursor-pointer group-hover/link:text-white"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
d="M2.036 12.322a1.012 1.012 0 0 1 0-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178Z"
|
||||||
|
></path>
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<a
|
||||||
|
v-if="p.gitURL"
|
||||||
|
:href="p.gitURL"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener"
|
||||||
|
class="h-14 w-14 mr-2 border-2 relative rounded-full border-[#ADB7BE] hover:border-white group/link"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="1.5"
|
||||||
|
aria-hidden="true"
|
||||||
|
data-slot="icon"
|
||||||
|
class="h-10 w-10 text-[#ADB7BE] absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 cursor-pointer"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
d="M17.25 6.75 22.5 12l-5.25 5.25m-10.5 0L1.5 12l5.25-5.25m7.5-3-4.5 16.5"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
<span
|
||||||
|
v-else
|
||||||
|
class="h-14 w-14 mr-2 border-2 relative rounded-full border-gray-600 opacity-40 cursor-not-allowed flex items-center justify-center"
|
||||||
|
aria-disabled="true"
|
||||||
|
title="Live demo unavailable"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="1.5"
|
||||||
|
aria-hidden="true"
|
||||||
|
data-slot="icon"
|
||||||
|
class="h-10 w-10 text-[#ADB7BE] absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 cursor-pointer"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
d="M17.25 6.75 22.5 12l-5.25 5.25m-10.5 0L1.5 12l5.25-5.25m7.5-3-4.5 16.5"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="text-white rounded-b-xl mt-3 bg-gray-900 shadow-lg border border-[#1f1641] py-6 px-4"
|
||||||
|
>
|
||||||
|
<h3 class="text-lg font-semibold uppercase lg:text-xl">
|
||||||
|
{{ p.title }}
|
||||||
|
</h3>
|
||||||
|
<p class="text-[#ADB7BE]">{{ p.description }}</p>
|
||||||
|
<div class="flex flex-wrap p-2.5">
|
||||||
|
<div
|
||||||
|
v-for="tech in p.technologies"
|
||||||
|
:key="tech"
|
||||||
|
class="text-center ml-1 mt-1 rounded-3xl bg-gray-800"
|
||||||
|
style="
|
||||||
|
box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1);
|
||||||
|
border: 1px solid #111827;
|
||||||
|
backdrop-filter: blur(9px);
|
||||||
|
-webkit-backdrop-filter: blur(9px);
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<p class="px-5 py-2">{{ tech }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { ref, computed } from "vue";
|
||||||
|
|
||||||
|
const projects = ref([
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
category: "Academic",
|
||||||
|
image: "src/assets/test.jpg",
|
||||||
|
title: "Stuff&Go Web Store",
|
||||||
|
description: "Supermarket e-commerce platform",
|
||||||
|
technologies: ["PHP", "JavaScript", "MySQL"],
|
||||||
|
gitURL: "https://github.com/FernandoJVideira/PL2-G7_ProjetoPlatSI",
|
||||||
|
webURL: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
category: "Academic",
|
||||||
|
image: "src/assets/test.jpg",
|
||||||
|
title: "Stuff&Go Mobile App",
|
||||||
|
description: "Mobile application for supermarket shopping.",
|
||||||
|
technologies: ["Java", "MQTT", "Android"],
|
||||||
|
gitURL: "https://github.com/FernandoJVideira/PL2-G7_ProjetoAMSI",
|
||||||
|
webURL: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
category: "Academic",
|
||||||
|
image: "src/assets/RestGest.png",
|
||||||
|
title: "RestGest",
|
||||||
|
description: "Restaurant POS system.",
|
||||||
|
technologies: ["C#", ".Net", "SQL Server"],
|
||||||
|
gitURL: "https://github.com/FernandoJVideira/PSI_DA_PL2_G",
|
||||||
|
webURL: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
category: "Academic",
|
||||||
|
image: "src/assets/test.jpg",
|
||||||
|
title: "La Redoute Product Page UI",
|
||||||
|
description: "UI design for a La Redoute product page.",
|
||||||
|
technologies: ["HTML", "Bootstrap", "Three.js"],
|
||||||
|
gitURL: "https://github.com/FernandoJVideira/SGI_Projeto24",
|
||||||
|
webURL: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 5,
|
||||||
|
category: "Academic",
|
||||||
|
image: "src/assets/chat.png",
|
||||||
|
title: "Secure Chat",
|
||||||
|
description: "End-to-End Encrypted Multi-Client Chat Application.",
|
||||||
|
technologies: ["C#", ".Net", "Encryption Algorithms"],
|
||||||
|
gitURL: "https://github.com/FernandoJVideira/SGI_Projeto24",
|
||||||
|
webURL: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 6,
|
||||||
|
category: "Personal",
|
||||||
|
image: "src/assets/velox_bot.png",
|
||||||
|
title: "Velox Discord Bot",
|
||||||
|
description: "Multi-purpose Discord bot built in Python.",
|
||||||
|
technologies: ["Python", "PostgreSQL", "Discord.py"],
|
||||||
|
gitURL: "https://github.com/FernandoJVideira/VeloxDiscordBot",
|
||||||
|
webURL: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 7,
|
||||||
|
category: "Personal",
|
||||||
|
image: "src/assets/velox_web.png",
|
||||||
|
title: "Velox Web Framework",
|
||||||
|
description: "Fullstack laravel like web framework built with Go.",
|
||||||
|
technologies: ["Go"],
|
||||||
|
gitURL: "https://github.com/FernandoJVideira/velox",
|
||||||
|
webURL: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 8,
|
||||||
|
category: "Personal",
|
||||||
|
image: "src/assets/profile_image.jpg",
|
||||||
|
title: "My Portfolio",
|
||||||
|
description: "Showcase of my projects and skills built in Vue 3.",
|
||||||
|
technologies: ["Vue.js", "Tailwind CSS"],
|
||||||
|
gitURL: "",
|
||||||
|
webURL: "https://fernandovideira.com",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 9,
|
||||||
|
category: "Personal",
|
||||||
|
image: "src/assets/Lk.jpg",
|
||||||
|
title: "LK Results Website",
|
||||||
|
description: "Landing Page for my Company.",
|
||||||
|
technologies: ["React.js", "Typescript"],
|
||||||
|
gitURL: "",
|
||||||
|
webURL: "https://lk-results.com",
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const selectedCategory = ref("All");
|
||||||
|
|
||||||
|
const filteredProjects = computed(() => {
|
||||||
|
if (selectedCategory.value === "All") {
|
||||||
|
return projects.value;
|
||||||
|
}
|
||||||
|
return projects.value.filter(
|
||||||
|
(p) =>
|
||||||
|
p.category.toLocaleLowerCase() ===
|
||||||
|
selectedCategory.value.toLocaleLowerCase()
|
||||||
|
);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
<template>
|
||||||
|
<section class="text-white mt-20" id="services">
|
||||||
|
<div class="px-4 xl:pl-16">
|
||||||
|
<h2 class="text-4xl font-bold text-white mb-4">My Services</h2>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="py-8 xl:px-16 px-4 sm:py-16 grid grid-cols-1 gap-6 pt-10 sm:grid-cols-2 md:gap-10 md:pt-12 lg:grid-cols-3"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
v-for="service in services"
|
||||||
|
:key="service.id"
|
||||||
|
data-aos="fade-up"
|
||||||
|
class="px-8 py-12 rounded-xl bg-gray-900 shadow-lg border border-[#1f1641]"
|
||||||
|
>
|
||||||
|
<div class="mx-auto h-24 w-24 text-center xl:h-28 xl:w-28">
|
||||||
|
<div>
|
||||||
|
<img :src="service.icon" alt="service icon" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="text-center">
|
||||||
|
<h3
|
||||||
|
class="pt-8 text-lg font-semibold uppercase text-transparent bg-clip-text bg-gradient-to-r from-primary to-secondary lg:text-xl"
|
||||||
|
>
|
||||||
|
{{ service.name }}
|
||||||
|
</h3>
|
||||||
|
<p class="text-gray pt-4 text-sm group-hover:text-white md:text-base">
|
||||||
|
{{ service.description }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref } from "vue";
|
||||||
|
|
||||||
|
const services = ref([
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
icon: "https://img.icons8.com/ios-filled/100/ffffff/google-code.png",
|
||||||
|
name: "Frontend Development",
|
||||||
|
description: "Building responsive and modern web applications.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
icon: "https://img.icons8.com/external-vectorslab-glyph-vectorslab/1000/fffeee/external-Technical-Writing-mobile-app-development-vectorslab-glyph-vectorslab.png",
|
||||||
|
name: "Backend Development",
|
||||||
|
description: "Building robust and scalable server-side RESTful APIs.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
icon: "https://img.icons8.com/ios-filled/100/ffffff/developer-mode.png",
|
||||||
|
name: "Mobile Development",
|
||||||
|
description:
|
||||||
|
"Building mobile applications with a focus on user experience and performance.",
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,104 @@
|
|||||||
|
<template>
|
||||||
|
<section class="text-white mt-18" id="skills">
|
||||||
|
<div class="absolute right-0 top-[110rem] h-full w-full justify-end">
|
||||||
|
<span class="flex opacity-20">
|
||||||
|
<span class="w-16 h-32 rounded-l-full flex bg-primary blur-2xl"></span>
|
||||||
|
<span
|
||||||
|
class="w-16 h-32 rounded-l-full flex bg-[#f88fc2] blur-2xl mt-14"
|
||||||
|
></span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="md:grid md:grid-cols-2 gap-8 items-center py-8 px-4 xl:gap-16 xl:px-16"
|
||||||
|
>
|
||||||
|
<div class="mt-4 md:mt-0 text-left flex flex-col z-10 h-full w-[80%]">
|
||||||
|
<h2 class="text-4xl font-bold text-white text-left mb-4">
|
||||||
|
My
|
||||||
|
<span
|
||||||
|
class="text-transparent bg-clip-text bg-gradient-to-r from-primary to-secondary"
|
||||||
|
>
|
||||||
|
Skills
|
||||||
|
</span>
|
||||||
|
</h2>
|
||||||
|
<div class="mt-8" v-for="skill in skills">
|
||||||
|
<div class="flex items-end justify-between" data-aos="fade-right">
|
||||||
|
<h4 class="font-semibold uppercase text-white">{{ skill.name }}</h4>
|
||||||
|
<h3 class="text-2xl font-bold text-white">{{ skill.width }}</h3>
|
||||||
|
</div>
|
||||||
|
<div class="mt-2 h-1 w-full bg-[#131d30] rounded-full">
|
||||||
|
<div
|
||||||
|
class="h-1 rounded-full bg-primary"
|
||||||
|
:style="{ width: skill.width }"
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div data-aos="flip-left">
|
||||||
|
<h2
|
||||||
|
class="text-4xl font-bold text-white text-left mb-8 md:text-center md:mt-0 mt-8"
|
||||||
|
>
|
||||||
|
My Experiences
|
||||||
|
</h2>
|
||||||
|
<div class="space-y-8 py-8" data-aos="fade-left">
|
||||||
|
<div
|
||||||
|
v-for="exp in experiences"
|
||||||
|
:key="exp.id"
|
||||||
|
class="flex items-center rounded-xl p-4 bg-gray-900 shadow-lg border border-[#1f1641]"
|
||||||
|
>
|
||||||
|
<div class="w-1/4 items-center justify-center flex">
|
||||||
|
<img
|
||||||
|
src="https://img.icons8.com/ios-filled/100/ffffff/lawyer.png"
|
||||||
|
alt="lawyer"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="w-3/4 pl-4">
|
||||||
|
<h3
|
||||||
|
class="text-2xl font-semibold uppercase text-transparent bg-clip-text bg-gradient-to-r from-primary to-secondary"
|
||||||
|
>
|
||||||
|
{{ exp.role }}
|
||||||
|
</h3>
|
||||||
|
<p class="text-white">{{ exp.company }}</p>
|
||||||
|
<p class="text-gray-400">{{ exp.date }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref } from "vue";
|
||||||
|
|
||||||
|
const skills = ref([
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
name: "Go",
|
||||||
|
width: "90% ",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
name: "C#",
|
||||||
|
width: "70%",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
name: "Nuxt.js",
|
||||||
|
width: "55%",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
name: "Python",
|
||||||
|
width: "45%",
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const experiences = ref([
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
role: "QA Engineer Intern",
|
||||||
|
company: "Void Software",
|
||||||
|
date: "Feb 2023 - Jul 2023",
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,110 @@
|
|||||||
|
<template>
|
||||||
|
<section class="text-white mt-20" id="testimonials" data-aos="zoom-in">
|
||||||
|
<h2 class="text-4xl font-bold text-white text-left mb-4 px-4 xl:pl-16">
|
||||||
|
Testimonials
|
||||||
|
</h2>
|
||||||
|
<div class="px-4 xl:px-16">
|
||||||
|
<Carousel v-bind="settings" :breakpoints="breakpoints">
|
||||||
|
<Slide v-for="t in testimonials" :key="t.id">
|
||||||
|
<div class="carousel__item p-4">
|
||||||
|
<div
|
||||||
|
class="w-full mx-auto bg-gray-900 shadow-lg border border-[#1f1641] p-5 text-white font-light mb-6"
|
||||||
|
>
|
||||||
|
<div class="w-full flex mb-4 items-center">
|
||||||
|
<div
|
||||||
|
class="overflow-hidden rounded-full w-10 h-10 bg-gray-50 border border-gray-200"
|
||||||
|
>
|
||||||
|
<img :src="t.image" alt="Profile Image" loading="lazy" />
|
||||||
|
</div>
|
||||||
|
<h6 class="ml-4 font-bold text-sm uppercase text-white">
|
||||||
|
{{ t.fullName }}
|
||||||
|
</h6>
|
||||||
|
</div>
|
||||||
|
<div class="w-full">
|
||||||
|
<p class="text-sm leading-tight">
|
||||||
|
<span
|
||||||
|
class="text-lg leading-none italic font-bold text-white mr-1"
|
||||||
|
>"</span
|
||||||
|
>{{ t.comment
|
||||||
|
}}<span
|
||||||
|
class="text-lg leading-none italic font-bold text-white mr-1"
|
||||||
|
>"</span
|
||||||
|
>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Slide>
|
||||||
|
<template #addons>
|
||||||
|
<Navigation />
|
||||||
|
</template>
|
||||||
|
</Carousel>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { ref } from "vue";
|
||||||
|
import { Carousel, Navigation, Slide } from "vue3-carousel";
|
||||||
|
import "vue3-carousel/dist/carousel.css";
|
||||||
|
|
||||||
|
const settings = ref({
|
||||||
|
itemsToShow: 1,
|
||||||
|
snapAlign: "center",
|
||||||
|
});
|
||||||
|
|
||||||
|
const breakpoints = ref({
|
||||||
|
700: {
|
||||||
|
itemsToShow: 2.5,
|
||||||
|
snapAlign: "center",
|
||||||
|
},
|
||||||
|
1024: {
|
||||||
|
itemsToShow: 3,
|
||||||
|
snapAlign: "start",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const testimonials = ref([
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
fullName: "client 1",
|
||||||
|
image: "src/assets/profile_image.jpg",
|
||||||
|
comment:
|
||||||
|
"Lorem ipsum dolor sit amet consectetur adipisicing elit. Aperiam minima reprehenderit maiores itaque molestiae optio, voluptatibus iusto eos doloremque consectetur! ",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
fullName: "client 2",
|
||||||
|
image: "src/assets/profile_image.jpg",
|
||||||
|
comment:
|
||||||
|
"Lorem ipsum dolor sit amet consectetur adipisicing elit. Aperiam minima reprehenderit maiores itaque molestiae optio, voluptatibus iusto eos doloremque consectetur! ",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
fullName: "client 3",
|
||||||
|
image: "src/assets/profile_image.jpg",
|
||||||
|
comment:
|
||||||
|
"Lorem ipsum dolor sit amet consectetur adipisicing elit. Aperiam minima reprehenderit maiores itaque molestiae optio, voluptatibus iusto eos doloremque consectetur! ",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
fullName: "client 4",
|
||||||
|
image: "src/assets/profile_image.jpg",
|
||||||
|
comment:
|
||||||
|
"Lorem ipsum dolor sit amet consectetur adipisicing elit. Aperiam minima reprehenderit maiores itaque molestiae optio, voluptatibus iusto eos doloremque consectetur! ",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 5,
|
||||||
|
fullName: "client 5",
|
||||||
|
image: "src/assets/profile_image.jpg",
|
||||||
|
comment:
|
||||||
|
"Lorem ipsum dolor sit amet consectetur adipisicing elit. Aperiam minima reprehenderit maiores itaque molestiae optio, voluptatibus iusto eos doloremque consectetur! ",
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.carousel__prev,
|
||||||
|
.carousel__next {
|
||||||
|
color: white !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import { createApp } from "vue";
|
||||||
|
import "./style.css";
|
||||||
|
import App from "./App.vue";
|
||||||
|
|
||||||
|
import ToastPlugin from "vue-toast-notification";
|
||||||
|
// Import one of the available themes
|
||||||
|
//import 'vue-toast-notification/dist/theme-default.css';
|
||||||
|
import "vue-toast-notification/dist/theme-bootstrap.css";
|
||||||
|
|
||||||
|
createApp(App).use(ToastPlugin).mount("#app");
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
@import "tailwindcss";
|
||||||
|
|
||||||
|
@theme {
|
||||||
|
--color-primary: #f59e0b;
|
||||||
|
--color-secondary: #ec4899;
|
||||||
|
--font-logo: "Outfit", sans-serif;
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
import { defineConfig } from "vite";
|
||||||
|
import { fileURLToPath, URL } from "node:url";
|
||||||
|
import vue from "@vitejs/plugin-vue";
|
||||||
|
import tailwindcss from "@tailwindcss/vite";
|
||||||
|
|
||||||
|
// https://vite.dev/config/
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [vue(), tailwindcss()],
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
"@": fileURLToPath(new URL("./src", import.meta.url)),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||