From 35af35e15eb215e9fdda664fd6764c26fd465882 Mon Sep 17 00:00:00 2001 From: Sebastian Luque Date: Sun, 24 Nov 2024 22:31:13 -0500 Subject: [PATCH] progress --- package.json | 3 + pnpm-lock.yaml | 286 +++++++++++++++++++++++++- src/assets/devtool.svg | 4 + src/assets/hat.svg | 5 + src/assets/home.svg | 7 + src/components/Button.astro | 26 +++ src/components/Dock/Dock.tsx | 165 +++++++++++++++ src/components/Dock/MouseProvider.tsx | 52 +++++ src/components/FeaturedProject.astro | 18 ++ src/components/PageViews.tsx | 6 +- src/components/SpotifyActivity.tsx | 23 ++- src/components/Tooltip.tsx | 39 ++++ src/index.css | 21 +- src/layouts/BaseLayout.astro | 6 +- src/pages/index.astro | 175 +++++++--------- src/utils/constants.ts | 1 + tailwind.config.ts | 16 +- 17 files changed, 713 insertions(+), 140 deletions(-) create mode 100644 src/assets/devtool.svg create mode 100644 src/assets/hat.svg create mode 100644 src/assets/home.svg create mode 100644 src/components/Button.astro create mode 100644 src/components/Dock/Dock.tsx create mode 100644 src/components/Dock/MouseProvider.tsx create mode 100644 src/components/FeaturedProject.astro create mode 100644 src/components/Tooltip.tsx diff --git a/package.json b/package.json index 3e8da70..4696eaf 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "@astrojs/tailwind": "^5.1.2", "@astrojs/vercel": "^7.8.2", "@fontsource/ia-writer-mono": "^5.0.7", + "@fontsource/inter": "^5.1.0", "@fontsource/la-belle-aurore": "^5.0.18", "@splinetool/react-spline": "4.0.0", "@splinetool/runtime": "^1.9.35", @@ -33,8 +34,10 @@ "astro-seo": "^0.8.4", "cheerio": "1.0.0", "dayjs": "^1.11.13", + "motion": "^11.11.17", "react": "^18.3.1", "react-dom": "^18.3.1", + "react-use": "^17.5.1", "swr": "^2.2.5", "tailwind-merge": "^2.5.4", "tailwindcss": "^3.4.14", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 661d38f..7d13699 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -26,6 +26,9 @@ importers: '@fontsource/ia-writer-mono': specifier: ^5.0.7 version: 5.1.0 + '@fontsource/inter': + specifier: ^5.1.0 + version: 5.1.0 '@fontsource/la-belle-aurore': specifier: ^5.0.18 version: 5.1.0 @@ -62,12 +65,18 @@ importers: dayjs: specifier: ^1.11.13 version: 1.11.13 + motion: + specifier: ^11.11.17 + version: 11.11.17(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: specifier: ^18.3.1 version: 18.3.1 react-dom: specifier: ^18.3.1 version: 18.3.1(react@18.3.1) + react-use: + specifier: ^17.5.1 + version: 17.5.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) swr: specifier: ^2.2.5 version: 2.2.5(react@18.3.1) @@ -269,6 +278,10 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/runtime@7.26.0': + resolution: {integrity: sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==} + engines: {node: '>=6.9.0'} + '@babel/template@7.25.9': resolution: {integrity: sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==} engines: {node: '>=6.9.0'} @@ -446,6 +459,9 @@ packages: '@fontsource/ia-writer-mono@5.1.0': resolution: {integrity: sha512-eddYdr7R5+yS8GUaudjcN/qKEdlvR/6PjONnQikMc7LORLXOksb3eGPI8y1YjGNpGS7XBUCWq6QnILI5AAguxw==} + '@fontsource/inter@5.1.0': + resolution: {integrity: sha512-zKZR3kf1G0noIes1frLfOHP5EXVVm0M7sV/l9f/AaYf+M/DId35FO4LkigWjqWYjTJZGgplhdv4cB+ssvCqr5A==} + '@fontsource/la-belle-aurore@5.1.0': resolution: {integrity: sha512-P/IIWAjLsnMkj1ceFFA3rLBiXreQaiFfG684ZSYbOhMZEgs9+tQDTbpWqtqvGxhHeU194eEVaM9MWUv53XXaBA==} @@ -753,6 +769,9 @@ packages: '@types/hast@3.0.4': resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + '@types/js-cookie@2.2.7': + resolution: {integrity: sha512-aLkWa0C0vO5b4Sr798E26QgOkss68Un0bLjs7u9qxzPT5CG+8DuNTffWES58YzJs3hrVAOs1wonycqEBqNJubA==} + '@types/mdast@4.0.4': resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} @@ -834,6 +853,9 @@ packages: '@vscode/l10n@0.0.18': resolution: {integrity: sha512-KYSIHVmslkaCDyw013pphY+d7x1qV8IZupYfeIfzNA+nsaWHbn5uPuQRvdRFsa9zFzGeudPuoGoZ1Op4jrJXIQ==} + '@xobotyi/scrollbar-width@1.9.5': + resolution: {integrity: sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ==} + abbrev@1.1.1: resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} @@ -1084,6 +1106,9 @@ packages: resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} engines: {node: '>= 0.6'} + copy-to-clipboard@3.3.3: + resolution: {integrity: sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==} + cross-spawn@7.0.3: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} @@ -1091,9 +1116,16 @@ packages: crypto-js@4.2.0: resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==} + css-in-js-utils@3.1.0: + resolution: {integrity: sha512-fJAcud6B3rRu+KHYk+Bwf+WFL2MDCJJ1XG9x137tJQ0xYxor7XziQtuGFbWNdqrvF4Tk26O3H73nfVqXt/fW1A==} + css-select@5.1.0: resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==} + css-tree@1.1.3: + resolution: {integrity: sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==} + engines: {node: '>=8.0.0'} + css-what@6.1.0: resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} engines: {node: '>= 6'} @@ -1194,6 +1226,9 @@ packages: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} + error-stack-parser@2.1.4: + resolution: {integrity: sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==} + es-module-lexer@1.5.4: resolution: {integrity: sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==} @@ -1238,6 +1273,9 @@ packages: resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} engines: {node: '>=8.6.0'} + fast-shallow-equal@1.0.0: + resolution: {integrity: sha512-HPtaa38cPgWvaCFmRNhlc6NG7pv6NUHqjPgVAkWGoB9mQMwYB27/K0CvOM5Czy+qpT3e8XJ6Q4aPAnzpNpzNaw==} + fast-uri@3.0.3: resolution: {integrity: sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==} @@ -1245,6 +1283,9 @@ packages: resolution: {integrity: sha512-/PlTQCI96+fZMAOLMZK4CWG1ItCbfZ/0jx7UIJFChPNrx7tcEgerUgWbeieCM9MfHInUDyK8DWYZ+YrywDJuTg==} hasBin: true + fastest-stable-stringify@2.0.2: + resolution: {integrity: sha512-bijHueCGd0LqqNK9b5oCMHc0MluJAx0cwqASgbWMvkO01lCYgIhacVRLcaDz3QnyYIRNJRDwMb41VuT6pHJ91Q==} + fastq@1.17.1: resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} @@ -1277,6 +1318,20 @@ packages: fraction.js@4.3.7: resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} + framer-motion@11.11.17: + resolution: {integrity: sha512-O8QzvoKiuzI5HSAHbcYuL6xU+ZLXbrH7C8Akaato4JzQbX2ULNeniqC2Vo5eiCtFktX9XsJ+7nUhxcl2E2IjpA==} + peerDependencies: + '@emotion/is-prop-valid': '*' + react: ^18.0.0 + react-dom: ^18.0.0 + peerDependenciesMeta: + '@emotion/is-prop-valid': + optional: true + react: + optional: true + react-dom: + optional: true + fs-minipass@2.1.0: resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} engines: {node: '>= 8'} @@ -1392,6 +1447,9 @@ packages: resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} engines: {node: '>= 6'} + hyphenate-style-name@1.1.0: + resolution: {integrity: sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw==} + iconv-lite@0.6.3: resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} @@ -1406,6 +1464,9 @@ packages: inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + inline-style-prefixer@7.0.1: + resolution: {integrity: sha512-lhYo5qNTQp3EvSSp3sRvXMbVQTLrvGV6DycRMJ5dm2BLMiJ30wpXKdDdgX+GmJZ5uQMucwRKHamXSst3Sj/Giw==} + is-arrayish@0.3.2: resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} @@ -1477,6 +1538,9 @@ packages: resolution: {integrity: sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==} hasBin: true + js-cookie@2.2.1: + resolution: {integrity: sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==} + js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -1622,6 +1686,9 @@ packages: mdast-util-to-string@4.0.0: resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + mdn-data@2.0.14: + resolution: {integrity: sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==} + merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} @@ -1746,6 +1813,20 @@ packages: engines: {node: '>=10'} hasBin: true + motion@11.11.17: + resolution: {integrity: sha512-y6mXYElvJ5HHwPBUpYG/5wclKVGW4hJhqPkTjWccib5/WrcRM185adg3+4aSmG5iD10XKFt5uBOAiKwuzMHPPQ==} + peerDependencies: + '@emotion/is-prop-valid': '*' + react: ^18.0.0 + react-dom: ^18.0.0 + peerDependenciesMeta: + '@emotion/is-prop-valid': + optional: true + react: + optional: true + react-dom: + optional: true + mrmime@2.0.0: resolution: {integrity: sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==} engines: {node: '>=10'} @@ -1759,6 +1840,12 @@ packages: mz@2.7.0: resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + nano-css@5.6.2: + resolution: {integrity: sha512-+6bHaC8dSDGALM1HJjOHVXpuastdu2xFoZlC77Jh4cg+33Zcgm+Gxd+1xsnpZK14eyHObSp82+ll5y3SX75liw==} + peerDependencies: + react: '*' + react-dom: '*' + nanoid@3.3.7: resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -2070,6 +2157,18 @@ packages: resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==} engines: {node: '>=0.10.0'} + react-universal-interface@0.6.2: + resolution: {integrity: sha512-dg8yXdcQmvgR13RIlZbTRQOoUrDciFVoSBZILwjE2LFISxZZ8loVJKAkuzswl5js8BHda79bIb2b84ehU8IjXw==} + peerDependencies: + react: '*' + tslib: '*' + + react-use@17.5.1: + resolution: {integrity: sha512-LG/uPEVRflLWMwi3j/sZqR00nF6JGqTTDblkXK2nzXsIvij06hXl1V/MZIlwj1OKIQUtlh1l9jK8gLsRyCQxMg==} + peerDependencies: + react: '*' + react-dom: '*' + react@18.3.1: resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} engines: {node: '>=0.10.0'} @@ -2089,6 +2188,9 @@ packages: resolution: {integrity: sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==} engines: {node: '>= 14.16.0'} + regenerator-runtime@0.14.1: + resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + regex@4.3.3: resolution: {integrity: sha512-r/AadFO7owAq1QJVeZ/nq9jNS1vyZt+6t1p/E59B56Rn2GCya+gr1KSyOzNL/er+r+B7phv5jG2xU2Nz1YkmJg==} @@ -2134,6 +2236,9 @@ packages: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} + resize-observer-polyfill@1.5.1: + resolution: {integrity: sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==} + resolve-from@5.0.0: resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} engines: {node: '>=8'} @@ -2172,6 +2277,9 @@ packages: engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true + rtl-css-js@1.16.1: + resolution: {integrity: sha512-lRQgou1mu19e+Ya0LsTvKrVJ5TYUbqCVPAiImX3UfLTenarvPUl1QFdvu5Z3PYmHT9RCcwIfbjRQBntExyj3Zg==} + run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} @@ -2190,6 +2298,10 @@ packages: scheduler@0.23.2: resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} + screenfull@5.2.0: + resolution: {integrity: sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA==} + engines: {node: '>=0.10.0'} + section-matter@1.0.0: resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==} engines: {node: '>=4'} @@ -2212,6 +2324,10 @@ packages: set-blocking@2.0.0: resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + set-harmonic-interval@1.0.1: + resolution: {integrity: sha512-AhICkFV84tBP1aWqPwLZqFvAwqEoVA9kxNMniGEUvzOlm4vLmOFLiTT3UZ6bziJTy4bOVpzWGTfSCbmaayGx8g==} + engines: {node: '>=6.9'} + sharp@0.33.5: resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} @@ -2244,12 +2360,32 @@ packages: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} + source-map@0.5.6: + resolution: {integrity: sha512-MjZkVp0NHr5+TPihLcadqnlVoGIoWo4IBHptutGh9wI3ttUYvCG26HkSuDi+K6lsZ25syXJXcctwgyVCt//xqA==} + engines: {node: '>=0.10.0'} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + space-separated-tokens@2.0.2: resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + stack-generator@2.0.10: + resolution: {integrity: sha512-mwnua/hkqM6pF4k8SnmZ2zfETsRUpWXREfA/goT8SLCV4iOFa4bzOX2nDipWAZFPTjLvQB82f5yaodMVhK0yJQ==} + + stackframe@1.3.4: + resolution: {integrity: sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==} + + stacktrace-gps@3.1.2: + resolution: {integrity: sha512-GcUgbO4Jsqqg6RxfyTHFiPxdPqF+3LFmQhm7MgCuYQOYuWyqxo5pwRPz5d/u6/WYJdEnWfK4r+jGbyD8TSggXQ==} + + stacktrace-js@2.0.2: + resolution: {integrity: sha512-Je5vBeY4S1r/RnLydLl0TBTi3F2qdfWmYsGvtfZgEI+SCprPppaIhQf5nGcal4gI4cGpCV/duLcAzT1np6sQqg==} + stdin-discarder@0.2.2: resolution: {integrity: sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==} engines: {node: '>=18'} @@ -2291,6 +2427,9 @@ packages: strnum@1.0.5: resolution: {integrity: sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==} + stylis@4.3.4: + resolution: {integrity: sha512-osIBl6BGUmSfDkyH2mB7EFvCJntXDrLhKjHTRj/rK6xLH0yuPrHULDRQzKokSOD4VoorhtKpfcfW1GAntu8now==} + sucrase@3.35.0: resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} engines: {node: '>=16 || 14 >=14.17'} @@ -2332,6 +2471,10 @@ packages: thenify@3.3.1: resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + throttle-debounce@3.0.1: + resolution: {integrity: sha512-dTEWWNu6JmeVXY0ZYoPuH5cRIwc0MeGbJwah9KUNYSJwommQpCzTySTpEe8Gs1J23aeWEuAobe4Ag7EHVt/LOg==} + engines: {node: '>=10'} + thumbhash@0.1.1: resolution: {integrity: sha512-kH5pKeIIBPQXAOni2AiY/Cu/NKdkFREdpH+TLdM0g6WA7RriCv0kPLgP731ady67MhTAqrVG/4mnEeibVuCJcg==} @@ -2342,6 +2485,9 @@ packages: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} + toggle-selection@1.0.6: + resolution: {integrity: sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==} + tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} @@ -2351,6 +2497,9 @@ packages: trough@2.2.0: resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} + ts-easing@0.2.0: + resolution: {integrity: sha512-Z86EW+fFFh/IFB1fqQ3/+7Zpf9t2ebOAxNI/V6Wo7r5gqiqtxmgTlQ1qbqQcjLKYeSHPTsEmvlJUDg/EuL0uHQ==} + ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} @@ -2961,6 +3110,10 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/runtime@7.26.0': + dependencies: + regenerator-runtime: 0.14.1 + '@babel/template@7.25.9': dependencies: '@babel/code-frame': 7.26.0 @@ -3083,6 +3236,8 @@ snapshots: '@fontsource/ia-writer-mono@5.1.0': {} + '@fontsource/inter@5.1.0': {} + '@fontsource/la-belle-aurore@5.1.0': {} '@img/sharp-darwin-arm64@0.33.5': @@ -3366,6 +3521,8 @@ snapshots: dependencies: '@types/unist': 3.0.3 + '@types/js-cookie@2.2.7': {} + '@types/mdast@4.0.4': dependencies: '@types/unist': 3.0.3 @@ -3486,6 +3643,8 @@ snapshots: '@vscode/l10n@0.0.18': {} + '@xobotyi/scrollbar-width@1.9.5': {} + abbrev@1.1.1: {} acorn-import-attributes@1.9.5(acorn@8.13.0): @@ -3808,6 +3967,10 @@ snapshots: cookie@0.7.2: {} + copy-to-clipboard@3.3.3: + dependencies: + toggle-selection: 1.0.6 + cross-spawn@7.0.3: dependencies: path-key: 3.1.1 @@ -3816,6 +3979,10 @@ snapshots: crypto-js@4.2.0: {} + css-in-js-utils@3.1.0: + dependencies: + hyphenate-style-name: 1.1.0 + css-select@5.1.0: dependencies: boolbase: 1.0.0 @@ -3824,6 +3991,11 @@ snapshots: domutils: 3.1.0 nth-check: 2.1.1 + css-tree@1.1.3: + dependencies: + mdn-data: 2.0.14 + source-map: 0.6.1 + css-what@6.1.0: {} cssesc@3.0.0: {} @@ -3904,6 +4076,10 @@ snapshots: entities@4.5.0: {} + error-stack-parser@2.1.4: + dependencies: + stackframe: 1.3.4 + es-module-lexer@1.5.4: {} esbuild@0.21.5: @@ -3962,12 +4138,16 @@ snapshots: merge2: 1.4.1 micromatch: 4.0.8 + fast-shallow-equal@1.0.0: {} + fast-uri@3.0.3: {} fast-xml-parser@4.5.0: dependencies: strnum: 1.0.5 + fastest-stable-stringify@2.0.2: {} + fastq@1.17.1: dependencies: reusify: 1.0.4 @@ -3999,6 +4179,13 @@ snapshots: fraction.js@4.3.7: {} + framer-motion@11.11.17(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + tslib: 2.8.0 + optionalDependencies: + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + fs-minipass@2.1.0: dependencies: minipass: 3.3.6 @@ -4180,6 +4367,8 @@ snapshots: transitivePeerDependencies: - supports-color + hyphenate-style-name@1.1.0: {} + iconv-lite@0.6.3: dependencies: safer-buffer: 2.1.2 @@ -4193,6 +4382,10 @@ snapshots: inherits@2.0.4: {} + inline-style-prefixer@7.0.1: + dependencies: + css-in-js-utils: 3.1.0 + is-arrayish@0.3.2: optional: true @@ -4244,6 +4437,8 @@ snapshots: jiti@1.21.6: {} + js-cookie@2.2.1: {} + js-tokens@4.0.0: {} js-yaml@3.14.1: @@ -4450,6 +4645,8 @@ snapshots: dependencies: '@types/mdast': 4.0.4 + mdn-data@2.0.14: {} + merge2@1.4.1: {} micromark-core-commonmark@2.0.1: @@ -4673,6 +4870,14 @@ snapshots: mkdirp@1.0.4: {} + motion@11.11.17(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + framer-motion: 11.11.17(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + tslib: 2.8.0 + optionalDependencies: + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + mrmime@2.0.0: {} ms@2.1.3: {} @@ -4685,6 +4890,19 @@ snapshots: object-assign: 4.1.1 thenify-all: 1.6.0 + nano-css@5.6.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + css-tree: 1.1.3 + csstype: 3.1.3 + fastest-stable-stringify: 2.0.2 + inline-style-prefixer: 7.0.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + rtl-css-js: 1.16.1 + stacktrace-js: 2.0.2 + stylis: 4.3.4 + nanoid@3.3.7: {} neotraverse@0.6.18: {} @@ -4914,6 +5132,30 @@ snapshots: react-refresh@0.14.2: {} + react-universal-interface@0.6.2(react@18.3.1)(tslib@2.8.0): + dependencies: + react: 18.3.1 + tslib: 2.8.0 + + react-use@17.5.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@types/js-cookie': 2.2.7 + '@xobotyi/scrollbar-width': 1.9.5 + copy-to-clipboard: 3.3.3 + fast-deep-equal: 3.1.3 + fast-shallow-equal: 1.0.0 + js-cookie: 2.2.1 + nano-css: 5.6.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-universal-interface: 0.6.2(react@18.3.1)(tslib@2.8.0) + resize-observer-polyfill: 1.5.1 + screenfull: 5.2.0 + set-harmonic-interval: 1.0.1 + throttle-debounce: 3.0.1 + ts-easing: 0.2.0 + tslib: 2.8.0 + react@18.3.1: dependencies: loose-envify: 1.4.0 @@ -4934,6 +5176,8 @@ snapshots: readdirp@4.0.2: {} + regenerator-runtime@0.14.1: {} + regex@4.3.3: {} rehype-parse@9.0.1: @@ -5010,6 +5254,8 @@ snapshots: require-from-string@2.0.2: {} + resize-observer-polyfill@1.5.1: {} + resolve-from@5.0.0: {} resolve@1.22.8: @@ -5076,6 +5322,10 @@ snapshots: '@rollup/rollup-win32-x64-msvc': 4.24.0 fsevents: 2.3.3 + rtl-css-js@1.16.1: + dependencies: + '@babel/runtime': 7.26.0 + run-parallel@1.2.0: dependencies: queue-microtask: 1.2.3 @@ -5094,6 +5344,8 @@ snapshots: dependencies: loose-envify: 1.4.0 + screenfull@5.2.0: {} + section-matter@1.0.0: dependencies: extend-shallow: 2.0.1 @@ -5109,6 +5361,8 @@ snapshots: set-blocking@2.0.0: {} + set-harmonic-interval@1.0.1: {} + sharp@0.33.5: dependencies: color: 4.2.3 @@ -5164,10 +5418,31 @@ snapshots: source-map-js@1.2.1: {} + source-map@0.5.6: {} + + source-map@0.6.1: {} + space-separated-tokens@2.0.2: {} sprintf-js@1.0.3: {} + stack-generator@2.0.10: + dependencies: + stackframe: 1.3.4 + + stackframe@1.3.4: {} + + stacktrace-gps@3.1.2: + dependencies: + source-map: 0.5.6 + stackframe: 1.3.4 + + stacktrace-js@2.0.2: + dependencies: + error-stack-parser: 2.1.4 + stack-generator: 2.0.10 + stacktrace-gps: 3.1.2 + stdin-discarder@0.2.2: {} string-width@4.2.3: @@ -5211,6 +5486,8 @@ snapshots: strnum@1.0.5: {} + stylis@4.3.4: {} + sucrase@3.35.0: dependencies: '@jridgewell/gen-mapping': 0.3.5 @@ -5283,6 +5560,8 @@ snapshots: dependencies: any-promise: 1.3.0 + throttle-debounce@3.0.1: {} + thumbhash@0.1.1: {} tinyexec@0.3.1: {} @@ -5291,20 +5570,23 @@ snapshots: dependencies: is-number: 7.0.0 + toggle-selection@1.0.6: {} + tr46@0.0.3: {} trim-lines@3.0.1: {} trough@2.2.0: {} + ts-easing@0.2.0: {} + ts-interface-checker@0.1.13: {} tsconfck@3.1.4(typescript@5.6.3): optionalDependencies: typescript: 5.6.3 - tslib@2.8.0: - optional: true + tslib@2.8.0: {} type-fest@4.26.1: {} diff --git a/src/assets/devtool.svg b/src/assets/devtool.svg new file mode 100644 index 0000000..e8433db --- /dev/null +++ b/src/assets/devtool.svg @@ -0,0 +1,4 @@ + + + \ No newline at end of file diff --git a/src/assets/hat.svg b/src/assets/hat.svg new file mode 100644 index 0000000..e26eca5 --- /dev/null +++ b/src/assets/hat.svg @@ -0,0 +1,5 @@ + + + \ No newline at end of file diff --git a/src/assets/home.svg b/src/assets/home.svg new file mode 100644 index 0000000..c44de8f --- /dev/null +++ b/src/assets/home.svg @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/src/components/Button.astro b/src/components/Button.astro new file mode 100644 index 0000000..0d8bd69 --- /dev/null +++ b/src/components/Button.astro @@ -0,0 +1,26 @@ +--- +import type { HTMLAttributes } from 'astro/types' +import { twMerge } from 'tailwind-merge' + +interface Props extends HTMLAttributes<'button'> { + variant?: 'primary' | 'secondary' | 'tertiary' +} + +const { variant } = Astro.props + +const variantClasses = { + primary: 'bg-primary/50', + secondary: 'bg-neutral-700/50 ', + tertiary: 'bg-neutral-800', +} as const +--- + + diff --git a/src/components/Dock/Dock.tsx b/src/components/Dock/Dock.tsx new file mode 100644 index 0000000..3f91900 --- /dev/null +++ b/src/components/Dock/Dock.tsx @@ -0,0 +1,165 @@ +import { + cloneElement, + createContext, + useContext, + useEffect, + useRef, + useState, +} from 'react' +import homeIcon from '../../assets/home.svg?raw' +import devtoolIcon from '../../assets/devtool.svg?raw' +import { + AnimatePresence, + motion, + useMotionValueEvent, + useSpring, + useTransform, +} from 'motion/react' +import { MouseProvider, useMouse } from './MouseProvider' +import { Tooltip } from '../Tooltip' + +const DockItem = ({ + icon, + href, + index, + total, + title, +}: { + icon: React.ReactElement + href: string + index: number + total: number + title: string +}) => { + const mouse = useMouse() + + const dock = useContext(DockContext) + if (!mouse) { + throw new Error('MouseProvider not found') + } + + const dimension = useTransform(mouse?.position.x, (mouseX) => { + if (!dock?.isHovered) { + return 48 + } + + const rangeStart = dock?.dock?.getBoundingClientRect()?.left ?? 0 + const dockWidth = dock?.dock?.clientWidth ?? 1 + + // 0-1 range + const normalizedMouseX = (mouseX - rangeStart) / dockWidth + + // Calculate normalized position of the current item's center + const itemCenterX = (index + 0.5) * (1 / total) + + // Calculate the difference between mouse position and item center + const distanceFromCenter = Math.abs(normalizedMouseX - itemCenterX) + + // Maximum extra scaling amount + const scalingMagnitude = 0.6 + // How quickly the scale decreases according to distance + const distanceSensitivity = 3 + + const scaleFactor = Math.max( + 1, + 1 + scalingMagnitude * (1 - distanceFromCenter * distanceSensitivity) + ) + + // Apply scale factor to the base size (48) + return 48 * scaleFactor + }) + + const spring = useSpring(48, { + damping: 10, + stiffness: 150, + mass: 0.01, + }) + + console.log('1111', dimension.get()) + + useMotionValueEvent(dimension, 'change', (latest) => { + if (dock?.isHovered) { + spring.set(latest) + } else { + spring.set(48) + } + }) + + return ( + + + {cloneElement(icon, { + className: 'transition-colors size-3/5', + })} + + + ) +} + +type DockContext = { + isHovered: boolean + dock: HTMLDivElement | null +} + +const DockContext = createContext(null) + +const dockItems = [ + { + icon: , + href: '/', + title: 'Home', + }, + { + icon: , + href: '/', + title: 'Projects', + }, +] + +export const Dock = () => { + const ref = useRef(null) + + const [isHovered, setIsHovered] = useState(false) + + const [dock, setDock] = useState(null) + + useEffect(() => { + setDock(ref.current) + }, []) + + return ( + + +
+ { + setIsHovered(true) + }} + onHoverEnd={() => { + setIsHovered(false) + }} + ref={ref} + > + {dockItems.map((item, index) => ( + + ))} + +
+
+
+ ) +} diff --git a/src/components/Dock/MouseProvider.tsx b/src/components/Dock/MouseProvider.tsx new file mode 100644 index 0000000..9786c91 --- /dev/null +++ b/src/components/Dock/MouseProvider.tsx @@ -0,0 +1,52 @@ +import { type MotionValue, useMotionValue, useVelocity } from 'motion/react' +import { createContext, useContext, useMemo, type ReactNode } from 'react' +import { useEvent } from 'react-use' + +type MouseType = { + position: { + x: MotionValue + y: MotionValue + } + velocity: { + x: MotionValue + y: MotionValue + } +} + +const useMousePosition = () => { + const x = useMotionValue(0) + const y = useMotionValue(0) + + useEvent('mousemove', (e) => { + x.set(e.clientX) + y.set(e.clientY) + }) + + return useMemo(() => ({ x, y }), [x, y]) +} + +const MouseContext = createContext(null) + +export const useMouse = () => { + if (!MouseContext) { + throw new Error('useMouse must be used within a MouseProvider') + } + + return useContext(MouseContext) +} + +export const MouseProvider = ({ children }: { children: ReactNode }) => { + const { x, y } = useMousePosition() + const velocityX = useVelocity(x) + const velocityY = useVelocity(y) + + const mouse = useMemo( + () => ({ + position: { x, y }, + velocity: { x: velocityX, y: velocityY }, + }), + [x, y, velocityX, velocityY] + ) + + return {children} +} diff --git a/src/components/FeaturedProject.astro b/src/components/FeaturedProject.astro new file mode 100644 index 0000000..d5be30a --- /dev/null +++ b/src/components/FeaturedProject.astro @@ -0,0 +1,18 @@ +--- +import type { HTMLAttributes } from 'astro/types' +import { twMerge } from 'tailwind-merge' + +interface Props extends HTMLAttributes<'button'> { + variant?: 'primary' | 'secondary' | 'tertiary' +} + +const { variant } = Astro.props + +const variantClasses = { + primary: 'bg-primary/50', + secondary: 'bg-neutral-700/50 ', + tertiary: 'bg-neutral-800', +} as const +--- + +
diff --git a/src/components/PageViews.tsx b/src/components/PageViews.tsx index 0598706..14b43e3 100644 --- a/src/components/PageViews.tsx +++ b/src/components/PageViews.tsx @@ -16,8 +16,8 @@ export const PageViews = () => { {error &&
Error: {String(error)}
} {data && (
-

Visits

-

+

Visits

+

Total:{' '} 000000 @@ -26,7 +26,7 @@ export const PageViews = () => {

-

+

Unique:{' '} 000000 diff --git a/src/components/SpotifyActivity.tsx b/src/components/SpotifyActivity.tsx index efc719f..b30e89a 100644 --- a/src/components/SpotifyActivity.tsx +++ b/src/components/SpotifyActivity.tsx @@ -2,6 +2,7 @@ import { Suspense, useRef, useState } from 'react' import useSWR from 'swr' import { twMerge } from 'tailwind-merge' import { ScrollyText } from './ScrollyText' +import spotifyIcon from '../assets/spotify.svg' import { WaveIcon } from './icons/WaveIcon' export const SpotifyActivity = () => { @@ -19,15 +20,23 @@ export const SpotifyActivity = () => { {error &&

Error: {String(error)}
} {data && ( <> +
+ +

+ {data.isPlaying ? "I'm listening to:" : 'Recently played:'} +

+ +
+
-

- {data.isPlaying ? "I'm listening to:" : 'Recently played:'} -

-
+
@@ -39,10 +48,6 @@ export const SpotifyActivity = () => { />
-
)} diff --git a/src/components/Tooltip.tsx b/src/components/Tooltip.tsx new file mode 100644 index 0000000..556403a --- /dev/null +++ b/src/components/Tooltip.tsx @@ -0,0 +1,39 @@ +import { AnimatePresence } from 'motion/react' +import { motion } from 'motion/react' +import { useState } from 'react' + +export const Tooltip = ({ + children, + text, +}: { + children: React.ReactNode + text: string +}) => { + const [hovered, setHovered] = useState(false) + + return ( + { + setHovered(true) + }} + onHoverEnd={() => { + setHovered(false) + }} + className='relative size-full [align-items:inherit] [display:inherit] [justify-content:inherit]' + > + + {hovered && ( + + {text} + + )} + + {children} + + ) +} diff --git a/src/index.css b/src/index.css index 8dba8cc..3eccfd4 100644 --- a/src/index.css +++ b/src/index.css @@ -11,27 +11,23 @@ } @font-face { - font-family: 'iA Writer Mono'; + font-family: 'Inter'; font-style: normal; font-display: swap; font-weight: 400; src: - url(@fontsource/ia-writer-mono/files/ia-writer-mono-latin-400-normal.woff2) - format('woff2'), - url(@fontsource/ia-writer-mono/files/ia-writer-mono-latin-400-normal.woff) - format('woff'); + url(@fontsource/inter/files/inter-latin-400-normal.woff2) format('woff2'), + url(@fontsource/inter/files/inter-latin-400-normal.woff2) format('woff'); } @font-face { - font-family: 'iA Writer Mono'; + font-family: 'Inter'; font-style: normal; font-display: swap; font-weight: 700; src: - url(@fontsource/ia-writer-mono/files/ia-writer-mono-latin-700-normal.woff2) - format('woff2'), - url(@fontsource/ia-writer-mono/files/ia-writer-mono-latin-700-normal.woff) - format('woff'); + url(@fontsource/inter/files/inter-latin-700-normal.woff2) format('woff2'), + url(@fontsource/inter/files/inter-latin-700-normal.woff2) format('woff'); } @layer components { @@ -44,4 +40,9 @@ theme('colors.surface.700') 100% ); } + + .shine { + border-top: 0.5px solid rgba(255, 255, 255, 0.2); + background-image: linear-gradient(to bottom, #ffffff08, #fff0); + } } diff --git a/src/layouts/BaseLayout.astro b/src/layouts/BaseLayout.astro index 7b4feb3..cf13a28 100644 --- a/src/layouts/BaseLayout.astro +++ b/src/layouts/BaseLayout.astro @@ -12,6 +12,7 @@ interface Props { import { ViewTransitions } from 'astro:transitions' import Navigation from '../components/Navigation.astro' +import { Dock } from '../components/Dock/Dock' const { title } = Astro.props --- @@ -57,11 +58,10 @@ const { title } = Astro.props }} /> - - - +
+
diff --git a/src/pages/index.astro b/src/pages/index.astro index 6f9f40c..da86d9c 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -7,7 +7,7 @@ import reactIcon from '../assets/react-icon.svg' import graphqlIcon from '../assets/graphql-icon.svg' import nodejsIcon from '../assets/nodejs-icon.svg' import sqlIcon from '../assets/sql-icon.svg' -import spotifyIcon from '../assets/spotify.svg' + import project1Img from '../assets/project1.png' import project2Img from '../assets/project2.png' import project3Img from '../assets/project3.png' @@ -21,9 +21,11 @@ import { isProduction } from '../utils/constants' import { Social } from '../components/Social' import UnderlineRainbow from '../components/UnderlineRainbow.astro' import { PageViews } from '../components/PageViews' +import hatIcon from '../assets/hat.svg?raw' import { WaveIcon } from '../components/icons/WaveIcon' +import Button from '../components/Button.astro' -const pageTitle = "Hi, I'm Sebastian" +const pageTitle = "I'm Sebastian" const techs = [ { @@ -94,12 +96,14 @@ const projects = [ --- - {''} - {''} + <body>

- Systems Engineer & Full Stack Web Developer specialized in JavaScript - with experience in technologies like + + Systems Engineer + & Full Stack + Web Developer + + specialized in JavaScript with experience in technologies like

@@ -134,7 +142,7 @@ const projects = [
-
+
-

- Hi there! My name is Sebastian and I’m a developer with over 5 years of - work experience using web technologies. I have expertise in +

+ I like building things for the web. I'm particularly drawn to frontend + development where I can craft user interfaces and implement design + systems. I have expertise in React.js and Node.js with Typescript. - Something I enjoy from this field is figuring out simple - solutions for difficult problems. +

-

Some skills:

-
    -
  • - Decent understanding of React: hooks, context, state management etc. -
  • -
  • Next.js with SSR/SSG
  • -
  • Mobile apps with React Native
  • -
  • GraphQL
  • -
  • CSS / Tailwind
  • -
  • Databases
  • -
  • Git workflows
  • -
  • - Adherence to and monitoring of best practices through code reviews +
      +
    • +  Currently +
        +
      • + ⠀⠀Working remotely for a video surveillance + company +
      • +
    • -
    • - Clean code (eslint standards and prettier, CI workflow checks, etc) +
    • +  Before +
        +
      • + ⠀⠀Working remotely for a B2B e-commerce + company +
      • +
      • + ⠀⠀Working for a B2B ERP software + company +
      • +
      • + ⠀⠀BS in Systems + Engineering  + +
      • +
    -

    - Learning and keeping up to date with new technologies motivates me. - Right now I'm learning Python. -

-
-
-
- - -
+
+
-
+
-
- -

- Personal projects. Check more on my - Github. - +

+

+ {'>'} Featured  + +

+

+ Some personal side projects that I’ve worked on.

- +
- </body> </html>(element: T[]): T => { diff --git a/tailwind.config.ts b/tailwind.config.ts index 6b98906..67f0a5e 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -9,7 +9,6 @@ type RootTheme = { const themes = { ':root': { - '--twdc-primary': '#08FDD8', '--twdc-grayscale-50': '#FaF5F6', '--twdc-grayscale-100': '#E4E3E7', '--twdc-grayscale-200': '#C2C0C8', @@ -18,16 +17,11 @@ const themes = { '--twdc-grayscale-500': '#5D5A67', '--twdc-grayscale-600': '#3D3B43', '--twdc-grayscale-700': '#1D1C20', - '--twdc-grayscale-800': '#131215', - '--twdc-grayscale-900': '#09090A', + '--twdc-grayscale-800': '#161616', + '--twdc-grayscale-900': '#0A0A0A', }, } satisfies RootTheme -type ExtendColors = Record< - string, - Record -> - const themePlugin = plugin(({ addBase }) => { addBase(themes) }) @@ -51,11 +45,11 @@ export default { fontFamily: { belle: ['"La Belle Aurore", sans-serif'], clvtc: ['clvtc, sans-serif'], - iamono: ['"iA Writer Mono", monospace'], + primary: ['Inter', 'sans-serif'], }, colors: { primary: { - DEFAULT: 'var(--twdc-primary)', + DEFAULT: '#08FDD8', }, surface: { DEFAULT: 'var(--twdc-grayscale-500)', @@ -70,7 +64,7 @@ export default { 800: 'var(--twdc-grayscale-800)', 900: 'var(--twdc-grayscale-900)', }, - } satisfies ExtendColors, + }, animation: { swipeUp: 'swipeUp 1.8s infinite ease-in-out', marquee: 'marquee linear alternate',