Compare commits
4 Commits
0.11.2
...
renovate/t
Author | SHA1 | Date | |
---|---|---|---|
3e71aaafd8
|
|||
f16af9a98d
|
|||
ec45ad29ed | |||
17afce6710 |
@@ -1,7 +1,7 @@
|
||||
ARG REGISTRY=docker.io
|
||||
FROM ${REGISTRY}/node:22.17.1-alpine3.22 AS base
|
||||
|
||||
LABEL version="0.11.2"
|
||||
LABEL version="0.11.3"
|
||||
LABEL description="Astro based personal website"
|
||||
|
||||
ENV PNPM_HOME="/pnpm"
|
||||
|
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "site-profile",
|
||||
"type": "module",
|
||||
"version": "0.11.2",
|
||||
"version": "0.11.3",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "astro dev",
|
||||
@@ -31,13 +31,13 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/typography": "^0.5.16",
|
||||
"@typescript-eslint/parser": "8.37.0",
|
||||
"@typescript-eslint/parser": "8.38.0",
|
||||
"eslint": "9.31.0",
|
||||
"eslint-config-prettier": "10.1.8",
|
||||
"eslint-plugin-astro": "1.3.1",
|
||||
"prettier": "^3.5.3",
|
||||
"prettier-plugin-astro": "^0.14.1",
|
||||
"prettier-plugin-tailwindcss": "^0.6.12",
|
||||
"typescript-eslint": "8.37.0"
|
||||
"typescript-eslint": "8.38.0"
|
||||
}
|
||||
}
|
||||
|
190
pnpm-lock.yaml
generated
190
pnpm-lock.yaml
generated
@@ -10,13 +10,13 @@ importers:
|
||||
dependencies:
|
||||
'@astrojs/mdx':
|
||||
specifier: ^4.3.0
|
||||
version: 4.3.1(astro@5.12.0(@types/node@24.0.15)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.45.1)(typescript@5.8.3)(yaml@2.8.0))
|
||||
version: 4.3.1(astro@5.12.1(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.45.1)(typescript@5.8.3)(yaml@2.8.0))
|
||||
'@astrojs/node':
|
||||
specifier: ^9.2.2
|
||||
version: 9.3.0(astro@5.12.0(@types/node@24.0.15)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.45.1)(typescript@5.8.3)(yaml@2.8.0))
|
||||
version: 9.3.0(astro@5.12.1(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.45.1)(typescript@5.8.3)(yaml@2.8.0))
|
||||
'@astrojs/react':
|
||||
specifier: ^4.3.0
|
||||
version: 4.3.0(@types/node@24.0.15)(@types/react-dom@19.1.6(@types/react@19.1.6))(@types/react@19.1.6)(jiti@2.4.2)(lightningcss@1.30.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(yaml@2.8.0)
|
||||
version: 4.3.0(@types/node@24.1.0)(@types/react-dom@19.1.6(@types/react@19.1.6))(@types/react@19.1.6)(jiti@2.4.2)(lightningcss@1.30.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(yaml@2.8.0)
|
||||
'@astrojs/rss':
|
||||
specifier: ^4.0.12
|
||||
version: 4.0.12
|
||||
@@ -28,10 +28,10 @@ importers:
|
||||
version: 4.1.11
|
||||
'@tailwindcss/vite':
|
||||
specifier: ^4.1.8
|
||||
version: 4.1.11(vite@6.3.5(@types/node@24.0.15)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))
|
||||
version: 4.1.11(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))
|
||||
astro:
|
||||
specifier: ^5.10.1
|
||||
version: 5.12.0(@types/node@24.0.15)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.45.1)(typescript@5.8.3)(yaml@2.8.0)
|
||||
version: 5.12.1(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.45.1)(typescript@5.8.3)(yaml@2.8.0)
|
||||
framer-motion:
|
||||
specifier: ^12.16.0
|
||||
version: 12.23.6(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
||||
@@ -58,8 +58,8 @@ importers:
|
||||
specifier: ^0.5.16
|
||||
version: 0.5.16(tailwindcss@4.1.11)
|
||||
'@typescript-eslint/parser':
|
||||
specifier: 8.37.0
|
||||
version: 8.37.0(eslint@9.31.0(jiti@2.4.2))(typescript@5.8.3)
|
||||
specifier: 8.38.0
|
||||
version: 8.38.0(eslint@9.31.0(jiti@2.4.2))(typescript@5.8.3)
|
||||
eslint:
|
||||
specifier: 9.31.0
|
||||
version: 9.31.0(jiti@2.4.2)
|
||||
@@ -79,8 +79,8 @@ importers:
|
||||
specifier: ^0.6.12
|
||||
version: 0.6.14(prettier-plugin-astro@0.14.1)(prettier@3.6.2)
|
||||
typescript-eslint:
|
||||
specifier: 8.37.0
|
||||
version: 8.37.0(eslint@9.31.0(jiti@2.4.2))(typescript@5.8.3)
|
||||
specifier: 8.38.0
|
||||
version: 8.38.0(eslint@9.31.0(jiti@2.4.2))(typescript@5.8.3)
|
||||
|
||||
packages:
|
||||
|
||||
@@ -867,8 +867,8 @@ packages:
|
||||
'@types/nlcst@2.0.3':
|
||||
resolution: {integrity: sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA==}
|
||||
|
||||
'@types/node@24.0.15':
|
||||
resolution: {integrity: sha512-oaeTSbCef7U/z7rDeJA138xpG3NuKc64/rZ2qmUFkFJmnMsAPaluIifqyWd8hSSMxyP9oie3dLAqYPblag9KgA==}
|
||||
'@types/node@24.1.0':
|
||||
resolution: {integrity: sha512-ut5FthK5moxFKH2T1CUOC6ctR67rQRvvHdFLCD2Ql6KXmMuCrjsSsRI9UsLCm9M18BMwClv4pn327UvB7eeO1w==}
|
||||
|
||||
'@types/react-dom@19.1.6':
|
||||
resolution: {integrity: sha512-4hOiT/dwO8Ko0gV1m/TJZYk3y0KBnY9vzDh7W+DH17b2HFSOGgdj33dhihPeuy3l0q23+4e+hoXHV6hCC4dCXw==}
|
||||
@@ -884,23 +884,23 @@ packages:
|
||||
'@types/unist@3.0.3':
|
||||
resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==}
|
||||
|
||||
'@typescript-eslint/eslint-plugin@8.37.0':
|
||||
resolution: {integrity: sha512-jsuVWeIkb6ggzB+wPCsR4e6loj+rM72ohW6IBn2C+5NCvfUVY8s33iFPySSVXqtm5Hu29Ne/9bnA0JmyLmgenA==}
|
||||
'@typescript-eslint/eslint-plugin@8.38.0':
|
||||
resolution: {integrity: sha512-CPoznzpuAnIOl4nhj4tRr4gIPj5AfKgkiJmGQDaq+fQnRJTYlcBjbX3wbciGmpoPf8DREufuPRe1tNMZnGdanA==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
peerDependencies:
|
||||
'@typescript-eslint/parser': ^8.37.0
|
||||
'@typescript-eslint/parser': ^8.38.0
|
||||
eslint: ^8.57.0 || ^9.0.0
|
||||
typescript: '>=4.8.4 <5.9.0'
|
||||
|
||||
'@typescript-eslint/parser@8.37.0':
|
||||
resolution: {integrity: sha512-kVIaQE9vrN9RLCQMQ3iyRlVJpTiDUY6woHGb30JDkfJErqrQEmtdWH3gV0PBAfGZgQXoqzXOO0T3K6ioApbbAA==}
|
||||
'@typescript-eslint/parser@8.38.0':
|
||||
resolution: {integrity: sha512-Zhy8HCvBUEfBECzIl1PKqF4p11+d0aUJS1GeUiuqK9WmOug8YCmC4h4bjyBvMyAMI9sbRczmrYL5lKg/YMbrcQ==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
peerDependencies:
|
||||
eslint: ^8.57.0 || ^9.0.0
|
||||
typescript: '>=4.8.4 <5.9.0'
|
||||
|
||||
'@typescript-eslint/project-service@8.37.0':
|
||||
resolution: {integrity: sha512-BIUXYsbkl5A1aJDdYJCBAo8rCEbAvdquQ8AnLb6z5Lp1u3x5PNgSSx9A/zqYc++Xnr/0DVpls8iQ2cJs/izTXA==}
|
||||
'@typescript-eslint/project-service@8.38.0':
|
||||
resolution: {integrity: sha512-dbK7Jvqcb8c9QfH01YB6pORpqX1mn5gDZc9n63Ak/+jD67oWXn3Gs0M6vddAN+eDXBCS5EmNWzbSxsn9SzFWWg==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
peerDependencies:
|
||||
typescript: '>=4.8.4 <5.9.0'
|
||||
@@ -909,18 +909,18 @@ packages:
|
||||
resolution: {integrity: sha512-beu6o6QY4hJAgL1E8RaXNC071G4Kso2MGmJskCFQhRhg8VOH/FDbC8soP8NHN7e/Hdphwp8G8cE6OBzC8o41ZA==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@typescript-eslint/scope-manager@8.37.0':
|
||||
resolution: {integrity: sha512-0vGq0yiU1gbjKob2q691ybTg9JX6ShiVXAAfm2jGf3q0hdP6/BruaFjL/ManAR/lj05AvYCH+5bbVo0VtzmjOA==}
|
||||
'@typescript-eslint/scope-manager@8.38.0':
|
||||
resolution: {integrity: sha512-WJw3AVlFFcdT9Ri1xs/lg8LwDqgekWXWhH3iAF+1ZM+QPd7oxQ6jvtW/JPwzAScxitILUIFs0/AnQ/UWHzbATQ==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@typescript-eslint/tsconfig-utils@8.37.0':
|
||||
resolution: {integrity: sha512-1/YHvAVTimMM9mmlPvTec9NP4bobA1RkDbMydxG8omqwJJLEW/Iy2C4adsAESIXU3WGLXFHSZUU+C9EoFWl4Zg==}
|
||||
'@typescript-eslint/tsconfig-utils@8.38.0':
|
||||
resolution: {integrity: sha512-Lum9RtSE3EroKk/bYns+sPOodqb2Fv50XOl/gMviMKNvanETUuUcC9ObRbzrJ4VSd2JalPqgSAavwrPiPvnAiQ==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
peerDependencies:
|
||||
typescript: '>=4.8.4 <5.9.0'
|
||||
|
||||
'@typescript-eslint/type-utils@8.37.0':
|
||||
resolution: {integrity: sha512-SPkXWIkVZxhgwSwVq9rqj/4VFo7MnWwVaRNznfQDc/xPYHjXnPfLWn+4L6FF1cAz6e7dsqBeMawgl7QjUMj4Ow==}
|
||||
'@typescript-eslint/type-utils@8.38.0':
|
||||
resolution: {integrity: sha512-c7jAvGEZVf0ao2z+nnz8BUaHZD09Agbh+DY7qvBQqLiz8uJzRgVPj5YvOh8I8uEiH8oIUGIfHzMwUcGVco/SJg==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
peerDependencies:
|
||||
eslint: ^8.57.0 || ^9.0.0
|
||||
@@ -934,18 +934,18 @@ packages:
|
||||
resolution: {integrity: sha512-rjLVbmE7HR18kDsjNIZQHxmv9RZwlgzavryL5Lnj2ujIRTeXlKtILHgRNmQ3j4daw7zd+mQgy+uyt6Zo6I0IGA==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@typescript-eslint/types@8.37.0':
|
||||
resolution: {integrity: sha512-ax0nv7PUF9NOVPs+lmQ7yIE7IQmAf8LGcXbMvHX5Gm+YJUYNAl340XkGnrimxZ0elXyoQJuN5sbg6C4evKA4SQ==}
|
||||
'@typescript-eslint/types@8.38.0':
|
||||
resolution: {integrity: sha512-wzkUfX3plUqij4YwWaJyqhiPE5UCRVlFpKn1oCRn2O1bJ592XxWJj8ROQ3JD5MYXLORW84063z3tZTb/cs4Tyw==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@typescript-eslint/typescript-estree@8.37.0':
|
||||
resolution: {integrity: sha512-zuWDMDuzMRbQOM+bHyU4/slw27bAUEcKSKKs3hcv2aNnc/tvE/h7w60dwVw8vnal2Pub6RT1T7BI8tFZ1fE+yg==}
|
||||
'@typescript-eslint/typescript-estree@8.38.0':
|
||||
resolution: {integrity: sha512-fooELKcAKzxux6fA6pxOflpNS0jc+nOQEEOipXFNjSlBS6fqrJOVY/whSn70SScHrcJ2LDsxWrneFoWYSVfqhQ==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
peerDependencies:
|
||||
typescript: '>=4.8.4 <5.9.0'
|
||||
|
||||
'@typescript-eslint/utils@8.37.0':
|
||||
resolution: {integrity: sha512-TSFvkIW6gGjN2p6zbXo20FzCABbyUAuq6tBvNRGsKdsSQ6a7rnV6ADfZ7f4iI3lIiXc4F4WWvtUfDw9CJ9pO5A==}
|
||||
'@typescript-eslint/utils@8.38.0':
|
||||
resolution: {integrity: sha512-hHcMA86Hgt+ijJlrD8fX0j1j8w4C92zue/8LOPAFioIno+W0+L7KqE8QZKCcPGc/92Vs9x36w/4MPTJhqXdyvg==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
peerDependencies:
|
||||
eslint: ^8.57.0 || ^9.0.0
|
||||
@@ -955,8 +955,8 @@ packages:
|
||||
resolution: {integrity: sha512-xoh5rJ+tgsRKoXnkBPFRLZ7rjKM0AfVbC68UZ/ECXoDbfggb9RbEySN359acY1vS3qZ0jVTVWzbtfapwm5ztxw==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@typescript-eslint/visitor-keys@8.37.0':
|
||||
resolution: {integrity: sha512-YzfhzcTnZVPiLfP/oeKtDp2evwvHLMe0LOy7oe+hb9KKIumLNohYS9Hgp1ifwpu42YWxhZE8yieggz6JpqO/1w==}
|
||||
'@typescript-eslint/visitor-keys@8.38.0':
|
||||
resolution: {integrity: sha512-pWrTcoFNWuwHlA9CvlfSsGWs14JxfN1TH25zM5L7o0pRLhsoZkDnTsXfQRJBEWJoV5DL0jf+Z+sxiud+K0mq1g==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@ungap/structured-clone@1.3.0':
|
||||
@@ -1022,8 +1022,8 @@ packages:
|
||||
resolution: {integrity: sha512-JepyLROIad6f44uyqMF6HKE2QbunNzp3mYKRcPoDGt0QkxXmH222FAFC64WTyQu2Kg8NNEXHTN/sWuUId9sSxw==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
astro@5.12.0:
|
||||
resolution: {integrity: sha512-Oov5JsMFHuUmuO+Nx6plfv3nQNK1Xl/8CgLvR8lBhZTjYnraxhuPX5COVAzbom+YLgwaDfK7KBd8zOEopRf9mg==}
|
||||
astro@5.12.1:
|
||||
resolution: {integrity: sha512-/gH9cLIp6UNdbJO1FPBVN/Ea+1I9hJdQoLJKYUsXIRIfHcyF/3NCg0QVDJGw1oWkyQT6x6poQsnbgY9UXitjiw==}
|
||||
engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0'}
|
||||
hasBin: true
|
||||
|
||||
@@ -2560,8 +2560,8 @@ packages:
|
||||
resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==}
|
||||
engines: {node: '>=16'}
|
||||
|
||||
typescript-eslint@8.37.0:
|
||||
resolution: {integrity: sha512-TnbEjzkE9EmcO0Q2zM+GE8NQLItNAJpMmED1BdgoBMYNdqMhzlbqfdSwiRlAzEK2pA9UzVW0gzaaIzXWg2BjfA==}
|
||||
typescript-eslint@8.38.0:
|
||||
resolution: {integrity: sha512-FsZlrYK6bPDGoLeZRuvx2v6qrM03I0U0SnfCLPs/XCCPCFD80xU9Pg09H/K+XFa68uJuZo7l/Xhs+eDRg2l3hg==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
peerDependencies:
|
||||
eslint: ^8.57.0 || ^9.0.0
|
||||
@@ -2875,12 +2875,12 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@astrojs/mdx@4.3.1(astro@5.12.0(@types/node@24.0.15)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.45.1)(typescript@5.8.3)(yaml@2.8.0))':
|
||||
'@astrojs/mdx@4.3.1(astro@5.12.1(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.45.1)(typescript@5.8.3)(yaml@2.8.0))':
|
||||
dependencies:
|
||||
'@astrojs/markdown-remark': 6.3.3
|
||||
'@mdx-js/mdx': 3.1.0(acorn@8.15.0)
|
||||
acorn: 8.15.0
|
||||
astro: 5.12.0(@types/node@24.0.15)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.45.1)(typescript@5.8.3)(yaml@2.8.0)
|
||||
astro: 5.12.1(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.45.1)(typescript@5.8.3)(yaml@2.8.0)
|
||||
es-module-lexer: 1.7.0
|
||||
estree-util-visit: 2.0.0
|
||||
hast-util-to-html: 9.0.5
|
||||
@@ -2894,10 +2894,10 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@astrojs/node@9.3.0(astro@5.12.0(@types/node@24.0.15)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.45.1)(typescript@5.8.3)(yaml@2.8.0))':
|
||||
'@astrojs/node@9.3.0(astro@5.12.1(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.45.1)(typescript@5.8.3)(yaml@2.8.0))':
|
||||
dependencies:
|
||||
'@astrojs/internal-helpers': 0.6.1
|
||||
astro: 5.12.0(@types/node@24.0.15)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.45.1)(typescript@5.8.3)(yaml@2.8.0)
|
||||
astro: 5.12.1(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.45.1)(typescript@5.8.3)(yaml@2.8.0)
|
||||
send: 1.2.0
|
||||
server-destroy: 1.0.1
|
||||
transitivePeerDependencies:
|
||||
@@ -2907,15 +2907,15 @@ snapshots:
|
||||
dependencies:
|
||||
prismjs: 1.30.0
|
||||
|
||||
'@astrojs/react@4.3.0(@types/node@24.0.15)(@types/react-dom@19.1.6(@types/react@19.1.6))(@types/react@19.1.6)(jiti@2.4.2)(lightningcss@1.30.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(yaml@2.8.0)':
|
||||
'@astrojs/react@4.3.0(@types/node@24.1.0)(@types/react-dom@19.1.6(@types/react@19.1.6))(@types/react@19.1.6)(jiti@2.4.2)(lightningcss@1.30.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(yaml@2.8.0)':
|
||||
dependencies:
|
||||
'@types/react': 19.1.6
|
||||
'@types/react-dom': 19.1.6(@types/react@19.1.6)
|
||||
'@vitejs/plugin-react': 4.5.1(vite@6.3.5(@types/node@24.0.15)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))
|
||||
'@vitejs/plugin-react': 4.5.1(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))
|
||||
react: 19.1.0
|
||||
react-dom: 19.1.0(react@19.1.0)
|
||||
ultrahtml: 1.6.0
|
||||
vite: 6.3.5(@types/node@24.0.15)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)
|
||||
vite: 6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)
|
||||
transitivePeerDependencies:
|
||||
- '@types/node'
|
||||
- jiti
|
||||
@@ -3542,12 +3542,12 @@ snapshots:
|
||||
postcss-selector-parser: 6.0.10
|
||||
tailwindcss: 4.1.11
|
||||
|
||||
'@tailwindcss/vite@4.1.11(vite@6.3.5(@types/node@24.0.15)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))':
|
||||
'@tailwindcss/vite@4.1.11(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))':
|
||||
dependencies:
|
||||
'@tailwindcss/node': 4.1.11
|
||||
'@tailwindcss/oxide': 4.1.11
|
||||
tailwindcss: 4.1.11
|
||||
vite: 6.3.5(@types/node@24.0.15)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)
|
||||
vite: 6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)
|
||||
|
||||
'@types/babel__core@7.20.5':
|
||||
dependencies:
|
||||
@@ -3582,7 +3582,7 @@ snapshots:
|
||||
|
||||
'@types/fontkit@2.0.8':
|
||||
dependencies:
|
||||
'@types/node': 24.0.15
|
||||
'@types/node': 24.1.0
|
||||
|
||||
'@types/hast@3.0.4':
|
||||
dependencies:
|
||||
@@ -3602,7 +3602,7 @@ snapshots:
|
||||
dependencies:
|
||||
'@types/unist': 3.0.3
|
||||
|
||||
'@types/node@24.0.15':
|
||||
'@types/node@24.1.0':
|
||||
dependencies:
|
||||
undici-types: 7.8.0
|
||||
|
||||
@@ -3618,14 +3618,14 @@ snapshots:
|
||||
|
||||
'@types/unist@3.0.3': {}
|
||||
|
||||
'@typescript-eslint/eslint-plugin@8.37.0(@typescript-eslint/parser@8.37.0(eslint@9.31.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.31.0(jiti@2.4.2))(typescript@5.8.3)':
|
||||
'@typescript-eslint/eslint-plugin@8.38.0(@typescript-eslint/parser@8.38.0(eslint@9.31.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.31.0(jiti@2.4.2))(typescript@5.8.3)':
|
||||
dependencies:
|
||||
'@eslint-community/regexpp': 4.12.1
|
||||
'@typescript-eslint/parser': 8.37.0(eslint@9.31.0(jiti@2.4.2))(typescript@5.8.3)
|
||||
'@typescript-eslint/scope-manager': 8.37.0
|
||||
'@typescript-eslint/type-utils': 8.37.0(eslint@9.31.0(jiti@2.4.2))(typescript@5.8.3)
|
||||
'@typescript-eslint/utils': 8.37.0(eslint@9.31.0(jiti@2.4.2))(typescript@5.8.3)
|
||||
'@typescript-eslint/visitor-keys': 8.37.0
|
||||
'@typescript-eslint/parser': 8.38.0(eslint@9.31.0(jiti@2.4.2))(typescript@5.8.3)
|
||||
'@typescript-eslint/scope-manager': 8.38.0
|
||||
'@typescript-eslint/type-utils': 8.38.0(eslint@9.31.0(jiti@2.4.2))(typescript@5.8.3)
|
||||
'@typescript-eslint/utils': 8.38.0(eslint@9.31.0(jiti@2.4.2))(typescript@5.8.3)
|
||||
'@typescript-eslint/visitor-keys': 8.38.0
|
||||
eslint: 9.31.0(jiti@2.4.2)
|
||||
graphemer: 1.4.0
|
||||
ignore: 7.0.5
|
||||
@@ -3635,22 +3635,22 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@typescript-eslint/parser@8.37.0(eslint@9.31.0(jiti@2.4.2))(typescript@5.8.3)':
|
||||
'@typescript-eslint/parser@8.38.0(eslint@9.31.0(jiti@2.4.2))(typescript@5.8.3)':
|
||||
dependencies:
|
||||
'@typescript-eslint/scope-manager': 8.37.0
|
||||
'@typescript-eslint/types': 8.37.0
|
||||
'@typescript-eslint/typescript-estree': 8.37.0(typescript@5.8.3)
|
||||
'@typescript-eslint/visitor-keys': 8.37.0
|
||||
'@typescript-eslint/scope-manager': 8.38.0
|
||||
'@typescript-eslint/types': 8.38.0
|
||||
'@typescript-eslint/typescript-estree': 8.38.0(typescript@5.8.3)
|
||||
'@typescript-eslint/visitor-keys': 8.38.0
|
||||
debug: 4.4.1
|
||||
eslint: 9.31.0(jiti@2.4.2)
|
||||
typescript: 5.8.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@typescript-eslint/project-service@8.37.0(typescript@5.8.3)':
|
||||
'@typescript-eslint/project-service@8.38.0(typescript@5.8.3)':
|
||||
dependencies:
|
||||
'@typescript-eslint/tsconfig-utils': 8.37.0(typescript@5.8.3)
|
||||
'@typescript-eslint/types': 8.37.0
|
||||
'@typescript-eslint/tsconfig-utils': 8.38.0(typescript@5.8.3)
|
||||
'@typescript-eslint/types': 8.38.0
|
||||
debug: 4.4.1
|
||||
typescript: 5.8.3
|
||||
transitivePeerDependencies:
|
||||
@@ -3661,20 +3661,20 @@ snapshots:
|
||||
'@typescript-eslint/types': 8.34.1
|
||||
'@typescript-eslint/visitor-keys': 8.34.1
|
||||
|
||||
'@typescript-eslint/scope-manager@8.37.0':
|
||||
'@typescript-eslint/scope-manager@8.38.0':
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 8.37.0
|
||||
'@typescript-eslint/visitor-keys': 8.37.0
|
||||
'@typescript-eslint/types': 8.38.0
|
||||
'@typescript-eslint/visitor-keys': 8.38.0
|
||||
|
||||
'@typescript-eslint/tsconfig-utils@8.37.0(typescript@5.8.3)':
|
||||
'@typescript-eslint/tsconfig-utils@8.38.0(typescript@5.8.3)':
|
||||
dependencies:
|
||||
typescript: 5.8.3
|
||||
|
||||
'@typescript-eslint/type-utils@8.37.0(eslint@9.31.0(jiti@2.4.2))(typescript@5.8.3)':
|
||||
'@typescript-eslint/type-utils@8.38.0(eslint@9.31.0(jiti@2.4.2))(typescript@5.8.3)':
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 8.37.0
|
||||
'@typescript-eslint/typescript-estree': 8.37.0(typescript@5.8.3)
|
||||
'@typescript-eslint/utils': 8.37.0(eslint@9.31.0(jiti@2.4.2))(typescript@5.8.3)
|
||||
'@typescript-eslint/types': 8.38.0
|
||||
'@typescript-eslint/typescript-estree': 8.38.0(typescript@5.8.3)
|
||||
'@typescript-eslint/utils': 8.38.0(eslint@9.31.0(jiti@2.4.2))(typescript@5.8.3)
|
||||
debug: 4.4.1
|
||||
eslint: 9.31.0(jiti@2.4.2)
|
||||
ts-api-utils: 2.1.0(typescript@5.8.3)
|
||||
@@ -3686,14 +3686,14 @@ snapshots:
|
||||
|
||||
'@typescript-eslint/types@8.34.1': {}
|
||||
|
||||
'@typescript-eslint/types@8.37.0': {}
|
||||
'@typescript-eslint/types@8.38.0': {}
|
||||
|
||||
'@typescript-eslint/typescript-estree@8.37.0(typescript@5.8.3)':
|
||||
'@typescript-eslint/typescript-estree@8.38.0(typescript@5.8.3)':
|
||||
dependencies:
|
||||
'@typescript-eslint/project-service': 8.37.0(typescript@5.8.3)
|
||||
'@typescript-eslint/tsconfig-utils': 8.37.0(typescript@5.8.3)
|
||||
'@typescript-eslint/types': 8.37.0
|
||||
'@typescript-eslint/visitor-keys': 8.37.0
|
||||
'@typescript-eslint/project-service': 8.38.0(typescript@5.8.3)
|
||||
'@typescript-eslint/tsconfig-utils': 8.38.0(typescript@5.8.3)
|
||||
'@typescript-eslint/types': 8.38.0
|
||||
'@typescript-eslint/visitor-keys': 8.38.0
|
||||
debug: 4.4.1
|
||||
fast-glob: 3.3.3
|
||||
is-glob: 4.0.3
|
||||
@@ -3704,12 +3704,12 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@typescript-eslint/utils@8.37.0(eslint@9.31.0(jiti@2.4.2))(typescript@5.8.3)':
|
||||
'@typescript-eslint/utils@8.38.0(eslint@9.31.0(jiti@2.4.2))(typescript@5.8.3)':
|
||||
dependencies:
|
||||
'@eslint-community/eslint-utils': 4.7.0(eslint@9.31.0(jiti@2.4.2))
|
||||
'@typescript-eslint/scope-manager': 8.37.0
|
||||
'@typescript-eslint/types': 8.37.0
|
||||
'@typescript-eslint/typescript-estree': 8.37.0(typescript@5.8.3)
|
||||
'@typescript-eslint/scope-manager': 8.38.0
|
||||
'@typescript-eslint/types': 8.38.0
|
||||
'@typescript-eslint/typescript-estree': 8.38.0(typescript@5.8.3)
|
||||
eslint: 9.31.0(jiti@2.4.2)
|
||||
typescript: 5.8.3
|
||||
transitivePeerDependencies:
|
||||
@@ -3720,14 +3720,14 @@ snapshots:
|
||||
'@typescript-eslint/types': 8.34.1
|
||||
eslint-visitor-keys: 4.2.1
|
||||
|
||||
'@typescript-eslint/visitor-keys@8.37.0':
|
||||
'@typescript-eslint/visitor-keys@8.38.0':
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 8.37.0
|
||||
'@typescript-eslint/types': 8.38.0
|
||||
eslint-visitor-keys: 4.2.1
|
||||
|
||||
'@ungap/structured-clone@1.3.0': {}
|
||||
|
||||
'@vitejs/plugin-react@4.5.1(vite@6.3.5(@types/node@24.0.15)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))':
|
||||
'@vitejs/plugin-react@4.5.1(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))':
|
||||
dependencies:
|
||||
'@babel/core': 7.27.4
|
||||
'@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.27.4)
|
||||
@@ -3735,7 +3735,7 @@ snapshots:
|
||||
'@rolldown/pluginutils': 1.0.0-beta.9
|
||||
'@types/babel__core': 7.20.5
|
||||
react-refresh: 0.17.0
|
||||
vite: 6.3.5(@types/node@24.0.15)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)
|
||||
vite: 6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@@ -3796,7 +3796,7 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
astro@5.12.0(@types/node@24.0.15)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.45.1)(typescript@5.8.3)(yaml@2.8.0):
|
||||
astro@5.12.1(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.45.1)(typescript@5.8.3)(yaml@2.8.0):
|
||||
dependencies:
|
||||
'@astrojs/compiler': 2.12.2
|
||||
'@astrojs/internal-helpers': 0.6.1
|
||||
@@ -3852,8 +3852,8 @@ snapshots:
|
||||
unist-util-visit: 5.0.0
|
||||
unstorage: 1.16.1
|
||||
vfile: 6.0.3
|
||||
vite: 6.3.5(@types/node@24.0.15)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)
|
||||
vitefu: 1.1.1(vite@6.3.5(@types/node@24.0.15)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))
|
||||
vite: 6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)
|
||||
vitefu: 1.1.1(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))
|
||||
xxhash-wasm: 1.1.0
|
||||
yargs-parser: 21.1.1
|
||||
yocto-spinner: 0.2.3
|
||||
@@ -5788,12 +5788,12 @@ snapshots:
|
||||
|
||||
type-fest@4.41.0: {}
|
||||
|
||||
typescript-eslint@8.37.0(eslint@9.31.0(jiti@2.4.2))(typescript@5.8.3):
|
||||
typescript-eslint@8.38.0(eslint@9.31.0(jiti@2.4.2))(typescript@5.8.3):
|
||||
dependencies:
|
||||
'@typescript-eslint/eslint-plugin': 8.37.0(@typescript-eslint/parser@8.37.0(eslint@9.31.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.31.0(jiti@2.4.2))(typescript@5.8.3)
|
||||
'@typescript-eslint/parser': 8.37.0(eslint@9.31.0(jiti@2.4.2))(typescript@5.8.3)
|
||||
'@typescript-eslint/typescript-estree': 8.37.0(typescript@5.8.3)
|
||||
'@typescript-eslint/utils': 8.37.0(eslint@9.31.0(jiti@2.4.2))(typescript@5.8.3)
|
||||
'@typescript-eslint/eslint-plugin': 8.38.0(@typescript-eslint/parser@8.38.0(eslint@9.31.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.31.0(jiti@2.4.2))(typescript@5.8.3)
|
||||
'@typescript-eslint/parser': 8.38.0(eslint@9.31.0(jiti@2.4.2))(typescript@5.8.3)
|
||||
'@typescript-eslint/typescript-estree': 8.38.0(typescript@5.8.3)
|
||||
'@typescript-eslint/utils': 8.38.0(eslint@9.31.0(jiti@2.4.2))(typescript@5.8.3)
|
||||
eslint: 9.31.0(jiti@2.4.2)
|
||||
typescript: 5.8.3
|
||||
transitivePeerDependencies:
|
||||
@@ -5919,7 +5919,7 @@ snapshots:
|
||||
'@types/unist': 3.0.3
|
||||
vfile-message: 4.0.2
|
||||
|
||||
vite@6.3.5(@types/node@24.0.15)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0):
|
||||
vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0):
|
||||
dependencies:
|
||||
esbuild: 0.25.8
|
||||
fdir: 6.4.6(picomatch@4.0.3)
|
||||
@@ -5928,15 +5928,15 @@ snapshots:
|
||||
rollup: 4.45.1
|
||||
tinyglobby: 0.2.14
|
||||
optionalDependencies:
|
||||
'@types/node': 24.0.15
|
||||
'@types/node': 24.1.0
|
||||
fsevents: 2.3.3
|
||||
jiti: 2.4.2
|
||||
lightningcss: 1.30.1
|
||||
yaml: 2.8.0
|
||||
|
||||
vitefu@1.1.1(vite@6.3.5(@types/node@24.0.15)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)):
|
||||
vitefu@1.1.1(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)):
|
||||
optionalDependencies:
|
||||
vite: 6.3.5(@types/node@24.0.15)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)
|
||||
vite: 6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)
|
||||
|
||||
web-namespaces@2.0.1: {}
|
||||
|
||||
|
@@ -19,7 +19,7 @@ const { tags = [], class: className = '' } = Astro.props;
|
||||
</a>
|
||||
))}
|
||||
{tags.length > 2 && (
|
||||
<span class="inline-flex items-center rounded-full bg-zinc-50 px-2 py-0.5 text-xs text-zinc-500 dark:bg-zinc-800/50 dark:text-zinc-400">
|
||||
<span class="inline-flex items-center rounded-full bg-zinc-50 px-2 py-0.5 text-xs text-zinc-500 dark:bg-zinc-900 dark:text-zinc-400">
|
||||
+{tags.length - 3}
|
||||
</span>
|
||||
)}
|
||||
|
@@ -29,12 +29,8 @@ import Layout from '../layouts/Layout.astro';
|
||||
<div class="mt-10 flex flex-col items-center justify-center gap-4 sm:flex-row">
|
||||
<a
|
||||
href="/"
|
||||
class="group relative inline-flex items-center gap-2 overflow-hidden rounded-lg bg-zinc-900 px-6 py-3 text-zinc-100 shadow-lg transition-all duration-300 hover:bg-zinc-800 hover:shadow-xl dark:bg-zinc-100 dark:text-zinc-900 dark:hover:bg-zinc-200"
|
||||
class="relative inline-flex items-center gap-2 overflow-hidden rounded-lg bg-zinc-900 px-6 py-3 text-zinc-100 shadow-lg transition-all duration-300 hover:bg-cyan-600 hover:text-zinc-100 hover:shadow-xl dark:bg-zinc-100 dark:text-zinc-900 dark:hover:bg-cyan-600"
|
||||
>
|
||||
<span
|
||||
class="absolute inset-0 z-0 bg-gradient-to-r from-zinc-700 to-zinc-900 opacity-0 transition-opacity duration-300 group-hover:opacity-100 dark:from-zinc-300 dark:to-zinc-100"
|
||||
>
|
||||
</span>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
@@ -55,7 +51,7 @@ import Layout from '../layouts/Layout.astro';
|
||||
|
||||
<button
|
||||
id="back-button"
|
||||
class="group inline-flex items-center gap-2 rounded-lg border border-zinc-300 px-6 py-3 text-zinc-700 shadow-xs transition-all duration-300 hover:bg-zinc-100 hover:shadow-md dark:border-zinc-700 dark:text-zinc-300 dark:hover:bg-zinc-800"
|
||||
class="group inline-flex translate-y-0 items-center gap-2 rounded-lg border border-zinc-300 px-6 py-3 text-zinc-700 shadow-xs transition-all duration-300 hover:bg-zinc-100 hover:shadow-md dark:border-zinc-700 dark:text-zinc-300 dark:hover:bg-zinc-800"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
@@ -7,7 +7,6 @@ import { readSingleton, readItems } from '@directus/sdk';
|
||||
|
||||
const global = await directus.request(readSingleton('global'));
|
||||
const about = await directus.request(readSingleton('about'));
|
||||
|
||||
const skills = await directus.request(
|
||||
readItems('skills', {
|
||||
fields: ['*'],
|
||||
@@ -20,17 +19,14 @@ const skills = await directus.request(
|
||||
class="theme-transition-all mx-auto max-w-6xl px-4 py-8 sm:px-6 sm:py-12 md:py-16"
|
||||
transition:animate="slide"
|
||||
>
|
||||
<!-- Hero Section -->
|
||||
<!-- Introduction Section -->
|
||||
<div class="relative mb-12 sm:mb-16 md:mb-20">
|
||||
<div class="relative grid grid-cols-1 items-center gap-8 md:grid-cols-2 md:gap-12">
|
||||
<div class="hero-text order-2 text-center md:order-1 md:text-left">
|
||||
<h1
|
||||
class="theme-transition-color hero-text mb-4 text-3xl font-bold tracking-tight text-zinc-900 sm:mb-6 sm:text-4xl md:text-5xl dark:text-zinc-100"
|
||||
>
|
||||
Hello, I'm <span
|
||||
class="theme-transition-all bg-gradient-to-r from-zinc-500 to-zinc-900 bg-clip-text text-transparent dark:from-zinc-300 dark:to-zinc-100"
|
||||
>{global.name}</span
|
||||
>
|
||||
Hello, I'm <span class="theme-transition-all bg-clip-text">{global.name}</span>
|
||||
</h1>
|
||||
|
||||
<p
|
||||
@@ -38,12 +34,6 @@ const skills = await directus.request(
|
||||
>
|
||||
{about.background}
|
||||
</p>
|
||||
|
||||
<div
|
||||
class="social-links-container theme-transition-children flex flex-wrap justify-center gap-4 md:justify-start"
|
||||
>
|
||||
<!-- Social links remain the same -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="relative order-1 md:order-2">
|
||||
@@ -61,7 +51,7 @@ const skills = await directus.request(
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- About Section -->
|
||||
<!-- About Me section -->
|
||||
<div class="theme-transition-all mb-16 sm:mb-20 md:mb-24">
|
||||
<div class="mx-auto max-w-3xl">
|
||||
<h2
|
||||
@@ -111,10 +101,7 @@ const skills = await directus.request(
|
||||
<div class="slider-track animate-slide flex">
|
||||
{
|
||||
[...skills, ...skills, ...skills].map((skill, index) => (
|
||||
<div
|
||||
key={`${skill.title}-${index}`}
|
||||
class="skill-card theme-transition-element mx-2 min-w-[220px] transform rounded-xl border border-zinc-200 bg-white transition-all duration-300 hover:-translate-y-2 hover:scale-105 hover:border-zinc-300 hover:shadow-xl sm:mx-4 sm:min-w-[280px] dark:border-zinc-700 dark:bg-zinc-800/50 dark:hover:border-zinc-600"
|
||||
>
|
||||
<div class="skill-card theme-transition-element Ztransition-all mx-2 min-w-[220px] transform rounded-xl border border-zinc-300 bg-white duration-300 hover:-translate-y-2 hover:scale-105 hover:border-zinc-200 hover:shadow-xl sm:mx-4 sm:min-w-[280px] dark:border-zinc-700 dark:bg-zinc-900 dark:hover:border-zinc-800 dark:hover:bg-zinc-900">
|
||||
<div class="p-4 sm:p-6">
|
||||
<div class="mb-4 flex items-center justify-between sm:mb-6">
|
||||
<div class="flex items-center gap-2 sm:gap-4">
|
||||
@@ -158,6 +145,7 @@ const skills = await directus.request(
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Contact Section -->
|
||||
<div class="theme-transition-all mx-auto max-w-3xl text-center">
|
||||
<h2
|
||||
@@ -222,45 +210,13 @@ const skills = await directus.request(
|
||||
animateContent();
|
||||
|
||||
// Create seamless infinite scrolling effect
|
||||
const sliderTrack = document.querySelector('.slider-track');
|
||||
function setupInfiniteScroll() {
|
||||
const cards = document.querySelectorAll('.skill-card');
|
||||
if (!cards.length) return;
|
||||
|
||||
// Set proper animation based on screen size
|
||||
function updateScrollAnimation() {
|
||||
if (window.innerWidth >= 640) {
|
||||
sliderTrack.style.animation = 'scroll 60s linear infinite';
|
||||
} else {
|
||||
sliderTrack.style.animation = 'scroll 40s linear infinite';
|
||||
}
|
||||
}
|
||||
|
||||
updateScrollAnimation();
|
||||
window.addEventListener('resize', updateScrollAnimation);
|
||||
}
|
||||
|
||||
setupInfiniteScroll();
|
||||
|
||||
// Pause animation on hover/touch
|
||||
sliderTrack?.addEventListener('mouseenter', () => {
|
||||
sliderTrack.style.animationPlayState = 'paused';
|
||||
});
|
||||
|
||||
sliderTrack?.addEventListener('touchstart', () => {
|
||||
sliderTrack.style.animationPlayState = 'paused';
|
||||
});
|
||||
|
||||
sliderTrack?.addEventListener('mouseleave', () => {
|
||||
sliderTrack.style.animationPlayState = 'running';
|
||||
});
|
||||
|
||||
sliderTrack?.addEventListener('touchend', () => {
|
||||
setTimeout(() => {
|
||||
sliderTrack.style.animationPlayState = 'running';
|
||||
}, 1000); // Delay resuming animation after touch
|
||||
});
|
||||
|
||||
// Add hover effects to cards - only on non-touch devices
|
||||
const isTouchDevice = 'ontouchstart' in window || navigator.maxTouchPoints > 0;
|
||||
const cards = document.querySelectorAll('.skill-card');
|
||||
@@ -308,18 +264,6 @@ const skills = await directus.request(
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Handle theme transition
|
||||
document.addEventListener('themeChange', () => {
|
||||
cards.forEach((card, index) => {
|
||||
setTimeout(() => {
|
||||
card.classList.add('theme-changing');
|
||||
setTimeout(() => {
|
||||
card.classList.remove('theme-changing');
|
||||
}, 600);
|
||||
}, index * 50);
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -442,36 +386,4 @@ const skills = await directus.request(
|
||||
min-height: 44px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Content reveal animations */
|
||||
.hero-text h1,
|
||||
.hero-text span,
|
||||
.hero-text p,
|
||||
.hero-text ~ div {
|
||||
opacity: 0;
|
||||
transform: translateY(20px);
|
||||
transition:
|
||||
opacity 0.8s ease,
|
||||
transform 0.8s ease;
|
||||
}
|
||||
|
||||
.animate-reveal {
|
||||
opacity: 1 !important;
|
||||
transform: translateY(0) !important;
|
||||
}
|
||||
|
||||
/* Theme transition effect */
|
||||
:global(.theme-switching) .theme-transition-element {
|
||||
animation: fadeIn 0.6s cubic-bezier(0.22, 1, 0.36, 1);
|
||||
}
|
||||
|
||||
/* Smooth card transition during theme switch */
|
||||
.skill-card.theme-transition-element {
|
||||
transition:
|
||||
background-color var(--theme-transition),
|
||||
border-color var(--theme-transition),
|
||||
color var(--theme-transition),
|
||||
box-shadow var(--theme-transition),
|
||||
transform 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275);
|
||||
}
|
||||
</style>
|
||||
|
@@ -117,32 +117,6 @@ const { post, nextPost, prevPost } = Astro.props;
|
||||
|
||||
<script>
|
||||
document.addEventListener('astro:page-load', () => {
|
||||
// Show button when scrolled down
|
||||
const backToTopButton = document.getElementById('back-to-top');
|
||||
if (backToTopButton) {
|
||||
const toggleBackToTopButton = () => {
|
||||
if (window.scrollY > 300) {
|
||||
backToTopButton.classList.remove('opacity-0', 'invisible');
|
||||
backToTopButton.classList.add('opacity-100', 'visible');
|
||||
} else {
|
||||
backToTopButton.classList.remove('opacity-100', 'visible');
|
||||
backToTopButton.classList.add('opacity-0', 'invisible');
|
||||
}
|
||||
};
|
||||
|
||||
// Scroll to top when clicked
|
||||
backToTopButton.addEventListener('click', () => {
|
||||
window.scrollTo({
|
||||
top: 0,
|
||||
behavior: 'smooth',
|
||||
});
|
||||
});
|
||||
|
||||
// Check scroll position
|
||||
window.addEventListener('scroll', toggleBackToTopButton);
|
||||
toggleBackToTopButton();
|
||||
}
|
||||
|
||||
// Add smooth reveal animations for content after loading
|
||||
const animateContent = () => {
|
||||
// Animate hero section
|
||||
@@ -258,24 +232,6 @@ const { post, nextPost, prevPost } = Astro.props;
|
||||
</script>
|
||||
|
||||
<style>
|
||||
/* Content reveal animations */
|
||||
.hero-text h1,
|
||||
.hero-text span,
|
||||
.hero-text p,
|
||||
.hero-text ~ div,
|
||||
article.group {
|
||||
opacity: 0;
|
||||
transform: translateY(20px);
|
||||
transition:
|
||||
opacity 0.8s ease,
|
||||
transform 0.8s ease;
|
||||
}
|
||||
|
||||
.animate-reveal {
|
||||
opacity: 1 !important;
|
||||
transform: translateY(0) !important;
|
||||
}
|
||||
|
||||
/* Language badge styling */
|
||||
.language-badge {
|
||||
font-family:
|
||||
@@ -296,7 +252,7 @@ const { post, nextPost, prevPost } = Astro.props;
|
||||
}
|
||||
}
|
||||
|
||||
/* Enhanced typography for blog content - Responsive adjustments */
|
||||
/* Typography for blog content */
|
||||
.prose {
|
||||
@reference text-zinc-800 dark:text-zinc-200;
|
||||
}
|
||||
|
@@ -133,7 +133,7 @@ const years = Object.keys(postsByYear).sort((a, b) => b - a);
|
||||
href={`#year-${year}`}
|
||||
class={`mr-3 flex items-center rounded-xl border border-zinc-300 bg-white/50 px-4 py-2 whitespace-nowrap transition-all duration-300 hover:bg-zinc-50 sm:rounded-2xl md:mr-0 md:w-full md:px-0 md:py-3 md:whitespace-normal dark:border-zinc-800 dark:hover:bg-zinc-800/70 ${index === 0 ? 'bg-white/50 dark:bg-zinc-900/50' : ''}`}
|
||||
>
|
||||
<span class="ml-3 text-base font-medium text-zinc-900 md:text-lg dark:text-zinc-100">
|
||||
<span class="mr-3 ml-3 text-base font-medium text-zinc-900 md:text-lg dark:text-zinc-100">
|
||||
{year}
|
||||
</span>
|
||||
<span class="mr-3 text-xs text-zinc-500 md:ml-auto md:text-sm dark:text-zinc-400">
|
||||
@@ -244,56 +244,6 @@ const years = Object.keys(postsByYear).sort((a, b) => b - a);
|
||||
|
||||
<script>
|
||||
document.addEventListener('astro:page-load', () => {
|
||||
// Force the viewport to be exactly the width of the device
|
||||
const fixViewportWidth = () => {
|
||||
const viewport = document.querySelector('meta[name="viewport"]');
|
||||
if (!viewport) {
|
||||
const meta = document.createElement('meta');
|
||||
meta.name = 'viewport';
|
||||
meta.content = 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no';
|
||||
document.getElementsByTagName('head')[0].appendChild(meta);
|
||||
} else {
|
||||
viewport.setAttribute(
|
||||
'content',
|
||||
'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no'
|
||||
);
|
||||
}
|
||||
|
||||
// Fix for horizontal overflow
|
||||
document.body.style.overflowX = 'hidden';
|
||||
document.documentElement.style.overflowX = 'hidden';
|
||||
document.documentElement.style.width = '100%';
|
||||
document.body.style.width = '100%';
|
||||
};
|
||||
|
||||
fixViewportWidth();
|
||||
|
||||
// Show button when scrolled down
|
||||
const backToTopButton = document.getElementById('back-to-top');
|
||||
if (backToTopButton) {
|
||||
const toggleBackToTopButton = () => {
|
||||
if (window.scrollY > 300) {
|
||||
backToTopButton.classList.remove('opacity-0', 'invisible');
|
||||
backToTopButton.classList.add('opacity-100', 'visible');
|
||||
} else {
|
||||
backToTopButton.classList.remove('opacity-100', 'visible');
|
||||
backToTopButton.classList.add('opacity-0', 'invisible');
|
||||
}
|
||||
};
|
||||
|
||||
// Scroll to top when clicked
|
||||
backToTopButton.addEventListener('click', () => {
|
||||
window.scrollTo({
|
||||
top: 0,
|
||||
behavior: 'smooth',
|
||||
});
|
||||
});
|
||||
|
||||
// Check scroll position
|
||||
window.addEventListener('scroll', toggleBackToTopButton);
|
||||
toggleBackToTopButton();
|
||||
}
|
||||
|
||||
// Add smooth reveal animations for content after loading
|
||||
const animateContent = () => {
|
||||
// Animate hero section
|
||||
@@ -322,453 +272,10 @@ const years = Object.keys(postsByYear).sort((a, b) => b - a);
|
||||
};
|
||||
|
||||
animateContent();
|
||||
|
||||
// Add smooth scrolling to year links
|
||||
document.querySelectorAll('a[href^="#year-"]').forEach((anchor) => {
|
||||
anchor.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
const targetId = this.getAttribute('href');
|
||||
const targetElement = document.querySelector(targetId);
|
||||
|
||||
if (targetElement) {
|
||||
window.scrollTo({
|
||||
top: targetElement.offsetTop - 100,
|
||||
behavior: 'smooth',
|
||||
});
|
||||
|
||||
// Update URL hash without jumping
|
||||
history.pushState(null, null, targetId);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Adjust tag items based on screen size with extreme precision
|
||||
const adjustTagItems = () => {
|
||||
const tagItems = document.querySelectorAll('.theme-ripple');
|
||||
const width =
|
||||
window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
|
||||
const isVerySmall = width < 360;
|
||||
const isExtremelySmall = width < 280;
|
||||
const isMicroScreen = width < 240;
|
||||
|
||||
// Fix container width to match viewport exactly
|
||||
const container = document.querySelector('.tag-cloud');
|
||||
if (container) {
|
||||
container.style.maxWidth = '100vw';
|
||||
container.style.width = '100%';
|
||||
container.style.boxSizing = 'border-box';
|
||||
|
||||
// Remove any margins that might cause overflow
|
||||
container.style.marginLeft = '0';
|
||||
container.style.marginRight = '0';
|
||||
}
|
||||
|
||||
// Fix grid width
|
||||
const grid = document.querySelector('.grid');
|
||||
if (grid) {
|
||||
grid.style.width = '100%';
|
||||
grid.style.maxWidth = '100%';
|
||||
}
|
||||
|
||||
tagItems.forEach((item) => {
|
||||
// Set appropriate classes based on screen size
|
||||
if (isMicroScreen) {
|
||||
item.classList.add('micro-screen');
|
||||
item.classList.remove('extremely-small-screen', 'very-small-screen');
|
||||
} else if (isExtremelySmall) {
|
||||
item.classList.add('extremely-small-screen');
|
||||
item.classList.remove('very-small-screen', 'micro-screen');
|
||||
} else if (isVerySmall) {
|
||||
item.classList.add('very-small-screen');
|
||||
item.classList.remove('extremely-small-screen', 'micro-screen');
|
||||
} else {
|
||||
item.classList.remove('very-small-screen', 'extremely-small-screen', 'micro-screen');
|
||||
}
|
||||
|
||||
// Ensure text doesn't overflow on small screens
|
||||
const tagName = item.querySelector('h3');
|
||||
const tagCount = item.querySelector('p');
|
||||
|
||||
if (tagName) {
|
||||
// Set title for accessibility
|
||||
tagName.title = tagName.textContent.trim();
|
||||
|
||||
// Adjust text length based on screen size
|
||||
if (isMicroScreen && tagName.textContent.length > 6) {
|
||||
tagName.dataset.fullText = tagName.textContent;
|
||||
tagName.textContent = tagName.textContent.substring(0, 6) + '...';
|
||||
} else if (isExtremelySmall && tagName.textContent.length > 8) {
|
||||
tagName.dataset.fullText = tagName.textContent;
|
||||
tagName.textContent = tagName.textContent.substring(0, 8) + '...';
|
||||
} else if (isVerySmall && tagName.textContent.length > 12) {
|
||||
tagName.dataset.fullText = tagName.textContent;
|
||||
tagName.textContent = tagName.textContent.substring(0, 12) + '...';
|
||||
} else if (tagName.dataset.fullText) {
|
||||
tagName.textContent = tagName.dataset.fullText;
|
||||
delete tagName.dataset.fullText;
|
||||
}
|
||||
}
|
||||
|
||||
// Set the tag hue for hover effects
|
||||
const hue = item.style.getPropertyValue('--tag-hue');
|
||||
item.style.setProperty('--hover-hue', hue);
|
||||
});
|
||||
};
|
||||
|
||||
adjustTagItems();
|
||||
|
||||
// Run on resize with optimized debounce
|
||||
let resizeTimer;
|
||||
const handleResize = () => {
|
||||
if (resizeTimer) {
|
||||
window.cancelAnimationFrame(resizeTimer);
|
||||
}
|
||||
|
||||
resizeTimer = window.requestAnimationFrame(() => {
|
||||
fixViewportWidth();
|
||||
adjustTagItems();
|
||||
});
|
||||
};
|
||||
|
||||
window.addEventListener('resize', handleResize);
|
||||
window.addEventListener('orientationchange', handleResize);
|
||||
|
||||
// Ensure layout is recalculated after page is fully loaded
|
||||
window.addEventListener('load', () => {
|
||||
fixViewportWidth();
|
||||
adjustTagItems();
|
||||
// Force recalculation after images and fonts are loaded
|
||||
setTimeout(() => {
|
||||
fixViewportWidth();
|
||||
adjustTagItems();
|
||||
}, 500);
|
||||
});
|
||||
|
||||
// Add touch support for hover effects
|
||||
const isTouchDevice = 'ontouchstart' in window || navigator.maxTouchPoints > 0;
|
||||
|
||||
if (isTouchDevice) {
|
||||
const articles = document.querySelectorAll('article');
|
||||
|
||||
articles.forEach((article) => {
|
||||
article.addEventListener('touchstart', () => {
|
||||
article.classList.add('is-touched');
|
||||
});
|
||||
|
||||
article.addEventListener('touchend', () => {
|
||||
setTimeout(() => {
|
||||
article.classList.remove('is-touched');
|
||||
}, 300);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Add touch support for mobile devices
|
||||
const addTouchSupport = () => {
|
||||
const tagItems = document.querySelectorAll('.theme-ripple');
|
||||
|
||||
tagItems.forEach((item) => {
|
||||
item.addEventListener(
|
||||
'touchstart',
|
||||
() => {
|
||||
item.classList.add('touch-active');
|
||||
},
|
||||
{ passive: true }
|
||||
);
|
||||
|
||||
item.addEventListener(
|
||||
'touchend',
|
||||
() => {
|
||||
setTimeout(() => {
|
||||
item.classList.remove('touch-active');
|
||||
}, 150);
|
||||
},
|
||||
{ passive: true }
|
||||
);
|
||||
|
||||
// Cancel active state if touch moves away
|
||||
item.addEventListener(
|
||||
'touchmove',
|
||||
(e) => {
|
||||
const touch = e.touches[0];
|
||||
const rect = item.getBoundingClientRect();
|
||||
|
||||
if (
|
||||
touch.clientX < rect.left ||
|
||||
touch.clientX > rect.right ||
|
||||
touch.clientY < rect.top ||
|
||||
touch.clientY > rect.bottom
|
||||
) {
|
||||
item.classList.remove('touch-active');
|
||||
}
|
||||
},
|
||||
{ passive: true }
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
addTouchSupport();
|
||||
|
||||
// Fix for iOS Safari and other mobile browsers
|
||||
if (/iPhone|iPad|iPod|Android/.test(navigator.userAgent)) {
|
||||
document.documentElement.style.setProperty(
|
||||
'--safe-area-inset-bottom',
|
||||
'env(safe-area-inset-bottom)'
|
||||
);
|
||||
|
||||
// Fix for mobile viewport height issues
|
||||
const setVh = () => {
|
||||
const vh = window.innerHeight * 0.01;
|
||||
document.documentElement.style.setProperty('--vh', `${vh}px`);
|
||||
};
|
||||
|
||||
setVh();
|
||||
window.addEventListener('resize', setVh);
|
||||
window.addEventListener('orientationchange', () => {
|
||||
// Wait for orientation change to complete
|
||||
setTimeout(() => {
|
||||
setVh();
|
||||
fixViewportWidth();
|
||||
}, 100);
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style>
|
||||
/* Content reveal animations */
|
||||
.hero-text h1,
|
||||
.hero-text span,
|
||||
.hero-text p,
|
||||
.hero-text ~ div,
|
||||
article.group {
|
||||
opacity: 0;
|
||||
transform: translateY(20px);
|
||||
transition:
|
||||
opacity 0.8s ease,
|
||||
transform 0.8s ease;
|
||||
}
|
||||
|
||||
.animate-reveal {
|
||||
opacity: 1 !important;
|
||||
transform: translateY(0) !important;
|
||||
}
|
||||
|
||||
/* Search container hover effect */
|
||||
.search-container:hover .search-pulse {
|
||||
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0%,
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
50% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Shadow for dark mode */
|
||||
:global(.dark) .tag-cloud {
|
||||
box-shadow:
|
||||
0 0 0 1px rgba(255, 255, 255, 0.05),
|
||||
0 2px 4px rgba(0, 0, 0, 0.1),
|
||||
0 4px 8px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
/* Input focus animation */
|
||||
input:focus + div .search-pulse {
|
||||
animation: pulse 1.5s cubic-bezier(0.4, 0, 0.6, 1) infinite;
|
||||
}
|
||||
|
||||
/* Base styles */
|
||||
.tag-cloud {
|
||||
box-shadow:
|
||||
0 0 0 1px rgba(0, 0, 0, 0.03),
|
||||
0 2px 4px rgba(0, 0, 0, 0.03),
|
||||
0 4px 8px rgba(0, 0, 0, 0.05);
|
||||
transform-style: preserve-3d;
|
||||
perspective: 1000px;
|
||||
transition: all var(--theme-transition);
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
box-sizing: border-box;
|
||||
margin-left: 0 !important;
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
|
||||
/* Fix for horizontal overflow */
|
||||
:global(html),
|
||||
:global(body) {
|
||||
overflow-x: hidden;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
:global(.max-w-6xl) {
|
||||
max-width: 100% !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
/* Micro screens (below 240px) */
|
||||
@media (max-width: 239px) {
|
||||
.tag-cloud {
|
||||
padding: 0.5rem !important;
|
||||
margin: 0 !important;
|
||||
border-radius: 0.25rem !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.tag-cloud h2 {
|
||||
font-size: 0.875rem !important;
|
||||
margin-bottom: 0.375rem !important;
|
||||
}
|
||||
|
||||
.grid {
|
||||
grid-template-columns: repeat(1, minmax(0, 1fr)) !important;
|
||||
gap: 0.375rem !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.micro-screen .flex {
|
||||
padding: 0.25rem !important;
|
||||
}
|
||||
|
||||
.micro-screen h3 {
|
||||
font-size: 0.625rem !important;
|
||||
}
|
||||
|
||||
.micro-screen p {
|
||||
font-size: 0.5rem !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* Extra extra extra small screens (240px-279px) */
|
||||
@media (min-width: 240px) and (max-width: 279px) {
|
||||
.xxxs\:grid-cols-2 {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.xxxs\:px-2 {
|
||||
padding-left: 0.5rem;
|
||||
padding-right: 0.5rem;
|
||||
}
|
||||
|
||||
.xxxs\:py-2 {
|
||||
padding-top: 0.5rem;
|
||||
padding-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.xxxs\:w-6 {
|
||||
width: 1.5rem;
|
||||
}
|
||||
|
||||
.xxxs\:h-6 {
|
||||
height: 1.5rem;
|
||||
}
|
||||
|
||||
.xxxs\:text-xs {
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
|
||||
.xxxs\:gap-2 {
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.xxxs\:text-\[9px\] {
|
||||
font-size: 9px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Extra extra small screens (280px-359px) */
|
||||
@media (min-width: 280px) {
|
||||
.xxs\:grid-cols-2 {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.xxs\:px-2 {
|
||||
padding-left: 0.5rem;
|
||||
padding-right: 0.5rem;
|
||||
}
|
||||
|
||||
.xxs\:py-2 {
|
||||
padding-top: 0.5rem;
|
||||
padding-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.xxs\:w-6 {
|
||||
width: 1.5rem;
|
||||
}
|
||||
|
||||
.xxs\:h-6 {
|
||||
height: 1.5rem;
|
||||
}
|
||||
|
||||
.xxs\:text-xs {
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
|
||||
.xxs\:gap-2 {
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.xxs\:text-\[9px\] {
|
||||
font-size: 9px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Extra small screens (360px-639px) */
|
||||
@media (min-width: 360px) {
|
||||
.xs\:grid-cols-3 {
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.xs\:px-2 {
|
||||
padding-left: 0.5rem;
|
||||
padding-right: 0.5rem;
|
||||
}
|
||||
|
||||
.xs\:py-2 {
|
||||
padding-top: 0.5rem;
|
||||
padding-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.xs\:w-7 {
|
||||
width: 1.75rem;
|
||||
}
|
||||
|
||||
.xs\:h-7 {
|
||||
height: 1.75rem;
|
||||
}
|
||||
|
||||
.xs\:text-xs {
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
|
||||
.xs\:text-sm {
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
.xs\:gap-2 {
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.xs\:text-\[10px\] {
|
||||
font-size: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Hide scrollbar but keep functionality */
|
||||
.hide-scrollbar {
|
||||
-ms-overflow-style: none;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
|
||||
.hide-scrollbar::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Line clamp for descriptions */
|
||||
.line-clamp-2 {
|
||||
display: -webkit-box;
|
||||
@@ -833,13 +340,4 @@ const years = Object.keys(postsByYear).sort((a, b) => b - a);
|
||||
transform 0.15s ease-in-out,
|
||||
opacity 0.15s ease-in-out !important;
|
||||
}
|
||||
|
||||
/* Fix for iOS Safari notch */
|
||||
@supports (padding: max(0px)) {
|
||||
.tag-cloud {
|
||||
padding-left: max(0.75rem, env(safe-area-inset-left));
|
||||
padding-right: max(0.75rem, env(safe-area-inset-right));
|
||||
padding-bottom: max(0.75rem, env(safe-area-inset-bottom));
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@@ -7,7 +7,6 @@ import directus from '../../lib/directus';
|
||||
import { readItems, readSingleton } from '@directus/sdk';
|
||||
|
||||
const global = await directus.request(readSingleton('global'));
|
||||
|
||||
const posts = await directus.request(
|
||||
readItems('posts', {
|
||||
fields: ['*'],
|
||||
@@ -18,11 +17,11 @@ const posts = await directus.request(
|
||||
const recentPosts = posts
|
||||
.sort((a, b) => b.published_date.getTime() - a.published_date.getTime())
|
||||
.slice(0, 3);
|
||||
|
||||
const allTags = [...new Set(posts.flatMap((post) => post.tags || []))].slice(0, 5);
|
||||
---
|
||||
|
||||
<Layout title=`Home | ${global.name}`>
|
||||
<!-- Header section -->
|
||||
<section
|
||||
class="theme-transition-all px-4 py-10 sm:px-6 sm:py-16 md:py-20"
|
||||
transition:animate="slide"
|
||||
@@ -53,7 +52,7 @@ const allTags = [...new Set(posts.flatMap((post) => post.tags || []))].slice(0,
|
||||
>
|
||||
<a
|
||||
href="/about"
|
||||
class="theme-transition-color group relative inline-flex min-h-[44px] items-center gap-2 text-sm font-medium text-zinc-900 transition-all duration-300 hover:text-zinc-700 dark:text-zinc-400 dark:hover:text-zinc-100"
|
||||
class="theme-transition-color group relative inline-flex min-h-[44px] items-center gap-2 text-sm font-medium text-zinc-600 transition-all duration-300 hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-zinc-100"
|
||||
>
|
||||
<span>More about me</span>
|
||||
<svg
|
||||
@@ -77,7 +76,7 @@ const allTags = [...new Set(posts.flatMap((post) => post.tags || []))].slice(0,
|
||||
|
||||
<!-- Featured post section -->
|
||||
<section
|
||||
class="theme-transition-all border-t border-zinc-100 px-4 py-10 sm:px-6 sm:py-12 md:py-16 dark:border-zinc-800"
|
||||
class="theme-transition-all border-t border-zinc-200 px-4 py-10 sm:px-6 sm:py-12 md:py-16 dark:border-zinc-800"
|
||||
>
|
||||
<div class="mx-auto max-w-3xl">
|
||||
<div
|
||||
@@ -90,7 +89,7 @@ const allTags = [...new Set(posts.flatMap((post) => post.tags || []))].slice(0,
|
||||
</h2>
|
||||
<a
|
||||
href="/blog"
|
||||
class="theme-transition-color group relative flex min-h-[44px] items-center justify-center self-center text-sm font-medium text-zinc-900 hover:text-zinc-700 sm:self-auto dark:text-zinc-400 dark:hover:text-zinc-100"
|
||||
class="theme-transition-color group relative flex min-h-[44px] items-center justify-center self-center text-sm font-medium text-zinc-600 transition-all duration-300 hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-zinc-100"
|
||||
>
|
||||
<span class="flex items-center gap-1">
|
||||
View all posts
|
||||
@@ -111,12 +110,12 @@ const allTags = [...new Set(posts.flatMap((post) => post.tags || []))].slice(0,
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Grid for mobile layout -->
|
||||
<!-- Post grid -->
|
||||
<div class="grid grid-cols-1 gap-6 sm:grid-cols-2 sm:gap-8 md:gap-12 lg:grid-cols-3">
|
||||
{
|
||||
recentPosts.map((post, index) => (
|
||||
<article class="hover-3d theme-transition-element group relative mx-auto flex w-full max-w-sm flex-col items-start sm:mx-0">
|
||||
<div class="theme-transition-all absolute -inset-x-4 -inset-y-6 z-0 border border-zinc-200 bg-white/50 transition-all duration-300 group-hover:bg-zinc-50 sm:-inset-x-6 sm:rounded-2xl dark:border-zinc-800 dark:bg-zinc-900/50 dark:group-hover:bg-zinc-800/70" />
|
||||
<article class="theme-transition-element group relative mx-auto flex w-full max-w-sm flex-col items-start sm:mx-0">
|
||||
<div class="theme-transition-all absolute -inset-x-4 -inset-y-6 z-0 border border-zinc-300 bg-white/50 transition-all duration-300 group-hover:bg-zinc-50 sm:-inset-x-6 sm:rounded-2xl dark:border-zinc-800 dark:bg-zinc-900/50 dark:group-hover:bg-zinc-800/70" />
|
||||
|
||||
{post.image && (
|
||||
<div class="relative z-10 mb-4 aspect-video w-full overflow-hidden rounded-lg">
|
||||
@@ -180,16 +179,16 @@ const allTags = [...new Set(posts.flatMap((post) => post.tags || []))].slice(0,
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Topics section -->
|
||||
<!-- Tags section -->
|
||||
{
|
||||
allTags.length > 0 && (
|
||||
<section class="theme-transition-all border-t border-zinc-100 px-4 py-10 sm:px-6 sm:py-12 md:py-16 dark:border-zinc-800">
|
||||
<section class="theme-transition-all border-t border-zinc-200 px-4 py-10 sm:px-6 sm:py-12 md:py-16 dark:border-zinc-800">
|
||||
<div class="mx-auto max-w-3xl">
|
||||
<h2 class="theme-transition-color mb-6 text-center text-xl font-bold tracking-tight text-zinc-900 sm:mb-8 sm:text-left sm:text-2xl md:text-3xl dark:text-zinc-100">
|
||||
Popular Tags
|
||||
</h2>
|
||||
|
||||
<div class="hover-3d mx-auto grid max-w-xs grid-cols-1 gap-3 sm:max-w-none sm:grid-cols-2 sm:gap-4 md:grid-cols-3">
|
||||
<div class="mx-auto grid max-w-xs grid-cols-1 gap-3 sm:max-w-none sm:grid-cols-2 sm:gap-4 md:grid-cols-3">
|
||||
{allTags.map((tag) => {
|
||||
const tagCount = posts.filter((post) => post.tags && post.tags.includes(tag)).length;
|
||||
return (
|
||||
@@ -201,7 +200,7 @@ const allTags = [...new Set(posts.flatMap((post) => post.tags || []))].slice(0,
|
||||
<span class="theme-transition-color mr-2 text-sm font-medium text-zinc-900 dark:text-zinc-100">
|
||||
#{tag}
|
||||
</span>
|
||||
<span class="theme-transition-all shrink-0 rounded-full bg-zinc-100 px-2 py-0.5 text-xs text-zinc-500 dark:bg-zinc-800 dark:text-zinc-400">
|
||||
<span class="theme-transition-all shrink-0 rounded-full bg-zinc-100 px-2.5 py-0.5 text-xs font-medium text-zinc-600 transition-colors hover:bg-zinc-200 dark:bg-zinc-800 dark:text-zinc-400 dark:hover:bg-zinc-700">
|
||||
{tagCount} {tagCount === 1 ? 'post' : 'posts'}
|
||||
</span>
|
||||
</div>
|
||||
@@ -219,135 +218,7 @@ const allTags = [...new Set(posts.flatMap((post) => post.tags || []))].slice(0,
|
||||
</Layout>
|
||||
|
||||
<script>
|
||||
// Add hover effect for cards on touch devices
|
||||
document.addEventListener('astro:page-load', () => {
|
||||
const isTouchDevice = 'ontouchstart' in window || navigator.maxTouchPoints > 0;
|
||||
|
||||
if (isTouchDevice) {
|
||||
const cards = document.querySelectorAll('.hover-3d');
|
||||
|
||||
cards.forEach((card) => {
|
||||
card.addEventListener('touchstart', () => {
|
||||
card.classList.add('is-touched');
|
||||
});
|
||||
|
||||
card.addEventListener('touchend', () => {
|
||||
setTimeout(() => {
|
||||
card.classList.remove('is-touched');
|
||||
}, 300);
|
||||
});
|
||||
});
|
||||
|
||||
// Disable hover animations on touch devices
|
||||
document.documentElement.classList.add('touch-device');
|
||||
}
|
||||
|
||||
// Viewport height fix for mobile browsers
|
||||
const setVh = () => {
|
||||
const vh = window.innerHeight * 0.01;
|
||||
document.documentElement.style.setProperty('--vh', `${vh}px`);
|
||||
};
|
||||
|
||||
// Set initial value
|
||||
setVh();
|
||||
|
||||
// Update on resize and scroll to prevent content shifting
|
||||
window.addEventListener('resize', setVh);
|
||||
|
||||
// Use a debounced scroll handler to prevent performance issues
|
||||
let scrollTimeout;
|
||||
window.addEventListener('scroll', () => {
|
||||
if (scrollTimeout) {
|
||||
window.cancelAnimationFrame(scrollTimeout);
|
||||
}
|
||||
|
||||
scrollTimeout = window.requestAnimationFrame(() => {
|
||||
// Lock width during scroll
|
||||
document.body.style.width = '100%';
|
||||
document.body.style.overflowX = 'hidden';
|
||||
});
|
||||
});
|
||||
|
||||
// Fix for iOS Safari address bar height changes
|
||||
if (/iPhone|iPad|iPod/.test(navigator.userAgent)) {
|
||||
// Force the layout to use the initial viewport size
|
||||
document.documentElement.style.setProperty('--initial-vh', `${window.innerHeight * 0.01}px`);
|
||||
|
||||
// Apply fixed height to sections to prevent resizing
|
||||
const sections = document.querySelectorAll('section');
|
||||
sections.forEach((section) => {
|
||||
section.style.width = '100%';
|
||||
});
|
||||
}
|
||||
|
||||
// Theme change handler that preserves scroll position and provides smoother transitions
|
||||
document.addEventListener('themeChanged', () => {
|
||||
// Store current scroll position
|
||||
const scrollPosition = window.scrollY;
|
||||
|
||||
// Create a temporary overlay for smoother transition
|
||||
const overlay = document.createElement('div');
|
||||
overlay.style.cssText = `
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background-color: ${document.documentElement.classList.contains('dark') ? 'rgba(255,255,255,0.05)' : 'rgba(0,0,0,0.05)'};
|
||||
z-index: 9999;
|
||||
pointer-events: none;
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease;
|
||||
`;
|
||||
document.body.appendChild(overlay);
|
||||
|
||||
// Fade in overlay
|
||||
requestAnimationFrame(() => {
|
||||
overlay.style.opacity = '0.5';
|
||||
|
||||
// Update theme-transition elements without forcing reflow of entire page
|
||||
requestAnimationFrame(() => {
|
||||
document
|
||||
.querySelectorAll(
|
||||
'.theme-transition-all, .theme-transition-bg, .theme-transition-color'
|
||||
)
|
||||
.forEach((el) => {
|
||||
// Apply a subtle animation instead of a hard reset
|
||||
el.style.transition = 'all 0.5s ease';
|
||||
});
|
||||
|
||||
// Fade out overlay after transition completes
|
||||
setTimeout(() => {
|
||||
overlay.style.opacity = '0';
|
||||
setTimeout(() => {
|
||||
overlay.remove();
|
||||
}, 300);
|
||||
}, 300);
|
||||
});
|
||||
});
|
||||
|
||||
// Restore scroll position (prevents jumping to top)
|
||||
if (scrollPosition > 0) {
|
||||
setTimeout(() => {
|
||||
window.scrollTo({
|
||||
top: scrollPosition,
|
||||
behavior: 'auto', // Use 'auto' to prevent animation
|
||||
});
|
||||
}, 10);
|
||||
}
|
||||
});
|
||||
|
||||
// Fix theme inconsistency issues by checking theme on visibility change
|
||||
document.addEventListener('visibilitychange', () => {
|
||||
if (document.visibilityState === 'visible') {
|
||||
const storedTheme = localStorage.getItem('theme');
|
||||
const currentThemeIsDark = document.documentElement.classList.contains('dark');
|
||||
|
||||
if (storedTheme === 'dark' && !currentThemeIsDark) {
|
||||
document.documentElement.classList.add('dark');
|
||||
} else if (storedTheme === 'light' && currentThemeIsDark) {
|
||||
document.documentElement.classList.remove('dark');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Add smooth reveal animations for content after loading
|
||||
const animateContent = () => {
|
||||
// Animate hero section
|
||||
@@ -389,53 +260,3 @@ const allTags = [...new Set(posts.flatMap((post) => post.tags || []))].slice(0,
|
||||
animateContent();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style>
|
||||
/* Fix for theme transition issues */
|
||||
:global(:root) {
|
||||
--theme-transition-duration: 0.5s;
|
||||
--theme-transition-timing: ease;
|
||||
}
|
||||
|
||||
:global(html),
|
||||
:global(body) {
|
||||
transition: background-color var(--theme-transition-duration) var(--theme-transition-timing);
|
||||
}
|
||||
|
||||
:global(.theme-transition-all) {
|
||||
transition: all var(--theme-transition-duration) var(--theme-transition-timing);
|
||||
}
|
||||
|
||||
:global(.theme-transition-bg) {
|
||||
transition: background-color var(--theme-transition-duration) var(--theme-transition-timing);
|
||||
}
|
||||
|
||||
:global(.theme-transition-color) {
|
||||
transition: color var(--theme-transition-duration) var(--theme-transition-timing);
|
||||
}
|
||||
|
||||
/* Remove the forced transition disabling which causes flickering */
|
||||
:global(.theme-switching),
|
||||
:global(.theme-switching *) {
|
||||
/* Use a subtle transition instead of none */
|
||||
transition-duration: 0.3s !important;
|
||||
}
|
||||
|
||||
/* Content reveal animations */
|
||||
.hero-text span,
|
||||
.hero-text + p,
|
||||
.hero-text ~ div,
|
||||
article.group,
|
||||
a.group.flex.flex-col {
|
||||
opacity: 0;
|
||||
transform: translateY(20px);
|
||||
transition:
|
||||
opacity 0.8s ease,
|
||||
transform 0.8s ease;
|
||||
}
|
||||
|
||||
.animate-reveal {
|
||||
opacity: 1 !important;
|
||||
transform: translateY(0) !important;
|
||||
}
|
||||
</style>
|
||||
|
@@ -32,13 +32,10 @@ export async function getStaticPaths() {
|
||||
const { tag } = Astro.params as { tag: string };
|
||||
const { posts = [] } = Astro.props;
|
||||
|
||||
console.log(`Tag: ${tag}, Number of posts: ${posts.length}`);
|
||||
|
||||
const sortedPosts =
|
||||
posts && posts.length > 0
|
||||
? [...posts].sort((a, b) => b.published_date.valueOf() - a.published_date.valueOf())
|
||||
: [];
|
||||
console.log(`Sorted posts length: ${sortedPosts.length}`);
|
||||
|
||||
const relatedTags = [
|
||||
...new Set(sortedPosts.flatMap((post) => post.tags || []).filter((t) => t !== tag)),
|
||||
@@ -308,7 +305,7 @@ const relatedTags = [
|
||||
);
|
||||
});
|
||||
|
||||
// Animate posts with staggered delay
|
||||
// Animate posts
|
||||
const articles = document.querySelectorAll('article.group');
|
||||
articles.forEach((article, index) => {
|
||||
setTimeout(
|
||||
@@ -321,52 +318,10 @@ const relatedTags = [
|
||||
};
|
||||
|
||||
animateContent();
|
||||
|
||||
// Add hover effect for cards on touch devices
|
||||
const isTouchDevice = 'ontouchstart' in window || navigator.maxTouchPoints > 0;
|
||||
|
||||
if (isTouchDevice) {
|
||||
const cards = document.querySelectorAll('.hover-3d');
|
||||
|
||||
cards.forEach((card) => {
|
||||
card.addEventListener('touchstart', () => {
|
||||
card.classList.add('is-touched');
|
||||
});
|
||||
|
||||
card.addEventListener('touchend', () => {
|
||||
setTimeout(() => {
|
||||
card.classList.remove('is-touched');
|
||||
}, 300);
|
||||
});
|
||||
});
|
||||
|
||||
// Disable hover animations on touch devices
|
||||
document.documentElement.classList.add('touch-device');
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style>
|
||||
/* Grid pattern background */
|
||||
.bg-grid-pattern {
|
||||
background-size: 30px 30px;
|
||||
background-image: radial-gradient(circle, rgba(0, 0, 0, 0.05) 1px, transparent 1px);
|
||||
}
|
||||
|
||||
:global(.dark) .bg-grid-pattern {
|
||||
background-image: radial-gradient(circle, rgba(255, 255, 255, 0.05) 1px, transparent 1px);
|
||||
}
|
||||
|
||||
/* Hide scrollbar but keep functionality */
|
||||
.hide-scrollbar {
|
||||
-ms-overflow-style: none;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
|
||||
.hide-scrollbar::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Animated underline */
|
||||
@keyframes expand {
|
||||
from {
|
||||
@@ -381,19 +336,6 @@ const relatedTags = [
|
||||
animation: expand 1s ease-out forwards;
|
||||
}
|
||||
|
||||
/* Content reveal animations */
|
||||
.hero-text h1,
|
||||
.hero-text span,
|
||||
.hero-text p,
|
||||
.hero-text ~ div,
|
||||
article.group {
|
||||
opacity: 0;
|
||||
transform: translateY(20px);
|
||||
transition:
|
||||
opacity 0.8s ease,
|
||||
transform 0.8s ease;
|
||||
}
|
||||
|
||||
.animate-reveal {
|
||||
opacity: 1 !important;
|
||||
transform: translateY(0) !important;
|
||||
@@ -413,11 +355,4 @@ const relatedTags = [
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* Responsive adjustments */
|
||||
@media (max-width: 640px) {
|
||||
.animate-blob {
|
||||
animation-duration: 10s;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@@ -132,7 +132,22 @@ button {
|
||||
transition: all 0.5s ease;
|
||||
}
|
||||
|
||||
a.hover:hover,
|
||||
button:hover {
|
||||
transform: translateY(-2px);
|
||||
/* Content reveal animations */
|
||||
.hero-text h1,
|
||||
.hero-text span,
|
||||
.hero-text p,
|
||||
.hero-text + p,
|
||||
.hero-text ~ div,
|
||||
article.group,
|
||||
a.group.flex.flex-col {
|
||||
opacity: 0;
|
||||
transform: translateY(20px);
|
||||
transition:
|
||||
opacity 0.8s ease,
|
||||
transform 0.8s ease;
|
||||
}
|
||||
|
||||
.animate-reveal {
|
||||
opacity: 1 !important;
|
||||
transform: translateY(0) !important;
|
||||
}
|
||||
|
@@ -23,7 +23,7 @@ const iconSets = {
|
||||
si: SiIcons,
|
||||
};
|
||||
|
||||
const DynamicIcon = ({ name, set = 'fa' }: { name: string; set: string }) => {
|
||||
const DynamicIcon = ({ name, set = 'fa' }: { name: string; set?: string }) => {
|
||||
let IconComponent = FaIcons.FaAlignCenter;
|
||||
|
||||
if (name.startsWith('Fa')) {
|
||||
|
Reference in New Issue
Block a user