From e226455c96d755826829a432ab5a21388583ee3f Mon Sep 17 00:00:00 2001 From: Leo dev Date: Wed, 21 Jan 2026 02:52:49 +0100 Subject: [PATCH] Proffesional freelance ui --- package-lock.json | 166 +++-------- package.json | 6 +- src/app/about/page.tsx | 379 ++++++++++++++++++++++++ src/app/globals.css | 254 ++++++++++++++-- src/app/layout.tsx | 10 +- src/app/page.tsx | 239 +-------------- src/app/pricing/page.tsx | 267 +++++++++++++++++ src/blogApi.ts | 129 -------- src/components/Background.tsx | 22 -- src/components/MarkdownRenderer.tsx | 73 ----- src/components/Navbar.tsx | 35 --- src/components/PinnedRepos.tsx | 178 ----------- src/components/Skill.tsx | 29 -- src/components/effects.ts | 32 -- src/components/home/CTASection.tsx | 39 +++ src/components/home/HeroSection.tsx | 97 ++++++ src/components/home/ProjectsSection.tsx | 159 ++++++++++ src/components/home/SkillsSection.tsx | 112 +++++++ src/components/layout/Footer.tsx | 118 ++++++++ src/components/layout/Layout.tsx | 19 ++ src/components/layout/Navbar.tsx | 152 ++++++++++ src/lib/utils.ts | 6 + src/notion.ts | 15 - tailwind.config.ts | 115 +++++-- 24 files changed, 1739 insertions(+), 912 deletions(-) create mode 100644 src/app/about/page.tsx create mode 100644 src/app/pricing/page.tsx delete mode 100644 src/blogApi.ts delete mode 100644 src/components/Background.tsx delete mode 100644 src/components/MarkdownRenderer.tsx delete mode 100644 src/components/Navbar.tsx delete mode 100644 src/components/PinnedRepos.tsx delete mode 100644 src/components/Skill.tsx delete mode 100644 src/components/effects.ts create mode 100644 src/components/home/CTASection.tsx create mode 100644 src/components/home/HeroSection.tsx create mode 100644 src/components/home/ProjectsSection.tsx create mode 100644 src/components/home/SkillsSection.tsx create mode 100644 src/components/layout/Footer.tsx create mode 100644 src/components/layout/Layout.tsx create mode 100644 src/components/layout/Navbar.tsx create mode 100644 src/lib/utils.ts delete mode 100644 src/notion.ts diff --git a/package-lock.json b/package-lock.json index 89c87aa..8ca4957 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,8 +14,10 @@ "@fortawesome/free-regular-svg-icons": "^6.7.2", "@fortawesome/free-solid-svg-icons": "^6.7.2", "@fortawesome/react-fontawesome": "^0.2.2", + "@icons-pack/react-simple-icons": "^13.8.0", "@notionhq/client": "^2.2.15", "@types/react-syntax-highlighter": "^15.5.13", + "clsx": "^2.1.1", "dotenv": "^16.4.7", "framer-motion": "^12.23.25", "katex": "^0.16.19", @@ -32,10 +34,12 @@ "remark-breaks": "^4.0.0", "remark-gfm": "^4.0.0", "remark-math": "^6.0.0", + "tailwind-merge": "^3.4.0", + "tailwindcss-animate": "^1.0.7", "tsparticles-slim": "^2.12.0" }, "devDependencies": { - "@types/node": "^20", + "@types/node": "^20.19.30", "@types/react": "^19", "@types/react-dom": "^19", "postcss": "^8", @@ -47,7 +51,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", - "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -157,6 +160,15 @@ "react": ">=16.3" } }, + "node_modules/@icons-pack/react-simple-icons": { + "version": "13.8.0", + "resolved": "https://registry.npmjs.org/@icons-pack/react-simple-icons/-/react-simple-icons-13.8.0.tgz", + "integrity": "sha512-iZrhL1fSklfCCVn68IYHaAoKfcby3RakUTn2tRPyHBkhr2tkYqeQbjJWf+NizIYBzKBn2IarDJXmTdXd6CuEfw==", + "license": "MIT", + "peerDependencies": { + "react": "^16.13 || ^17 || ^18 || ^19" + } + }, "node_modules/@img/colour": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.0.0.tgz", @@ -627,7 +639,6 @@ "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, "license": "ISC", "dependencies": { "string-width": "^5.1.2", @@ -645,7 +656,6 @@ "version": "0.3.8", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", - "dev": true, "license": "MIT", "dependencies": { "@jridgewell/set-array": "^1.2.1", @@ -660,7 +670,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, "license": "MIT", "engines": { "node": ">=6.0.0" @@ -670,7 +679,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "dev": true, "license": "MIT", "engines": { "node": ">=6.0.0" @@ -680,14 +688,12 @@ "version": "1.5.0", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", - "dev": true, "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.25", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dev": true, "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", @@ -832,7 +838,6 @@ "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", @@ -846,7 +851,6 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, "license": "MIT", "engines": { "node": ">= 8" @@ -856,7 +860,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", @@ -883,7 +886,6 @@ "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, "license": "MIT", "optional": true, "engines": { @@ -954,12 +956,12 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "20.17.11", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.11.tgz", - "integrity": "sha512-Ept5glCK35R8yeyIeYlRIZtX6SLRyqMhOFTgj5SOkMpLTdw3SEHI9fHx60xaUZ+V1aJxQJODE+7/j5ocZydYTg==", + "version": "20.19.30", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.30.tgz", + "integrity": "sha512-WJtwWJu7UdlvzEAUm484QNg5eAoq5QR08KDNx7g45Usrs2NtOPiX8ugDqmKdXkyL03rBqU5dYNYVQetEpBHq2g==", "license": "MIT", "dependencies": { - "undici-types": "~6.19.2" + "undici-types": "~6.21.0" } }, "node_modules/@types/node-fetch": { @@ -1016,7 +1018,6 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -1029,7 +1030,6 @@ "version": "6.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -1042,14 +1042,12 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", - "dev": true, "license": "MIT" }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", @@ -1063,7 +1061,6 @@ "version": "5.0.2", "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", - "dev": true, "license": "MIT" }, "node_modules/asynckit": { @@ -1086,14 +1083,12 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, "license": "MIT" }, "node_modules/binary-extensions": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -1106,7 +1101,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" @@ -1116,7 +1110,6 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, "license": "MIT", "dependencies": { "fill-range": "^7.1.1" @@ -1129,7 +1122,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", - "dev": true, "license": "MIT", "engines": { "node": ">= 6" @@ -1209,7 +1201,6 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, "license": "MIT", "dependencies": { "anymatch": "~3.1.2", @@ -1234,7 +1225,6 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, "license": "ISC", "dependencies": { "is-glob": "^4.0.1" @@ -1249,11 +1239,19 @@ "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", "license": "MIT" }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -1266,7 +1264,6 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, "license": "MIT" }, "node_modules/combined-stream": { @@ -1295,7 +1292,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", - "dev": true, "license": "MIT", "engines": { "node": ">= 6" @@ -1305,7 +1301,6 @@ "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "dev": true, "license": "MIT", "dependencies": { "path-key": "^3.1.0", @@ -1320,7 +1315,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "dev": true, "license": "MIT", "bin": { "cssesc": "bin/cssesc" @@ -1420,14 +1414,12 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", - "dev": true, "license": "Apache-2.0" }, "node_modules/dlv": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", - "dev": true, "license": "MIT" }, "node_modules/dotenv": { @@ -1446,14 +1438,12 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true, "license": "MIT" }, "node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true, "license": "MIT" }, "node_modules/entities": { @@ -1500,7 +1490,6 @@ "version": "3.3.2", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", - "dev": true, "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", @@ -1517,7 +1506,6 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, "license": "ISC", "dependencies": { "is-glob": "^4.0.1" @@ -1530,7 +1518,6 @@ "version": "1.18.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.18.0.tgz", "integrity": "sha512-QKHXPW0hD8g4UET03SdOdunzSouc9N4AuHdsX8XNcTsuz+yYFILVNIX4l9yHABMhiEI9Db0JTTIpu0wB+Y1QQw==", - "dev": true, "license": "ISC", "dependencies": { "reusify": "^1.0.4" @@ -1553,7 +1540,6 @@ "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" @@ -1566,7 +1552,6 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", - "dev": true, "license": "ISC", "dependencies": { "cross-spawn": "^7.0.0", @@ -1632,7 +1617,6 @@ "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, "hasInstallScript": true, "license": "MIT", "optional": true, @@ -1647,7 +1631,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -1657,7 +1640,6 @@ "version": "10.4.5", "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", - "dev": true, "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", @@ -1678,7 +1660,6 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, "license": "ISC", "dependencies": { "is-glob": "^4.0.3" @@ -1691,7 +1672,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -2086,7 +2066,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, "license": "MIT", "dependencies": { "binary-extensions": "^2.0.0" @@ -2099,7 +2078,6 @@ "version": "2.16.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", - "dev": true, "license": "MIT", "dependencies": { "hasown": "^2.0.2" @@ -2125,7 +2103,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -2135,7 +2112,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -2145,7 +2121,6 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" @@ -2168,7 +2143,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.12.0" @@ -2190,14 +2164,12 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true, "license": "ISC" }, "node_modules/jackspeak": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/cliui": "^8.0.2" @@ -2213,7 +2185,6 @@ "version": "1.21.7", "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", - "dev": true, "license": "MIT", "bin": { "jiti": "bin/jiti.js" @@ -2254,7 +2225,6 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", - "dev": true, "license": "MIT", "engines": { "node": ">=14" @@ -2267,7 +2237,6 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true, "license": "MIT" }, "node_modules/longest-streak": { @@ -2310,7 +2279,6 @@ "version": "10.4.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, "license": "ISC" }, "node_modules/lucide-react": { @@ -2652,7 +2620,6 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 8" @@ -3244,7 +3211,6 @@ "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "dev": true, "license": "MIT", "dependencies": { "braces": "^3.0.3", @@ -3279,7 +3245,6 @@ "version": "9.0.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" @@ -3295,7 +3260,6 @@ "version": "7.1.2", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true, "license": "ISC", "engines": { "node": ">=16 || 14 >=14.17" @@ -3326,7 +3290,6 @@ "version": "2.7.0", "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "dev": true, "license": "MIT", "dependencies": { "any-promise": "^1.0.0", @@ -3456,7 +3419,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -3488,7 +3450,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", - "dev": true, "license": "MIT", "engines": { "node": ">= 6" @@ -3498,7 +3459,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", - "dev": true, "license": "BlueOak-1.0.0" }, "node_modules/parse-entities": { @@ -3542,7 +3502,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -3552,14 +3511,12 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true, "license": "MIT" }, "node_modules/path-scurry": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "lru-cache": "^10.2.0", @@ -3582,7 +3539,6 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, "license": "MIT", "engines": { "node": ">=8.6" @@ -3595,7 +3551,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -3605,7 +3560,6 @@ "version": "4.0.6", "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 6" @@ -3615,7 +3569,6 @@ "version": "8.4.49", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", - "dev": true, "funding": [ { "type": "opencollective", @@ -3644,7 +3597,6 @@ "version": "15.1.0", "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", - "dev": true, "license": "MIT", "dependencies": { "postcss-value-parser": "^4.0.0", @@ -3662,7 +3614,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", - "dev": true, "license": "MIT", "dependencies": { "camelcase-css": "^2.0.1" @@ -3682,7 +3633,6 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", - "dev": true, "funding": [ { "type": "opencollective", @@ -3718,7 +3668,6 @@ "version": "6.2.0", "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", - "dev": true, "funding": [ { "type": "opencollective", @@ -3744,7 +3693,6 @@ "version": "6.1.2", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", - "dev": true, "license": "MIT", "dependencies": { "cssesc": "^3.0.0", @@ -3758,7 +3706,6 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "dev": true, "license": "MIT" }, "node_modules/prismjs": { @@ -3795,7 +3742,6 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, "funding": [ { "type": "github", @@ -3910,7 +3856,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", - "dev": true, "license": "MIT", "dependencies": { "pify": "^2.3.0" @@ -3920,7 +3865,6 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, "license": "MIT", "dependencies": { "picomatch": "^2.2.1" @@ -4195,7 +4139,6 @@ "version": "1.22.10", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", - "dev": true, "license": "MIT", "dependencies": { "is-core-module": "^2.16.0", @@ -4216,7 +4159,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, "license": "MIT", "engines": { "iojs": ">=1.0.0", @@ -4227,7 +4169,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, "funding": [ { "type": "github", @@ -4315,7 +4256,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" @@ -4328,7 +4268,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -4338,7 +4277,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, "license": "ISC", "engines": { "node": ">=14" @@ -4370,7 +4308,6 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, "license": "MIT", "dependencies": { "eastasianwidth": "^0.2.0", @@ -4389,7 +4326,6 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -4404,7 +4340,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -4414,14 +4349,12 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, "license": "MIT" }, "node_modules/string-width-cjs/node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -4448,7 +4381,6 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" @@ -4465,7 +4397,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -4478,7 +4409,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -4520,7 +4450,6 @@ "version": "3.35.0", "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", - "dev": true, "license": "MIT", "dependencies": { "@jridgewell/gen-mapping": "^0.3.2", @@ -4543,7 +4472,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -4552,11 +4480,20 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/tailwind-merge": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.4.0.tgz", + "integrity": "sha512-uSaO4gnW+b3Y2aWoWfFpX62vn2sR3skfhbjsEnaBI81WD1wBLlHZe5sWf0AqjksNdYTbGBEd0UasQMT3SNV15g==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/dcastil" + } + }, "node_modules/tailwindcss": { "version": "3.4.17", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.17.tgz", "integrity": "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==", - "dev": true, "license": "MIT", "dependencies": { "@alloc/quick-lru": "^5.2.0", @@ -4590,11 +4527,19 @@ "node": ">=14.0.0" } }, + "node_modules/tailwindcss-animate": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/tailwindcss-animate/-/tailwindcss-animate-1.0.7.tgz", + "integrity": "sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==", + "license": "MIT", + "peerDependencies": { + "tailwindcss": ">=3.0.0 || insiders" + } + }, "node_modules/thenify": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", - "dev": true, "license": "MIT", "dependencies": { "any-promise": "^1.0.0" @@ -4604,7 +4549,6 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", - "dev": true, "license": "MIT", "dependencies": { "thenify": ">= 3.1.0 < 4" @@ -4617,7 +4561,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, "license": "MIT", "dependencies": { "is-number": "^7.0.0" @@ -4656,7 +4599,6 @@ "version": "0.1.13", "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", - "dev": true, "license": "Apache-2.0" }, "node_modules/tslib": { @@ -5126,9 +5068,9 @@ } }, "node_modules/undici-types": { - "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "license": "MIT" }, "node_modules/unified": { @@ -5250,7 +5192,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true, "license": "MIT" }, "node_modules/vfile": { @@ -5325,7 +5266,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, "license": "ISC", "dependencies": { "isexe": "^2.0.0" @@ -5341,7 +5281,6 @@ "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^6.1.0", @@ -5360,7 +5299,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", @@ -5378,7 +5316,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -5388,7 +5325,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -5404,14 +5340,12 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, "license": "MIT" }, "node_modules/wrap-ansi-cjs/node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -5426,7 +5360,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -5448,7 +5381,6 @@ "version": "2.7.0", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz", "integrity": "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==", - "dev": true, "license": "ISC", "bin": { "yaml": "bin.mjs" diff --git a/package.json b/package.json index 747c66b..1656a1f 100644 --- a/package.json +++ b/package.json @@ -15,8 +15,10 @@ "@fortawesome/free-regular-svg-icons": "^6.7.2", "@fortawesome/free-solid-svg-icons": "^6.7.2", "@fortawesome/react-fontawesome": "^0.2.2", + "@icons-pack/react-simple-icons": "^13.8.0", "@notionhq/client": "^2.2.15", "@types/react-syntax-highlighter": "^15.5.13", + "clsx": "^2.1.1", "dotenv": "^16.4.7", "framer-motion": "^12.23.25", "katex": "^0.16.19", @@ -33,10 +35,12 @@ "remark-breaks": "^4.0.0", "remark-gfm": "^4.0.0", "remark-math": "^6.0.0", + "tailwind-merge": "^3.4.0", + "tailwindcss-animate": "^1.0.7", "tsparticles-slim": "^2.12.0" }, "devDependencies": { - "@types/node": "^20", + "@types/node": "^20.19.30", "@types/react": "^19", "@types/react-dom": "^19", "postcss": "^8", diff --git a/src/app/about/page.tsx b/src/app/about/page.tsx new file mode 100644 index 0000000..bb40680 --- /dev/null +++ b/src/app/about/page.tsx @@ -0,0 +1,379 @@ +import { Layout } from "@/components/layout/Layout"; +import { + Github, + Linkedin, + Youtube, + Instagram, + ExternalLink, + MapPin, + Crown, + Code, + Trophy, + Box, + FileText, +} from "lucide-react"; +import { + SiRust, + SiTypescript, + SiReact, + SiGo, + SiPython, + SiDocker, + SiLinux, +} from "@icons-pack/react-simple-icons"; +import { cn } from "@/lib/utils"; + +const timeline = [ + { + year: "2020", + title: "Started Programming Journey", + description: + "Began learning programming at age 10, with C# .net WinForms applications.", + }, + { + year: "2021", + title: "Started learning Python and Web Development", + description: + "Began learning Python and web development, building my first fully coded applications.", + }, + { + year: "2022", + title: "First Open Source Contributions", + description: + "Started contributing to open source projects and building my GitHub presence.", + }, + { + year: "2023", + title: "Hacking tools", + description: + "Started building hacking tools and security-focused applications.", + }, + { + year: "2024", + title: "Founded ORUS", + description: "Created the orus-dev organization to house major projects.", + }, + { + year: "2025", + title: "Expanding Horizons", + description: + "Taking on freelance work and building products that make a difference.", + }, +]; + +export default function About() { + const techStack = [ + { name: "Rust", icon: , color: "text-orange-500" }, + { name: "TypeScript", icon: , color: "text-blue-500" }, + { name: "React", icon: , color: "text-cyan-500" }, + { name: "Go", icon: , color: "text-cyan-400" }, + { name: "Python", icon: , color: "text-yellow-500" }, + { + name: "Java", + icon: ( + + + + + ), + color: "text-red-500", + }, + { name: "Docker", icon: , color: "text-blue-400" }, + { name: "Linux", icon: , color: "text-yellow-400" }, + ]; + + const achievements = [ + { + icon: , + title: "Top GitHub Contributor in Albania", + description: + "Ranked #2 nationally based on commits, contributions, and repository activity.", + }, + { + icon: , + title: "Contributor to 80+ Public Repositories", + description: + "Actively contributed code, bug fixes, and features to multiple open-source projects.", + }, + { + icon: , + title: "Built & Deployed 3 Full-Stack Applications", + description: + "Completed end-to-end development projects using Next.js, React, and TypeScript.", + }, + { + icon: , + title: "Published Technical Guides & Documentation", + description: + "Authored clear technical documentation and tutorials in public repositories.", + }, + ]; + + return ( + + {/* Hero */} +
+
+
+
+ {/* Image/Avatar */} +
+
+
+ Klesti Selimaj +
+
+ {/* Floating badges */} +
+ + Available +
+
+ + {/* Content */} +
+ + About Me + +

+ Hey, I'm{" "} + Klesti Selimaj +

+

+ A 16-year-old software engineer from Albania with 6+ years of + experience. I'm passionate about building things that matter, + from low-level systems to beautiful user interfaces. +

+

+ My journey started at age 10 when I had my first laptop (a Asus + with pre installed endless linux), and since then I've been + hooked on computers, but i didn't exactly know what programming + was but i was doing it unconsciously, making winforms apps in c# + with visual studio. +

+ + {/* Quick Info */} +
+
+ + Albania +
+
+ + 6+ Years Experience +
+
+ + @orus-dev +
+
+ + {/* Social Links */} + +
+
+
+
+ + {/* Tech Stack */} +
+
+
+ + Tech Stack + +

+ Tools I Work With +

+

+ A carefully curated set of technologies that I use to build + exceptional products. +

+
+ +
+ {techStack.map((tech, index) => ( +
+
+ {tech.icon} +
+

+ {tech.name} +

+
+ ))} +
+
+
+ + {/* Achievements */} +
+
+
+ + Recognition + +

+ My Achievements +

+

+ Achievements earned through consistent contributions and learning. +

+
+ +
+ {achievements.map((achievement, index) => ( +
+
{achievement.icon}
+

+ {achievement.title} +

+

+ {achievement.description} +

+
+ ))} +
+
+
+ + {/* Timeline */} +
+
+
+ + Journey + +

+ My Story +

+

+ From curious kid to entrepreneurial developer, here's how I got + here. +

+
+ +
+ {timeline.map((item, index) => ( +
+ {/* Line */} + {index !== timeline.length - 1 && ( +
+ )} + + {/* Dot */} +
+
+ + {item.year.slice(2)} + +
+
+ + {/* Content */} +
+
+ + {item.year} + +
+

+ {item.title} +

+

+ {item.description} +

+
+
+ ))} +
+
+
+ + {/* Philosophy */} +
+
+
+
+ + Philosophy + + +
+ "One day or Day one?" +
+

- Klesti Selimaj

+
+
+
+
+ ); +} diff --git a/src/app/globals.css b/src/app/globals.css index 8e68a8c..87ef9b3 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -1,41 +1,237 @@ +@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap'); + @tailwind base; @tailwind components; @tailwind utilities; -@font-face { - font-family: 'Kodchasan Medium'; - src: url('/fonts/Kodchasan-Medium.ttf'); -} +/* Premium Monochromatic Design System with Gold Accents */ -@font-face { - font-family: 'Kodchasan'; - src: url('/fonts/Kodchasan-Regular.ttf'); -} - -@font-face { - font-family: 'Kodchasan Semi Bold'; - src: url('/fonts/Kodchasan-SemiBold.ttf'); -} - -:root { - --background: #ffffff; - --foreground: #171717; -} - -@media (prefers-color-scheme: dark) { +@layer base { :root { - --background: #0a0a0a; - --foreground: #ededed; + --background: 0 0% 100%; + --foreground: 0 0% 5%; + + --card: 0 0% 98%; + --card-foreground: 0 0% 5%; + + --popover: 0 0% 100%; + --popover-foreground: 0 0% 5%; + + --primary: 0 0% 9%; + --primary-foreground: 0 0% 98%; + + --secondary: 0 0% 96%; + --secondary-foreground: 0 0% 9%; + + --muted: 0 0% 94%; + --muted-foreground: 0 0% 45%; + + --accent: 43 41% 59%; + --accent-foreground: 0 0% 5%; + + --destructive: 0 84% 60%; + --destructive-foreground: 0 0% 98%; + + --border: 0 0% 90%; + --input: 0 0% 90%; + --ring: 43 41% 59%; + + --radius: 0.75rem; + + /* Premium Gold Tokens */ + --gold: 43 41% 59%; + --gold-light: 43 45% 70%; + --gold-dark: 43 38% 45%; + + /* Gradient tokens */ + --gradient-gold: linear-gradient(135deg, hsl(43 41% 59%), hsl(43 45% 70%)); + --gradient-dark: linear-gradient(180deg, hsl(0 0% 100%), hsl(0 0% 96%)); + + /* Shadows */ + --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.03); + --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.05), 0 2px 4px -2px rgb(0 0 0 / 0.05); + --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.05), 0 4px 6px -4px rgb(0 0 0 / 0.05); + --shadow-gold: 0 0 30px -5px hsl(43 41% 59% / 0.15); + + --sidebar-background: 0 0% 98%; + --sidebar-foreground: 0 0% 25%; + --sidebar-primary: 0 0% 10%; + --sidebar-primary-foreground: 0 0% 98%; + --sidebar-accent: 0 0% 95%; + --sidebar-accent-foreground: 0 0% 10%; + --sidebar-border: 0 0% 91%; + --sidebar-ring: 43 41% 59%; + } + + .dark { + --background: 0 0% 4%; + --foreground: 0 0% 95%; + + --card: 0 0% 7%; + --card-foreground: 0 0% 95%; + + --popover: 0 0% 6%; + --popover-foreground: 0 0% 95%; + + --primary: 0 0% 95%; + --primary-foreground: 0 0% 5%; + + --secondary: 0 0% 12%; + --secondary-foreground: 0 0% 95%; + + --muted: 0 0% 15%; + --muted-foreground: 0 0% 55%; + + --accent: 43 41% 59%; + --accent-foreground: 0 0% 5%; + + --destructive: 0 62% 30%; + --destructive-foreground: 0 0% 95%; + + --border: 0 0% 15%; + --input: 0 0% 15%; + --ring: 43 41% 59%; + + /* Premium Gold Tokens (adjusted for dark) */ + --gold: 43 41% 59%; + --gold-light: 43 50% 68%; + --gold-dark: 43 35% 48%; + + /* Gradient tokens */ + --gradient-gold: linear-gradient(135deg, hsl(43 41% 59%), hsl(43 50% 68%)); + --gradient-dark: linear-gradient(180deg, hsl(0 0% 4%), hsl(0 0% 8%)); + + /* Shadows */ + --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.3); + --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.4), 0 2px 4px -2px rgb(0 0 0 / 0.3); + --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.5), 0 4px 6px -4px rgb(0 0 0 / 0.4); + --shadow-gold: 0 0 40px -5px hsl(43 41% 59% / 0.25); + + --sidebar-background: 0 0% 6%; + --sidebar-foreground: 0 0% 90%; + --sidebar-primary: 43 41% 59%; + --sidebar-primary-foreground: 0 0% 100%; + --sidebar-accent: 0 0% 12%; + --sidebar-accent-foreground: 0 0% 90%; + --sidebar-border: 0 0% 12%; + --sidebar-ring: 43 41% 59%; } } -body { - color: var(--foreground); - background: var(--background); - font-family: 'Kodchasan Semi Bold', sans-serif; +@layer base { + * { + @apply border-border; + } + + html { + scroll-behavior: smooth; + } + + body { + @apply bg-background text-foreground antialiased; + font-family: 'Inter', system-ui, sans-serif; + } + + ::selection { + @apply bg-accent/30 text-foreground; + } } -h1 { - font-size: 30px; - font-weight: bold; +@layer components { + .text-gradient-gold { + @apply bg-clip-text text-transparent; + background-image: linear-gradient(135deg, hsl(var(--gold)), hsl(var(--gold-light))); + } + + .border-gradient-gold { + border-image: linear-gradient(135deg, hsl(var(--gold)), hsl(var(--gold-light))) 1; + } + + .glow-gold { + box-shadow: 0 0 40px -5px hsl(var(--gold) / 0.3); + } + + .glass-card { + @apply bg-card/80 backdrop-blur-xl border border-border/50; + } + + .hover-lift { + @apply transition-all duration-300 ease-out; + } + + .hover-lift:hover { + @apply -translate-y-1; + box-shadow: var(--shadow-lg); + } + + .font-mono { + font-family: 'JetBrains Mono', monospace; + } +} + +@layer utilities { + .animate-fade-in { + animation: fadeIn 0.6s ease-out forwards; + } + + .animate-fade-in-up { + animation: fadeInUp 0.6s ease-out forwards; + } + + .animate-fade-in-delay-1 { + animation: fadeIn 0.6s ease-out 0.1s forwards; + opacity: 0; + } + + .animate-fade-in-delay-2 { + animation: fadeIn 0.6s ease-out 0.2s forwards; + opacity: 0; + } + + .animate-fade-in-delay-3 { + animation: fadeIn 0.6s ease-out 0.3s forwards; + opacity: 0; + } + + @keyframes fadeIn { + from { + opacity: 0; + transform: translateY(10px); + } + to { + opacity: 1; + transform: translateY(0); + } + } + + @keyframes fadeInUp { + from { + opacity: 0; + transform: translateY(20px); + } + to { + opacity: 1; + transform: translateY(0); + } + } + + @keyframes shimmer { + 0% { + background-position: -200% 0; + } + 100% { + background-position: 200% 0; + } + } + + .animate-shimmer { + background: linear-gradient( + 90deg, + hsl(var(--gold) / 0) 0%, + hsl(var(--gold) / 0.3) 50%, + hsl(var(--gold) / 0) 100% + ); + background-size: 200% 100%; + animation: shimmer 3s infinite; + } } \ No newline at end of file diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 28c1d98..5f84625 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,10 +1,8 @@ import type { Metadata } from "next"; import "./globals.css"; -import Navbar from "@/components/Navbar"; -import Background from "@/components/Background"; export const metadata: Metadata = { - title: "Klesti's Portfolio", + title: "Selimaj.dev", description: "", }; @@ -15,11 +13,7 @@ export default function RootLayout({ }>) { return ( - - -
{children}
-
- + {children} ); } diff --git a/src/app/page.tsx b/src/app/page.tsx index b702cfe..7bff87c 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,231 +1,16 @@ -"use client"; - -import { motion, spring } from "framer-motion"; -import PinnedRepos from "@/components/PinnedRepos"; -import Skill from "@/components/Skill"; -import { - faGithub, - faGolang, - faInstagram, - faJs, - faLinkedin, - faPython, - faReact, - faRust, -} from "@fortawesome/free-brands-svg-icons"; -import { faJava } from "@fortawesome/free-brands-svg-icons/faJava"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { CoffeeIcon, HeartIcon } from "lucide-react"; -import { useEffect, useState } from "react"; -import GitHubCalendar from "react-github-calendar"; -import { fadeInUp, popIn, staggerContainer } from "@/components/effects"; - -export default function App() { - const [contribs, setContribs] = useState(); - - useEffect(() => { - const fetchContributions = async () => { - const res = await fetch("/api/contribs"); - const data = await res.json(); - setContribs(data.total || undefined); - }; - fetchContributions(); - }, []); +import { Layout } from "@/components/layout/Layout"; +import { HeroSection } from "@/components/home/HeroSection"; +import { ProjectsSection } from "@/components/home/ProjectsSection"; +import { SkillsSection } from "@/components/home/SkillsSection"; +import { CTASection } from "@/components/home/CTASection"; +export default function Home() { return ( - -
- {/* HEADER */} - - Hey, I'm Klesti! 👋🏻 - - - - A 16 year old Software Engineer from Tirane, Albania, with 6 years of - experience, specializing in full-stack web development, desktop - applications, TUI apps, and hacking. I also have a deep interest in - low-level programming. - - - {/* KO-FI BUTTON */} - - - - Support me on Ko-fi - - - - - {/* SOCIALS + SKILLS */} - - {/* socials */} - - {[faGithub, faLinkedin, faInstagram].map((icon, i) => ( - - - - ))} - - - {/* skills */} - -
- - - - - - - - - - - - - - - - - - - - -
-
-
- - {/* PINNED PROJECTS */} - - Pinned Projects - - - - - - - {/* CONTRIBUTIONS */} - - {contribs || "Loading.."} contributions in the last year - - - - - - - - - {/* FOOTER */} -
- - If you see this i{" "} - - - {" "} - you - - - - © 2025 Klesti. All rights reserved. - -
-
-
+ + + + + + ); } diff --git a/src/app/pricing/page.tsx b/src/app/pricing/page.tsx new file mode 100644 index 0000000..2b90376 --- /dev/null +++ b/src/app/pricing/page.tsx @@ -0,0 +1,267 @@ +"use client"; + +import { Layout } from "@/components/layout/Layout"; +import { Check, ArrowRight, Zap, Crown, Rocket } from "lucide-react"; +import { useState } from "react"; + +const plans = [ + { + name: "Starter", + description: "Perfect for small projects and quick fixes", + price: "$500", + period: "project", + icon: Zap, + features: [ + "Single page application", + "Responsive design", + "Basic animations", + "2 revision rounds", + "1 week delivery", + "Source code included", + ], + cta: "Get Started", + popular: false, + }, + { + name: "Professional", + description: "For complex applications and systems", + price: "$2,000", + period: "project", + icon: Crown, + features: [ + "Multi-page application", + "Custom backend integration", + "Advanced animations & UI", + "5 revision rounds", + "2-3 weeks delivery", + "Full source code & docs", + "1 month support", + "Performance optimization", + ], + cta: "Start Project", + popular: true, + }, + { + name: "Enterprise", + description: "Full-scale systems and ongoing partnership", + price: "Custom", + period: "quote", + icon: Rocket, + features: [ + "Complex systems architecture", + "Low-level development", + "TUI/CLI applications", + "Unlimited revisions", + "Priority support", + "Full documentation", + "Training & onboarding", + "Long-term partnership", + ], + cta: "Contact Me", + popular: false, + }, +]; + +const services = [ + { + title: "Web Development", + description: + "Modern, performant web applications built with React, TypeScript, and cutting-edge technologies.", + }, + { + title: "Systems Programming", + description: + "Low-level development in Rust and Go for performance-critical applications.", + }, + { + title: "TUI/CLI Tools", + description: + "Beautiful terminal user interfaces and command-line tools that developers love.", + }, + { + title: "API Development", + description: "Robust, scalable backend systems and API architectures.", + }, + { + title: "DevOps & Deployment", + description: + "Docker, CI/CD pipelines, and self-hosted deployment solutions.", + }, + { + title: "Consulting", + description: + "Technical guidance and architecture planning for your projects.", + }, +]; + +export default function Pricing() { + const [hoveredPlan, setHoveredPlan] = useState(null); + + return ( + + {/* Hero */} +
+
+
+
+ + Pricing + +

+ Transparent Pricing for{" "} + Premium Quality +

+

+ Choose a plan that fits your needs. Every project receives the + same attention to detail and commitment to excellence. +

+
+
+
+ + {/* Pricing Cards */} +
+
+
+ {plans.map((plan) => ( +
setHoveredPlan(plan.name)} + onMouseLeave={() => setHoveredPlan(null)} + > + {plan.popular && ( +
+ + Most Popular + +
+ )} + +
+
+ +
+

+ {plan.name} +

+
+ +

+ {plan.description} +

+ +
+ + {plan.price} + + {plan.period !== "quote" && ( + + /{plan.period} + + )} +
+ +
    + {plan.features.map((feature) => ( +
  • + + {feature} +
  • + ))} +
+ + + {plan.cta} + + +
+ ))} +
+
+
+ + {/* Services */} +
+
+
+ + Services + +

+ What I Offer +

+

+ From concept to deployment, I provide end-to-end development + services tailored to your needs. +

+
+ +
+ {services.map((service, index) => ( +
+

+ {service.title} +

+

+ {service.description} +

+
+ ))} +
+
+
+ + {/* Contact CTA */} +
+
+
+
+

+ Have a Custom Project in Mind? +

+

+ Let's discuss your requirements and create a tailored solution + that exceeds expectations. +

+ + Schedule a Call + + +
+
+
+
+ ); +} diff --git a/src/blogApi.ts b/src/blogApi.ts deleted file mode 100644 index 3baece6..0000000 --- a/src/blogApi.ts +++ /dev/null @@ -1,129 +0,0 @@ -import { Client } from "@notionhq/client"; -import { SearchResponse } from "@notionhq/client/build/src/api-endpoints"; -import { NotionToMarkdown } from "notion-to-md"; - -interface Blog { - id: string; - title: string; - tags: { name: string; color: string }[]; - date: string; - description: string; -} - -type QueryResponse = { cursor: string | null; hasMore: boolean; items: Blog[] }; -type Error = { msg: string }; - -export async function getBlogs( - notion: Client, - databaseId: string, - cursor: string | undefined, - pageSize: number -): Promise<[number, QueryResponse | Error]> { - try { - const response = await notion.databases.query({ - database_id: databaseId, - filter: { - property: "Status", - status: { - equals: "Posted", - }, - }, - start_cursor: cursor, - page_size: pageSize, - }); - return [ - 200, - { - cursor: response.next_cursor, - hasMore: response.has_more, - items: response.results.map(convertBlog), - }, - ]; - } catch (err: any) { - return [400, { msg: String(err) }]; - } -} - -function convertBlog(page: any): Blog { - return { - id: page.id, - title: page.properties.Title.title[0].plain_text, - description: [ - page.properties.Description.rich_text.map( - (d: { plain_text: string }) => d.plain_text - ), - ].join(" "), - date: page.properties.Date.created_time, - tags: page.properties.Tags.multi_select.map((tag: any) => ({ - name: tag.name, - color: tag.color, - })), - }; -} - -interface FullBlog extends Blog { - markdown: string; -} - -export async function getBlog( - notion: Client, - n2m: NotionToMarkdown, - pageId: string -): Promise<[number, FullBlog | Error]> { - try { - const page: any = await notion.pages.retrieve({ page_id: pageId }); - if (page.properties.Status.status.name !== "Posted") - return [400, { msg: "Blog not found" }]; - try { - const blog = convertBlog(page); - const mdBlocks = await n2m.pageToMarkdown(page.id); - return [ - 200, - { - id: blog.id, - title: blog.title, - description: blog.description, - tags: blog.tags, - date: blog.date, - markdown: n2m.toMarkdownString(mdBlocks).parent || "", - }, - ]; - } catch (err: any) { - return [500, { msg: String(err) }]; - } - } catch { - return [400, { msg: "Blog not found" }]; - } -} - -export async function searchBlog( - notion: Client, - query: string -): Promise<[200 | 400, QueryResponse | Error]> { - try { - var response = await notion.search({ - query, - filter: { - value: "page", - property: "object", - }, - sort: { - direction: "ascending", - timestamp: "last_edited_time", - }, - }); - response.results = response.results.filter( - (item: any) => item.properties.Status.status.name === "Posted" - ); - return [ - 200, - { - cursor: response.next_cursor, - hasMore: response.has_more, - items: response.results.map(convertBlog), - }, - ]; - } catch (err: any) { - return [400, { msg: String(err) }]; - } -} diff --git a/src/components/Background.tsx b/src/components/Background.tsx deleted file mode 100644 index 4c3228a..0000000 --- a/src/components/Background.tsx +++ /dev/null @@ -1,22 +0,0 @@ -"use client"; - -import React from "react"; - -export default function Background({ - children, -}: Readonly<{ children: React.ReactNode }>) { - return ( -
-
- -
{children}
-
- ); -} diff --git a/src/components/MarkdownRenderer.tsx b/src/components/MarkdownRenderer.tsx deleted file mode 100644 index fd6db73..0000000 --- a/src/components/MarkdownRenderer.tsx +++ /dev/null @@ -1,73 +0,0 @@ -import React from "react"; -import Markdown from "react-markdown"; -import remarkGfm from "remark-gfm"; -import remarkBreaks from "remark-breaks"; -import remarkMath from "remark-math"; -import rehypeRaw from "rehype-raw"; -import rehypeKatex from "rehype-katex"; -import { Prism as SyntaxHighlighter } from "react-syntax-highlighter"; -import { gruvboxDark } from "react-syntax-highlighter/dist/esm/styles/prism"; -import "katex/dist/katex.min.css"; - -type MarkdownRendererProps = { - children: string; -}; - -export default function MarkdownRenderer({ - children: markdown, -}: MarkdownRendererProps) { - return ( - - {String(children).replace(/\n$/, "")} - - ) : ( - - {children} - - ); - }, - ul({ children, ...props }) { - return ( -
    - {children} -
- ); - }, - ol({ children, ...props }) { - return ( -
    - {children} -
- ); - }, - li({ children, ...props }) { - return ( -
  • - {children} -
  • - ); - }, - }} - > - {markdown} -
    - ); -} diff --git a/src/components/Navbar.tsx b/src/components/Navbar.tsx deleted file mode 100644 index 10aa453..0000000 --- a/src/components/Navbar.tsx +++ /dev/null @@ -1,35 +0,0 @@ -"use client"; - -import { usePathname } from "next/navigation"; -import Link from "next/link"; - -export default function Navbar() { - const pathname = usePathname(); - - return ( - - ); -} diff --git a/src/components/PinnedRepos.tsx b/src/components/PinnedRepos.tsx deleted file mode 100644 index ebebf80..0000000 --- a/src/components/PinnedRepos.tsx +++ /dev/null @@ -1,178 +0,0 @@ -"use client"; - -import { useEffect, useState } from "react"; -import { motion } from "framer-motion"; -import { fadeInUp, fadeInUp2, staggerContainer } from "./effects"; - -type PinnedRepo = { - author: string; - name: string; - description: string; - language: string; - stars: number; - forks: number; - href?: string; -}; - -export function Repo({ - name, - description: desc, - language: lang, - stars, - forks, - href, -}: PinnedRepo) { - return ( - -
    -
    -
    -

    - - {name} - -

    -

    - {desc} -

    -
    -
    -
    -
    -
    - - - - {stars} -
    -
    - - - - - - - - {forks} -
    -
    - {lang && ( -
    - - - - - - {lang} -
    - )} -
    -
    -
    -
    -
    - ); -} - -export default function PinnedRepos() { - try { - const [pinned, setPinned] = useState([]); - - useEffect(() => { - fetch("https://pinned.berrysauce.dev/get/selimaj-dev") - .then((r) => { - r.json() - .then((p) => { - setPinned(p); - }) - .catch((e) => { - console.error(e); - }); - }) - .catch((e) => { - console.error(e); - }); - }, []); - - return ( - - {pinned && - pinned.map((repo, i) => ( - - ))} - - ); - } catch (e: any) { - return

    {e.toString()}

    ; - } -} diff --git a/src/components/Skill.tsx b/src/components/Skill.tsx deleted file mode 100644 index b338fe4..0000000 --- a/src/components/Skill.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import { IconProp } from "@fortawesome/fontawesome-svg-core"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; - -export default function Skill({ - skill, - icon, - classInsert, -}: { - skill: string; - icon: IconProp; - classInsert?: string; -}) { - return ( -
    - - Skilled in {skill} - - - -
    - ); -} diff --git a/src/components/effects.ts b/src/components/effects.ts deleted file mode 100644 index 7335a1c..0000000 --- a/src/components/effects.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { easeOut, spring } from "framer-motion"; - -export const fadeInUp = { - hidden: { opacity: 0, y: 20 }, - show: { opacity: 1, y: 0, transition: { duration: 0.5 } }, -}; - -export const fadeInUp2 = { - hidden: { opacity: 0, y: 20 }, - visible: { - opacity: 1, - y: 0, - transition: { duration: 0.4, ease: easeOut }, - }, -}; - -export const staggerContainer = { - show: { - transition: { - staggerChildren: 0.12, - }, - }, -}; - -export const popIn = { - hidden: { opacity: 0, scale: 0.8 }, - show: { - opacity: 1, - scale: 1, - transition: { type: spring, stiffness: 120 }, - }, -}; diff --git a/src/components/home/CTASection.tsx b/src/components/home/CTASection.tsx new file mode 100644 index 0000000..ce97082 --- /dev/null +++ b/src/components/home/CTASection.tsx @@ -0,0 +1,39 @@ +import { ArrowRight } from "lucide-react"; +import Link from "next/link"; + +export function CTASection() { + return ( +
    + {/* Background Effects */} +
    + +
    +
    +

    + Ready to build something{" "} + extraordinary? +

    +

    + Whether you need a complex system, a modern web application, or specialized tooling, + I'm here to bring your vision to life. +

    +
    + + View Pricing Plans + + + + Learn more about me + +
    +
    +
    +
    + ); +} \ No newline at end of file diff --git a/src/components/home/HeroSection.tsx b/src/components/home/HeroSection.tsx new file mode 100644 index 0000000..e78c3ca --- /dev/null +++ b/src/components/home/HeroSection.tsx @@ -0,0 +1,97 @@ +import { ArrowRight, Github, Linkedin, Youtube } from "lucide-react"; +import Link from "next/link"; + +export function HeroSection() { + return ( +
    + {/* Background Effects */} +
    +
    +
    + +
    +
    + {/* Status Badge */} +
    + + + Available for new projects + +
    + + {/* Main Heading */} +

    + Building{" "} + exceptional +
    + digital experiences +

    + + {/* Subheading */} +

    + I'm{" "} + Klesti Selimaj, + a 16-year-old software engineer with 6+ years of experience. + Passionate about low-level systems, modern web apps, and crafting + tools that make a difference. +

    + + {/* CTA Buttons */} +
    + + Work with me + + + + + View GitHub + +
    + + {/* Social Links */} + +
    +
    + + {/* Scroll Indicator */} +
    +
    +
    +
    +
    +
    + ); +} diff --git a/src/components/home/ProjectsSection.tsx b/src/components/home/ProjectsSection.tsx new file mode 100644 index 0000000..3d4780f --- /dev/null +++ b/src/components/home/ProjectsSection.tsx @@ -0,0 +1,159 @@ +import { ExternalLink, Github, Star } from "lucide-react"; + +const projects = [ + { + name: "DockShip", + description: "A powerful self-hosted Deployment Platform for modern teams.", + tech: ["TypeScript", "Docker", "React"], + stars: 1, + github: "https://github.com/orus-dev/dockship", + featured: true, + }, + { + name: "OSUI", + description: + "A TUI library written in Rust for building beautiful terminal interfaces.", + tech: ["Rust", "TUI", "Systems"], + stars: 8, + github: "https://github.com/osui-rs/osui", + featured: true, + }, + { + name: "Linear Linux", + description: + "Linux support for linear.app - bringing seamless project management to Linux users.", + tech: ["JavaScript", "Electron", "Linux"], + stars: 23, + github: "https://github.com/selimaj-dev/linear-linux", + featured: true, + }, + { + name: "Saturn Client", + description: + "A Minecraft client full of customizability and free cosmetics.", + tech: ["Java", "Minecraft", "Gaming"], + stars: 3, + github: "https://github.com/saturnclientmc/saturnclient", + featured: false, + }, + { + name: "Axiom Chat", + description: "A modern, feature-rich chat application built for teams.", + tech: ["TypeScript", "Real-time", "WebSockets"], + stars: 1, + github: "https://github.com/AxiomChat/axiom", + featured: false, + }, + { + name: "Drift", + description: "An organized productivity app to get rid of distractions.", + tech: ["TypeScript", "Productivity", "Focus"], + stars: 1, + github: "https://github.com/orus-dev/drift", + featured: false, + }, +]; + +export function ProjectsSection() { + return ( +
    +
    + {/* Section Header */} +
    + + Portfolio + +

    + Featured Projects +

    +

    + A selection of my open-source work and personal projects that + showcase my skills in systems programming, web development, and + tooling. +

    +
    + + {/* Projects Grid */} +
    + {projects.map((project, index) => ( +
    + {/* Header */} +
    +
    + {project.featured && ( + + Featured + + )} +
    +
    + + {project.stars} +
    +
    + + {/* Content */} +

    + {project.name} +

    +

    + {project.description} +

    + + {/* Tech Stack */} +
    + {project.tech.map((tech) => ( + + {tech} + + ))} +
    + + {/* Actions */} + +
    + ))} +
    + + {/* View All CTA */} + +
    +
    + ); +} diff --git a/src/components/home/SkillsSection.tsx b/src/components/home/SkillsSection.tsx new file mode 100644 index 0000000..6778273 --- /dev/null +++ b/src/components/home/SkillsSection.tsx @@ -0,0 +1,112 @@ +const skills = [ + { + category: "Languages", + items: [ + { name: "Rust", level: 90 }, + { name: "TypeScript", level: 95 }, + { name: "JavaScript", level: 95 }, + { name: "Python", level: 80 }, + { name: "Go", level: 75 }, + { name: "Java", level: 85 }, + ], + }, + { + category: "Frontend", + items: [ + { name: "React", level: 95 }, + { name: "Next.js", level: 85 }, + { name: "Tailwind CSS", level: 95 }, + { name: "Framer Motion", level: 80 }, + ], + }, + { + category: "Systems & Tools", + items: [ + { name: "Linux", level: 90 }, + { name: "Docker", level: 85 }, + { name: "Git", level: 95 }, + { name: "TUI Development", level: 90 }, + ], + }, +]; + +const stats = [ + { label: "Years Experience", value: "6+" }, + { label: "GitHub Followers", value: "32" }, + { label: "Open Source Projects", value: "10+" }, + { label: "Technologies Mastered", value: "15+" }, +]; + +export function SkillsSection() { + return ( +
    +
    + {/* Stats */} +
    + {stats.map((stat, index) => ( +
    +
    + {stat.value} +
    +
    {stat.label}
    +
    + ))} +
    + + {/* Section Header */} +
    + + Expertise + +

    + Technical Skills +

    +

    + From low-level systems programming to modern web development, I + bring a diverse skill set to every project. +

    +
    + + {/* Skills Grid */} +
    + {skills.map((category, categoryIndex) => ( +
    +

    + + {category.category} +

    +
    + {category.items.map((skill) => ( +
    +
    + + {skill.name} + + + {skill.level}% + +
    +
    +
    +
    +
    + ))} +
    +
    + ))} +
    +
    +
    + ); +} diff --git a/src/components/layout/Footer.tsx b/src/components/layout/Footer.tsx new file mode 100644 index 0000000..482d569 --- /dev/null +++ b/src/components/layout/Footer.tsx @@ -0,0 +1,118 @@ +import Link from "next/link"; + +export function Footer() { + const currentYear = new Date().getFullYear(); + + return ( +
    +
    +
    + {/* Brand */} +
    + + Logo + selimaj.dev + +

    + Building digital experiences with precision and passion. + Specializing in low-level systems, modern web applications, and + everything in between. +

    +
    + + {/* Quick Links */} +
    +

    Quick Links

    +
      +
    • + + Home + +
    • +
    • + + About + +
    • +
    • + + Hire Me + +
    • +
    +
    + + {/* Connect */} +
    +

    Connect

    + +
    +
    + +
    +

    + © {currentYear} Klesti Selimaj. All rights reserved. +

    +
    + + Available for work +
    +
    +
    +
    + ); +} diff --git a/src/components/layout/Layout.tsx b/src/components/layout/Layout.tsx new file mode 100644 index 0000000..3f5bbdf --- /dev/null +++ b/src/components/layout/Layout.tsx @@ -0,0 +1,19 @@ +"use client"; + +import { ReactNode } from "react"; +import { Footer } from "./Footer"; +import { Navbar } from "./Navbar"; + +interface LayoutProps { + children: ReactNode; +} + +export function Layout({ children }: LayoutProps) { + return ( +
    + +
    {children}
    +
    +
    + ); +} diff --git a/src/components/layout/Navbar.tsx b/src/components/layout/Navbar.tsx new file mode 100644 index 0000000..4ed0945 --- /dev/null +++ b/src/components/layout/Navbar.tsx @@ -0,0 +1,152 @@ +"use client"; + +import { cn } from "@/lib/utils"; +import { CoffeeIcon, Github, Menu, X } from "lucide-react"; +import Link from "next/link"; +import { usePathname } from "next/navigation"; +import { useState } from "react"; +import { motion } from "framer-motion"; + +const navLinks = [ + { href: "/", label: "Home" }, + { href: "/about", label: "About" }, + { href: "/pricing", label: "Hire Me" }, +]; + +export function Navbar() { + const [mobileMenuOpen, setMobileMenuOpen] = useState(false); + const pathname = usePathname(); + + return ( +
    + + + {/* Mobile Menu */} + {mobileMenuOpen && ( +
    +
      + {navLinks.map((link) => ( +
    • + setMobileMenuOpen(false)} + className={cn( + "block text-sm font-medium transition-colors", + location.pathname === link.href + ? "text-accent" + : "text-muted-foreground", + )} + > + {link.label} + +
    • + ))} +
    • + + + +
    • + + + + + + + + +
    +
    + )} +
    + ); +} diff --git a/src/lib/utils.ts b/src/lib/utils.ts new file mode 100644 index 0000000..a5ef193 --- /dev/null +++ b/src/lib/utils.ts @@ -0,0 +1,6 @@ +import { clsx, type ClassValue } from "clsx"; +import { twMerge } from "tailwind-merge"; + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)); +} diff --git a/src/notion.ts b/src/notion.ts deleted file mode 100644 index cfcf2ab..0000000 --- a/src/notion.ts +++ /dev/null @@ -1,15 +0,0 @@ -import dotenv from 'dotenv'; -import { Client } from '@notionhq/client'; -import { NotionToMarkdown } from 'notion-to-md'; -dotenv.config(); - -export const notion = new Client( { auth: process.env.NOTION_API_KEY } ) -export const n2m = new NotionToMarkdown({ - notionClient: notion, -}); - -if (process.env.NOTION_DATABASE_ID === undefined) { - console.error('[server] Error: environment variable \'NOTION_DATABASE_ID\' not found') - process.exit(); -} -export const databaseId: string = process.env.NOTION_DATABASE_ID; \ No newline at end of file diff --git a/tailwind.config.ts b/tailwind.config.ts index 72ca559..3a081cd 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -1,31 +1,112 @@ import type { Config } from "tailwindcss"; export default { + darkMode: ["class"], content: [ - "./src/pages/**/*.{js,ts,jsx,tsx,mdx}", - "./src/components/**/*.{js,ts,jsx,tsx,mdx}", - "./src/app/**/*.{js,ts,jsx,tsx,mdx}", + "./pages/**/*.{ts,tsx}", + "./components/**/*.{ts,tsx}", + "./app/**/*.{ts,tsx}", + "./src/**/*.{ts,tsx}", ], + prefix: "", theme: { - extend: { - colors: { - background: "var(--background)", - foreground: "var(--foreground)", - red: '#f5304c', - 'red-400': '#fa5770', - 'red-600': '#eb2642', - 'transparent-ish': '#0000000A', + container: { + center: true, + padding: "2rem", + screens: { + "2xl": "1400px", }, - animation: { - fadeIn: "fadeIn 1s ease-in-out", + }, + extend: { + fontFamily: { + sans: ["Inter", "system-ui", "sans-serif"], + mono: ["JetBrains Mono", "monospace"], + }, + colors: { + border: "hsl(var(--border))", + input: "hsl(var(--input))", + ring: "hsl(var(--ring))", + background: "hsl(var(--background))", + foreground: "hsl(var(--foreground))", + gold: { + DEFAULT: "hsl(var(--gold))", + light: "hsl(var(--gold-light))", + dark: "hsl(var(--gold-dark))", + }, + primary: { + DEFAULT: "hsl(var(--primary))", + foreground: "hsl(var(--primary-foreground))", + }, + secondary: { + DEFAULT: "hsl(var(--secondary))", + foreground: "hsl(var(--secondary-foreground))", + }, + destructive: { + DEFAULT: "hsl(var(--destructive))", + foreground: "hsl(var(--destructive-foreground))", + }, + muted: { + DEFAULT: "hsl(var(--muted))", + foreground: "hsl(var(--muted-foreground))", + }, + accent: { + DEFAULT: "hsl(var(--accent))", + foreground: "hsl(var(--accent-foreground))", + }, + popover: { + DEFAULT: "hsl(var(--popover))", + foreground: "hsl(var(--popover-foreground))", + }, + card: { + DEFAULT: "hsl(var(--card))", + foreground: "hsl(var(--card-foreground))", + }, + sidebar: { + DEFAULT: "hsl(var(--sidebar-background))", + foreground: "hsl(var(--sidebar-foreground))", + primary: "hsl(var(--sidebar-primary))", + "primary-foreground": "hsl(var(--sidebar-primary-foreground))", + accent: "hsl(var(--sidebar-accent))", + "accent-foreground": "hsl(var(--sidebar-accent-foreground))", + border: "hsl(var(--sidebar-border))", + ring: "hsl(var(--sidebar-ring))", + }, + }, + borderRadius: { + lg: "var(--radius)", + md: "calc(var(--radius) - 2px)", + sm: "calc(var(--radius) - 4px)", }, keyframes: { - fadeIn: { - "0%": { opacity: "0", transform: "translateY(10px)" }, - "100%": { opacity: "1", transform: "translateY(0px)" }, + "accordion-down": { + from: { height: "0" }, + to: { height: "var(--radix-accordion-content-height)" }, }, + "accordion-up": { + from: { height: "var(--radix-accordion-content-height)" }, + to: { height: "0" }, + }, + "fade-in": { + "0%": { opacity: "0", transform: "translateY(10px)" }, + "100%": { opacity: "1", transform: "translateY(0)" }, + }, + "fade-in-up": { + "0%": { opacity: "0", transform: "translateY(20px)" }, + "100%": { opacity: "1", transform: "translateY(0)" }, + }, + pulse: { + "0%, 100%": { opacity: "1" }, + "50%": { opacity: "0.5" }, + }, + }, + animation: { + "accordion-down": "accordion-down 0.2s ease-out", + "accordion-up": "accordion-up 0.2s ease-out", + "fade-in": "fade-in 0.6s ease-out forwards", + "fade-in-up": "fade-in-up 0.6s ease-out forwards", + pulse: "pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite", }, }, }, - plugins: [], + plugins: [require("tailwindcss-animate")], } satisfies Config;