Compare commits

..

19 Commits

Author SHA1 Message Date
1a8473b964 feat: release 2.12.0
All checks were successful
test-build / guarddog (push) Successful in 1m11s
renovate / renovate (push) Successful in 1m19s
release-image-gitea / build (push) Successful in 2m28s
release-image-harbor / build (push) Successful in 2m19s
test-build / build (push) Successful in 5m33s
release-image-gitea / release (push) Successful in 7m39s
release-image-harbor / release (push) Successful in 7m16s
2026-02-16 23:08:06 -06:00
18211ad485 feat: update BaseHead
All checks were successful
renovate / renovate (push) Successful in 1m33s
test-build / build (push) Successful in 1m40s
test-build / guarddog (push) Successful in 1m59s
2026-02-16 23:04:42 -06:00
429cf94023 feat: organize to consistency pass on sections 2026-02-16 22:57:39 -06:00
0497731c45 feat: organize to consistency 2026-02-16 22:38:45 -06:00
6c2c6da91d feat: organize to consistency 2026-02-16 22:36:24 -06:00
19e17ea947 feat: remove option 2026-02-16 22:34:57 -06:00
3d9120c570 fix: remove unused property 2026-02-16 22:34:14 -06:00
875b8a7f47 fix: remove border from blog cards 2026-02-16 22:32:12 -06:00
1ddc76ae69 fix: remove errant semicolon 2026-02-16 22:30:04 -06:00
6423ffba63 feat: refactor blog components 2026-02-16 22:26:53 -06:00
505670dbf8 feat: remove unused packages
Some checks are pending
test-build / guarddog (push) Successful in 34s
test-build / build (push) Successful in 1m6s
release-image-harbor / build (push) Successful in 1m1s
release-image-harbor / release (push) Successful in 2m27s
release-image-gitea / build (push) Successful in 1m0s
release-image-gitea / release (push) Successful in 6m21s
renovate / renovate (push) Has started running
2026-02-16 00:28:58 -06:00
b3d7e7af2b chore(deps): update deps
All checks were successful
test-build / guarddog (push) Successful in 31s
renovate / renovate (push) Successful in 1m0s
test-build / build (push) Successful in 1m24s
2026-02-16 00:21:43 -06:00
440c95224d feat: release 2.11.0 2026-02-16 00:20:26 -06:00
b9ee82e9d8 Merge pull request 'chore(deps): update dependency eslint-plugin-astro to v1.6.0' (#340) from renovate/eslint-plugin-astro-1.x-lockfile into main
All checks were successful
test-build / guarddog (push) Successful in 33s
renovate / renovate (push) Successful in 49s
test-build / build (push) Successful in 1m26s
Reviewed-on: #340
2026-02-16 06:20:15 +00:00
3af9f08b7c chore(deps): update dependency eslint-plugin-astro to v1.6.0
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
test-build / guarddog (pull_request) Successful in 1m20s
test-build / build (pull_request) Successful in 2m18s
2026-02-16 06:09:50 +00:00
0bd56b172f Merge pull request 'chore(deps): update dependency @swup/astro to v1.8.0' (#339) from renovate/swup-astro-1.x-lockfile into main
All checks were successful
test-build / guarddog (push) Successful in 54s
renovate / renovate (push) Successful in 1m11s
test-build / build (push) Successful in 2m34s
Reviewed-on: #339
2026-02-16 06:08:50 +00:00
ebf70bd747 chore(deps): update dependency @swup/astro to v1.8.0
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
test-build / guarddog (pull_request) Successful in 38s
test-build / build (pull_request) Successful in 1m37s
2026-02-16 05:57:02 +00:00
9c5e9b6a5b Merge pull request 'chore(deps): update dependency @eslint-react/eslint-plugin to v2.13.0' (#338) from renovate/eslint-react-eslint-plugin-2.x-lockfile into main
All checks were successful
test-build / guarddog (push) Successful in 51s
test-build / build (push) Successful in 1m42s
renovate / renovate (push) Successful in 2m17s
Reviewed-on: #338
2026-02-16 05:55:20 +00:00
568f9e5164 chore(deps): update dependency @eslint-react/eslint-plugin to v2.13.0
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
test-build / guarddog (pull_request) Successful in 43s
test-build / build (pull_request) Successful in 1m50s
2026-02-16 05:40:13 +00:00
38 changed files with 680 additions and 726 deletions

View File

@@ -27,7 +27,7 @@ ENV SITE_URL=https://www.alexlebens.dev
ENV DIRECTUS_URL=https://directus.alexlebens.net ENV DIRECTUS_URL=https://directus.alexlebens.net
ENV PORT=4321 ENV PORT=4321
LABEL version="2.10.1" LABEL version="2.12.0"
LABEL description="Astro based personal website" LABEL description="Astro based personal website"
EXPOSE $PORT EXPOSE $PORT

View File

@@ -1,7 +1,7 @@
{ {
"name": "site-profile", "name": "site-profile",
"type": "module", "type": "module",
"version": "2.10.1", "version": "2.12.0",
"homepage": "https://www.alexlebens.dev", "homepage": "https://www.alexlebens.dev",
"bugs": { "bugs": {
"url": "https://gitea.alexlebens.dev/alexlebens/site-profile/issues", "url": "https://gitea.alexlebens.dev/alexlebens/site-profile/issues",
@@ -39,18 +39,16 @@
"@iconify-json/pajamas": "^1.2.15", "@iconify-json/pajamas": "^1.2.15",
"@iconify-json/simple-icons": "^1.2.70", "@iconify-json/simple-icons": "^1.2.70",
"@playform/compress": "^0.2.1", "@playform/compress": "^0.2.1",
"@swup/astro": "^1.7.0", "@swup/astro": "^1.8.0",
"@tailwindcss/postcss": "^4.1.18", "@tailwindcss/postcss": "^4.1.18",
"@tailwindcss/vite": "^4.1.18", "@tailwindcss/vite": "^4.1.18",
"@types/react": "^19.2.14", "@types/react": "^19.2.14",
"@types/unist": "^3.0.3", "@types/unist": "^3.0.3",
"astro": "^5.17.2", "astro": "^5.17.2",
"astro-compressor": "^1.2.0",
"astro-icon": "^1.1.5", "astro-icon": "^1.1.5",
"marked": "^17.0.2", "marked": "^17.0.2",
"marked-shiki": "^1.2.1", "marked-shiki": "^1.2.1",
"mdast-util-to-string": "^4.0.0", "mdast-util-to-string": "^4.0.0",
"motion": "^12.34.0",
"preline": "^4.0.1", "preline": "^4.0.1",
"react": "^19.2.4", "react": "^19.2.4",
"react-dom": "^19.2.4", "react-dom": "^19.2.4",
@@ -62,13 +60,12 @@
"ultrahtml": "^1.6.0" "ultrahtml": "^1.6.0"
}, },
"devDependencies": { "devDependencies": {
"@eslint-react/eslint-plugin": "^2.12.4", "@eslint-react/eslint-plugin": "^2.13.0",
"@tailwindcss/forms": "^0.5.11", "@tailwindcss/forms": "^0.5.11",
"@tailwindcss/typography": "^0.5.19", "@tailwindcss/typography": "^0.5.19",
"astro-icon": "^1.1.5",
"eslint": "^10.0.0", "eslint": "^10.0.0",
"eslint-config-prettier": "^10.1.8", "eslint-config-prettier": "^10.1.8",
"eslint-plugin-astro": "^1.5.0", "eslint-plugin-astro": "^1.6.0",
"eslint-plugin-format": "^1.4.0", "eslint-plugin-format": "^1.4.0",
"eslint-plugin-react": "^7.37.5", "eslint-plugin-react": "^7.37.5",
"eslint-plugin-react-hooks": "^7.0.1", "eslint-plugin-react-hooks": "^7.0.1",

368
pnpm-lock.yaml generated
View File

@@ -45,8 +45,8 @@ importers:
specifier: ^0.2.1 specifier: ^0.2.1
version: 0.2.1(@types/node@25.2.3)(jiti@2.6.1)(rollup@2.79.2)(typescript@5.9.3)(yaml@2.8.2) version: 0.2.1(@types/node@25.2.3)(jiti@2.6.1)(rollup@2.79.2)(typescript@5.9.3)(yaml@2.8.2)
'@swup/astro': '@swup/astro':
specifier: ^1.7.0 specifier: ^1.8.0
version: 1.7.0(@types/babel__core@7.20.5) version: 1.8.0(@types/babel__core@7.20.5)
'@tailwindcss/postcss': '@tailwindcss/postcss':
specifier: ^4.1.18 specifier: ^4.1.18
version: 4.1.18 version: 4.1.18
@@ -62,9 +62,6 @@ importers:
astro: astro:
specifier: ^5.17.2 specifier: ^5.17.2
version: 5.17.2(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@2.79.2)(terser@5.44.1)(typescript@5.9.3)(yaml@2.8.2) version: 5.17.2(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@2.79.2)(terser@5.44.1)(typescript@5.9.3)(yaml@2.8.2)
astro-compressor:
specifier: ^1.2.0
version: 1.2.0
astro-icon: astro-icon:
specifier: ^1.1.5 specifier: ^1.1.5
version: 1.1.5 version: 1.1.5
@@ -77,9 +74,6 @@ importers:
mdast-util-to-string: mdast-util-to-string:
specifier: ^4.0.0 specifier: ^4.0.0
version: 4.0.0 version: 4.0.0
motion:
specifier: ^12.34.0
version: 12.34.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
preline: preline:
specifier: ^4.0.1 specifier: ^4.0.1
version: 4.0.1 version: 4.0.1
@@ -109,8 +103,8 @@ importers:
version: 1.6.0 version: 1.6.0
devDependencies: devDependencies:
'@eslint-react/eslint-plugin': '@eslint-react/eslint-plugin':
specifier: ^2.12.4 specifier: ^2.13.0
version: 2.12.4(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3) version: 2.13.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)
'@tailwindcss/forms': '@tailwindcss/forms':
specifier: ^0.5.11 specifier: ^0.5.11
version: 0.5.11(tailwindcss@4.1.18) version: 0.5.11(tailwindcss@4.1.18)
@@ -124,7 +118,7 @@ importers:
specifier: ^10.1.8 specifier: ^10.1.8
version: 10.1.8(eslint@10.0.0(jiti@2.6.1)) version: 10.1.8(eslint@10.0.0(jiti@2.6.1))
eslint-plugin-astro: eslint-plugin-astro:
specifier: ^1.5.0 specifier: ^1.6.0
version: 1.6.0(eslint@10.0.0(jiti@2.6.1)) version: 1.6.0(eslint@10.0.0(jiti@2.6.1))
eslint-plugin-format: eslint-plugin-format:
specifier: ^1.4.0 specifier: ^1.4.0
@@ -1168,40 +1162,40 @@ packages:
resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==}
engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
'@eslint-react/ast@2.12.4': '@eslint-react/ast@2.13.0':
resolution: {integrity: sha512-UNr5OsaNXfDBcIWZtahlNBjqEQeysAU4NzPqsxnogghUd7pX0aQxaQHXIOdSKTd5037PbyHIILbiimDmI/BYAQ==} resolution: {integrity: sha512-43+5gmqV3MpatTzKnu/V2i/jXjmepvwhrb9MaGQvnXHQgq9J7/C7VVCCcwp6Rvp2QHAFquAAdvQDSL8IueTpeA==}
engines: {node: '>=20.19.0'} engines: {node: '>=20.19.0'}
peerDependencies: peerDependencies:
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
typescript: '>=4.8.4 <6.0.0' typescript: '>=4.8.4 <6.0.0'
'@eslint-react/core@2.12.4': '@eslint-react/core@2.13.0':
resolution: {integrity: sha512-YAZrvc62wcMFT06twU4orNeGI8HCv9/B3X19hzU9/vhN5hCdr4HM3tl9E7qd79anjFBO30zflhpghB1zeAfjyQ==} resolution: {integrity: sha512-m62XDzkf1hpzW4sBc7uh7CT+8rBG2xz/itSADuEntlsg4YA7Jhb8hjU6VHf3wRFDwyfx5VnbV209sbJ7Azey0Q==}
engines: {node: '>=20.19.0'} engines: {node: '>=20.19.0'}
peerDependencies: peerDependencies:
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
typescript: '>=4.8.4 <6.0.0' typescript: '>=4.8.4 <6.0.0'
'@eslint-react/eff@2.12.4': '@eslint-react/eff@2.13.0':
resolution: {integrity: sha512-lpC7s9bvHvVMcYZ01Py/nUTWjhq2/VRI+ftfFfIeqPTYXuXt95V3MIS+jtTK74f3BVXqxpAFbSx81hpd7ISMeg==} resolution: {integrity: sha512-rEH2R8FQnUAblUW+v3ZHDU1wEhatbL1+U2B1WVuBXwSKqzF7BGaLqCPIU7o9vofumz5MerVfaCtJgI8jYe2Btg==}
engines: {node: '>=20.19.0'} engines: {node: '>=20.19.0'}
'@eslint-react/eslint-plugin@2.12.4': '@eslint-react/eslint-plugin@2.13.0':
resolution: {integrity: sha512-ML7EyET19pPgGOQmm5uEN9yoVkHqTtPyLMPWL2wlap9LVuFxoMK2owESkrq7mhWrXPf/NLuO4Z7lTcu5Sqv1EQ==} resolution: {integrity: sha512-iaMXpqnJCTW7317hg8L4wx7u5aIiPzZ+d1p59X8wXFgMHzFX4hNu4IfV8oygyjmWKdLsjKE9sEpv/UYWczlb+A==}
engines: {node: '>=20.19.0'} engines: {node: '>=20.19.0'}
peerDependencies: peerDependencies:
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
typescript: '>=4.8.4 <6.0.0' typescript: '>=4.8.4 <6.0.0'
'@eslint-react/shared@2.12.4': '@eslint-react/shared@2.13.0':
resolution: {integrity: sha512-a6qV2cQzxH3EFPlc2MU1/13D6J+LwlzUVTQ7vGAEKBHNEIxIwXBSdah8MGU8TQp/3+12oVMIm6FK71yZOjwqkA==} resolution: {integrity: sha512-IOloCqrZ7gGBT4lFf9+0/wn7TfzU7JBRjYwTSyb9SDngsbeRrtW95ZpgUpS8/jen1wUEm6F08duAooTZ2FtsWA==}
engines: {node: '>=20.19.0'} engines: {node: '>=20.19.0'}
peerDependencies: peerDependencies:
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
typescript: '>=4.8.4 <6.0.0' typescript: '>=4.8.4 <6.0.0'
'@eslint-react/var@2.12.4': '@eslint-react/var@2.13.0':
resolution: {integrity: sha512-NITTpD0fNPVmFpiTwP4PuyLblhuKvMWDU36bIoQL+Xh7xxcCc+lbiUCCOQiOzFgz+l36JhnOAjoRJ4rnP3yDUA==} resolution: {integrity: sha512-dM+QaeiHR16qPQoJYg205MkdHYSWVa2B7ore5OFpOPlSwqDV3tLW7I+475WjbK7potq5QNPTxRa7VLp9FGeQqA==}
engines: {node: '>=20.19.0'} engines: {node: '>=20.19.0'}
peerDependencies: peerDependencies:
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
@@ -1429,13 +1423,9 @@ packages:
cpu: [x64] cpu: [x64]
os: [win32] os: [win32]
'@isaacs/balanced-match@4.0.1': '@isaacs/cliui@9.0.0':
resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} resolution: {integrity: sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg==}
engines: {node: 20 || >=22} engines: {node: '>=18'}
'@isaacs/brace-expansion@5.0.1':
resolution: {integrity: sha512-WMz71T1JS624nWj2n2fnYAuPovhv7EUhk69R6i9dsVyzxt5eM3bjwvgk9L+APE1TRscGysAVMANkB0jh0LQZrQ==}
engines: {node: 20 || >=22}
'@isaacs/fs-minipass@4.0.1': '@isaacs/fs-minipass@4.0.1':
resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==}
@@ -1747,8 +1737,8 @@ packages:
peerDependencies: peerDependencies:
swup: ^4.0.0 swup: ^4.0.0
'@swup/astro@1.7.0': '@swup/astro@1.8.0':
resolution: {integrity: sha512-OxZskzeYkEZ4+McbwJKyD018sHNlrKQLdtHzlmNjivrzQY/dB7ncnWqDs3d4IkA7Y+ydNjpwBqpR/asjDhTiag==} resolution: {integrity: sha512-FI8/jNXgyUoWpnOgdB3MOUobRtRzedKBE8+qbBH5c8CE4q9Ni/GHPGrXK/0xG+g1ZiIQuTF3OXRvTLNVouiBig==}
'@swup/body-class-plugin@3.3.0': '@swup/body-class-plugin@3.3.0':
resolution: {integrity: sha512-4h/6mAgDd0+ml8Gc2kX8tikIR0HZZLF+WTnfm0JTVrGDw74bgEBenbsaWFfIS+gn4RWKZdWBUOfaZ+Im5J7Gvw==} resolution: {integrity: sha512-4h/6mAgDd0+ml8Gc2kX8tikIR0HZZLF+WTnfm0JTVrGDw74bgEBenbsaWFfIS+gn4RWKZdWBUOfaZ+Im5J7Gvw==}
@@ -2153,8 +2143,8 @@ packages:
ajv@6.12.6: ajv@6.12.6:
resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
ajv@8.17.1: ajv@8.18.0:
resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} resolution: {integrity: sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==}
ansi-align@3.0.1: ansi-align@3.0.1:
resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==} resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==}
@@ -2231,10 +2221,6 @@ packages:
resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
astro-compressor@1.2.0:
resolution: {integrity: sha512-Y0UWW/AjyLcHlRhCK9yUqy0kg4qZHd54kDIMY4C/1huS6pSVZNsMY7a3Jk7o5RjytIkVaLDDkcUzR8SgipBH8g==}
engines: {node: '>=22'}
astro-eslint-parser@1.3.0: astro-eslint-parser@1.3.0:
resolution: {integrity: sha512-aOLc/aDR7lTWAHlytEefwn4Y6qs6uMr69DZvUx2A1AOAZsWhGB/paiRWPtVchh9wzMvLeqr+DkbENhVreVr9AQ==} resolution: {integrity: sha512-aOLc/aDR7lTWAHlytEefwn4Y6qs6uMr69DZvUx2A1AOAZsWhGB/paiRWPtVchh9wzMvLeqr+DkbENhVreVr9AQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
@@ -2316,6 +2302,10 @@ packages:
balanced-match@1.0.2: balanced-match@1.0.2:
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
balanced-match@4.0.2:
resolution: {integrity: sha512-x0K50QvKQ97fdEz2kPehIerj+YTeptKF9hyYkKf6egnwmMWAkADiO0QCzSp0R5xN8FTZgYaBfSaue46Ej62nMg==}
engines: {node: 20 || >=22}
base-64@1.0.0: base-64@1.0.0:
resolution: {integrity: sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==} resolution: {integrity: sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==}
@@ -2339,6 +2329,10 @@ packages:
brace-expansion@2.0.2: brace-expansion@2.0.2:
resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==}
brace-expansion@5.0.2:
resolution: {integrity: sha512-Pdk8c9poy+YhOgVWw1JNN22/HcivgKWwpxKq04M/jTmHyCZn12WPJebZxdjSa5TmBqISrUSgNYU3eRORljfCCw==}
engines: {node: 20 || >=22}
braces@3.0.3: braces@3.0.3:
resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
engines: {node: '>=8'} engines: {node: '>=8'}
@@ -2392,8 +2386,8 @@ packages:
caniuse-api@3.0.0: caniuse-api@3.0.0:
resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==} resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==}
caniuse-lite@1.0.30001769: caniuse-lite@1.0.30001770:
resolution: {integrity: sha512-BCfFL1sHijQlBGWBMuJyhZUhzo7wer5sVj9hqekB/7xn0Ypy+pER/edCYQm4exbXj4WiySGp40P8UuTh6w1srg==} resolution: {integrity: sha512-x/2CLQ1jHENRbHg5PSId2sXq1CIO1CISvwWAj027ltMVG2UNgW+w9oH2+HzgEIRFembL8bUlXtfbBHR1fCg2xw==}
ccount@2.0.1: ccount@2.0.1:
resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==}
@@ -2906,15 +2900,15 @@ packages:
peerDependencies: peerDependencies:
eslint: ^8.40.0 || ^9.0.0 eslint: ^8.40.0 || ^9.0.0
eslint-plugin-react-dom@2.12.4: eslint-plugin-react-dom@2.13.0:
resolution: {integrity: sha512-KxjyVB+zb8DR+knd8pTCLRFZh3Tdvkv96LYzruTbM4rKAOpHwsmJ+5/tXo5P8kgl7bMBYsHR0akbhUm+tb/MBw==} resolution: {integrity: sha512-+2IZzQ1WEFYOWatW+xvNUqmZn55YBCufzKA7hX3XQ/8eu85Mp4vnlOyNvdVHEOGhUnGuC6+9+zLK+IlEHKdKLQ==}
engines: {node: '>=20.19.0'} engines: {node: '>=20.19.0'}
peerDependencies: peerDependencies:
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
typescript: '>=4.8.4 <6.0.0' typescript: '>=4.8.4 <6.0.0'
eslint-plugin-react-hooks-extra@2.12.4: eslint-plugin-react-hooks-extra@2.13.0:
resolution: {integrity: sha512-7KiMJYYYG4K6KHd+6VtlmA/1BdUSzqcMIR3ebL47+6znYgwNatTouKOSX6V+HeQPW9IIsFfmmTvwlzWh+hsQJA==} resolution: {integrity: sha512-qIbha1nzuyhXM9SbEfrcGVqmyvQu7GAOB2sy9Y4Qo5S8nCqw4fSBxq+8lSce5Tk5Y7XzIkgHOhNyXEvUHRWFMQ==}
engines: {node: '>=20.19.0'} engines: {node: '>=20.19.0'}
peerDependencies: peerDependencies:
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
@@ -2926,8 +2920,8 @@ packages:
peerDependencies: peerDependencies:
eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0
eslint-plugin-react-naming-convention@2.12.4: eslint-plugin-react-naming-convention@2.13.0:
resolution: {integrity: sha512-VCPmN15AFFZ2fuy8OA40zumN5p12BVlEJvA/YLb6b0uiLHdCQsV6kuZwCNRRUWE6DJmJBe9k5fZW/Ww71ceQyg==} resolution: {integrity: sha512-uSd25JzSg2R4p81s3Wqck0AdwRlO9Yc+cZqTEXv7vW8exGGAM3mWnF6hgrgdqVJqBEGJIbS/Vx1r5BdKcY/MHA==}
engines: {node: '>=20.19.0'} engines: {node: '>=20.19.0'}
peerDependencies: peerDependencies:
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
@@ -2938,22 +2932,22 @@ packages:
peerDependencies: peerDependencies:
eslint: '>=9' eslint: '>=9'
eslint-plugin-react-rsc@2.12.4: eslint-plugin-react-rsc@2.13.0:
resolution: {integrity: sha512-Bp2Yy3Hk3OUcUtGPRt5z/UtODFUP2ExM1j47J4KJJghrTay/UH01vFC+T0tXQ4GXGxpXt/aJJX42DJpbz5sY6Q==} resolution: {integrity: sha512-RaftgITDLQm1zIgYyvR51sBdy4FlVaXFts5VISBaKbSUB0oqXyzOPxMHasfr9BCSjPLKus9zYe+G/Hr6rjFLXQ==}
engines: {node: '>=20.19.0'} engines: {node: '>=20.19.0'}
peerDependencies: peerDependencies:
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
typescript: '>=4.8.4 <6.0.0' typescript: '>=4.8.4 <6.0.0'
eslint-plugin-react-web-api@2.12.4: eslint-plugin-react-web-api@2.13.0:
resolution: {integrity: sha512-upmeq9d5D4wDgm+exkBAOAtWfdi5vRZGxYQhtmhXabmV2nEq/UFKT8vMkcnWNBJCpTM+bcb0YtJK6WVlM2WcdA==} resolution: {integrity: sha512-nmJbzIAte7PeAkp22CwcKEASkKi49MshSdiDGO1XuN3f4N4/8sBfDcWbQuLPde6JiuzDT/0+l7Gi8wwTHtR1kg==}
engines: {node: '>=20.19.0'} engines: {node: '>=20.19.0'}
peerDependencies: peerDependencies:
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
typescript: '>=4.8.4 <6.0.0' typescript: '>=4.8.4 <6.0.0'
eslint-plugin-react-x@2.12.4: eslint-plugin-react-x@2.13.0:
resolution: {integrity: sha512-DzVSPAOCHMawhkn30GUYCL2y89NgZk2umFTJ9RFpfoN1AejdT1T7wXysJiqzfezSpbxW0uzKSoWbjnbsTE0YPQ==} resolution: {integrity: sha512-cMNX0+ws/fWTgVxn52qAQbaFF2rqvaDAtjrPUzY6XOzPjY0rJQdR2tSlWJttz43r2yBfqu+LGvHlGpWL2wfpTQ==}
engines: {node: '>=20.19.0'} engines: {node: '>=20.19.0'}
peerDependencies: peerDependencies:
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
@@ -3071,8 +3065,8 @@ packages:
fast-uri@3.1.0: fast-uri@3.1.0:
resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==}
fast-xml-parser@5.3.5: fast-xml-parser@5.3.6:
resolution: {integrity: sha512-JeaA2Vm9ffQKp9VjvfzObuMCjUYAp5WDYhRYL5LrBPY/jUDlUtOvDfot0vKSkB9tuX885BDHjtw4fZadD95wnA==} resolution: {integrity: sha512-QNI3sAvSvaOiaMl8FYU4trnEzCwiRr8XMWgAHzlrWpTSj+QaCSvOf1h82OEP1s4hiAXhnbXSyFWCf4ldZzZRVA==}
hasBin: true hasBin: true
fastq@1.20.1: fastq@1.20.1:
@@ -3149,20 +3143,6 @@ packages:
fraction.js@5.3.4: fraction.js@5.3.4:
resolution: {integrity: sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==} resolution: {integrity: sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==}
framer-motion@12.34.0:
resolution: {integrity: sha512-+/H49owhzkzQyxtn7nZeF4kdH++I2FWrESQ184Zbcw5cEqNHYkE5yxWxcTLSj5lNx3NWdbIRy5FHqUvetD8FWg==}
peerDependencies:
'@emotion/is-prop-valid': '*'
react: ^18.0.0 || ^19.0.0
react-dom: ^18.0.0 || ^19.0.0
peerDependenciesMeta:
'@emotion/is-prop-valid':
optional: true
react:
optional: true
react-dom:
optional: true
fresh@2.0.0: fresh@2.0.0:
resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==}
engines: {node: '>= 0.8'} engines: {node: '>= 0.8'}
@@ -3569,8 +3549,8 @@ packages:
resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==}
engines: {node: '>=8'} engines: {node: '>=8'}
is-wsl@3.1.0: is-wsl@3.1.1:
resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==} resolution: {integrity: sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==}
engines: {node: '>=16'} engines: {node: '>=16'}
isarray@2.0.5: isarray@2.0.5:
@@ -3583,6 +3563,10 @@ packages:
resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==} resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
jackspeak@4.2.3:
resolution: {integrity: sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg==}
engines: {node: 20 || >=22}
jake@10.9.4: jake@10.9.4:
resolution: {integrity: sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==} resolution: {integrity: sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==}
engines: {node: '>=10'} engines: {node: '>=10'}
@@ -4003,8 +3987,8 @@ packages:
resolution: {integrity: sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==} resolution: {integrity: sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==}
hasBin: true hasBin: true
minimatch@10.1.2: minimatch@10.2.0:
resolution: {integrity: sha512-fu656aJ0n2kcXwsnwnv9g24tkU5uSmOlTjd6WyyaKm2Z+h1qmY6bAjrcaIxF/BslFqbZ8UBtbJi7KgQOZD2PTw==} resolution: {integrity: sha512-ugkC31VaVg9cF0DFVoADH12k6061zNZkZON+aX8AWsR9GhPcErkcMBceb6znR8wLERM2AkkOxy2nWRLpT9Jq5w==}
engines: {node: 20 || >=22} engines: {node: 20 || >=22}
minimatch@3.1.2: minimatch@3.1.2:
@@ -4032,26 +4016,6 @@ packages:
morphdom@2.7.8: morphdom@2.7.8:
resolution: {integrity: sha512-D/fR4xgGUyVRbdMGU6Nejea1RFzYxYtyurG4Fbv2Fi/daKlWKuXGLOdXtl+3eIwL110cI2hz1ZojGICjjFLgTg==} resolution: {integrity: sha512-D/fR4xgGUyVRbdMGU6Nejea1RFzYxYtyurG4Fbv2Fi/daKlWKuXGLOdXtl+3eIwL110cI2hz1ZojGICjjFLgTg==}
motion-dom@12.34.0:
resolution: {integrity: sha512-Lql3NuEcScRDxTAO6GgUsRHBZOWI/3fnMlkMcH5NftzcN37zJta+bpbMAV9px4Nj057TuvRooMK7QrzMCgtz6Q==}
motion-utils@12.29.2:
resolution: {integrity: sha512-G3kc34H2cX2gI63RqU+cZq+zWRRPSsNIOjpdl9TN4AQwC4sgwYPl/Q/Obf/d53nOm569T0fYK+tcoSV50BWx8A==}
motion@12.34.0:
resolution: {integrity: sha512-01Sfa/zgsD/di8zA/uFW5Eb7/SPXoGyUfy+uMRMW5Spa8j0z/UbfQewAYvPMYFCXRlyD6e5aLHh76TxeeJD+RA==}
peerDependencies:
'@emotion/is-prop-valid': '*'
react: ^18.0.0 || ^19.0.0
react-dom: ^18.0.0 || ^19.0.0
peerDependenciesMeta:
'@emotion/is-prop-valid':
optional: true
react:
optional: true
react-dom:
optional: true
mri@1.2.0: mri@1.2.0:
resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==}
engines: {node: '>=4'} engines: {node: '>=4'}
@@ -5137,10 +5101,9 @@ packages:
resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==}
engines: {node: '>=6'} engines: {node: '>=6'}
tar@7.5.7: tar@7.5.9:
resolution: {integrity: sha512-fov56fJiRuThVFXD6o6/Q354S7pnWMJIVlDBYijsTNx6jKSE4pvrDTs6lUnmGvNyfJwFQQwWy3owKz1ucIhveQ==} resolution: {integrity: sha512-BTLcK0xsDh2+PUe9F6c2TlRp4zOOBMTkoQHQIWSIzI0R7KG46uEwq4OPk2W7bZcprBMsuaeFsqwYr7pjh6CuHg==}
engines: {node: '>=18'} engines: {node: '>=18'}
deprecated: Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
terser@5.44.1: terser@5.44.1:
resolution: {integrity: sha512-t/R3R/n0MSwnnazuPpPNVO60LX0SKL45pyl9YlvxIdkH0Of7D5qM2EVe+yASRIlY5pZ73nclYJfNANGWPwFDZw==} resolution: {integrity: sha512-t/R3R/n0MSwnnazuPpPNVO60LX0SKL45pyl9YlvxIdkH0Of7D5qM2EVe+yASRIlY5pZ73nclYJfNANGWPwFDZw==}
@@ -5279,8 +5242,8 @@ packages:
undici-types@7.16.0: undici-types@7.16.0:
resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==}
undici@7.21.0: undici@7.22.0:
resolution: {integrity: sha512-Hn2tCQpoDt1wv23a68Ctc8Cr/BHpUSfaPYrkajTXOS9IKpxVRx/X5m1K2YkbK2ipgZgxXSgsUinl3x+2YdSSfg==} resolution: {integrity: sha512-RqslV2Us5BrllB+JeiZnK4peryVTndy9Dnqq62S3yYRRTj0tFQCwEniUy2167skdGOy3vqRzEvl1Dm4sV2ReDg==}
engines: {node: '>=20.18.1'} engines: {node: '>=20.18.1'}
unicode-canonical-property-names-ecmascript@2.0.1: unicode-canonical-property-names-ecmascript@2.0.1:
@@ -5302,8 +5265,8 @@ packages:
unified@11.0.5: unified@11.0.5:
resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==}
unifont@0.7.3: unifont@0.7.4:
resolution: {integrity: sha512-b0GtQzKCyuSHGsfj5vyN8st7muZ6VCI4XD4vFlr7Uy1rlWVYxC3npnfk8MyreHxJYrz1ooLDqDzFe9XqQTlAhA==} resolution: {integrity: sha512-oHeis4/xl42HUIeHuNZRGEvxj5AaIKR+bHPNegRq5LV1gdc3jundpONbjglKpihmJf+dswygdMJn3eftGIMemg==}
unist-util-find-after@5.0.0: unist-util-find-after@5.0.0:
resolution: {integrity: sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==} resolution: {integrity: sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==}
@@ -5824,7 +5787,7 @@ snapshots:
'@astrojs/rss@4.0.15': '@astrojs/rss@4.0.15':
dependencies: dependencies:
fast-xml-parser: 5.3.5 fast-xml-parser: 5.3.6
piccolore: 0.1.3 piccolore: 0.1.3
'@astrojs/sitemap@3.7.0': '@astrojs/sitemap@3.7.0':
@@ -5840,7 +5803,7 @@ snapshots:
dlv: 1.1.3 dlv: 1.1.3
dset: 3.1.4 dset: 3.1.4
is-docker: 3.0.0 is-docker: 3.0.0
is-wsl: 3.1.0 is-wsl: 3.1.1
which-pm-runs: 1.1.0 which-pm-runs: 1.1.0
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@@ -6795,9 +6758,9 @@ snapshots:
'@eslint-community/regexpp@4.12.2': {} '@eslint-community/regexpp@4.12.2': {}
'@eslint-react/ast@2.12.4(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)': '@eslint-react/ast@2.13.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)':
dependencies: dependencies:
'@eslint-react/eff': 2.12.4 '@eslint-react/eff': 2.13.0
'@typescript-eslint/types': 8.55.0 '@typescript-eslint/types': 8.55.0
'@typescript-eslint/typescript-estree': 8.55.0(typescript@5.9.3) '@typescript-eslint/typescript-estree': 8.55.0(typescript@5.9.3)
'@typescript-eslint/utils': 8.55.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3) '@typescript-eslint/utils': 8.55.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)
@@ -6807,12 +6770,12 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
'@eslint-react/core@2.12.4(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)': '@eslint-react/core@2.13.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)':
dependencies: dependencies:
'@eslint-react/ast': 2.12.4(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3) '@eslint-react/ast': 2.13.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)
'@eslint-react/eff': 2.12.4 '@eslint-react/eff': 2.13.0
'@eslint-react/shared': 2.12.4(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3) '@eslint-react/shared': 2.13.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)
'@eslint-react/var': 2.12.4(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3) '@eslint-react/var': 2.13.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)
'@typescript-eslint/scope-manager': 8.55.0 '@typescript-eslint/scope-manager': 8.55.0
'@typescript-eslint/types': 8.55.0 '@typescript-eslint/types': 8.55.0
'@typescript-eslint/utils': 8.55.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3) '@typescript-eslint/utils': 8.55.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)
@@ -6822,31 +6785,31 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
'@eslint-react/eff@2.12.4': {} '@eslint-react/eff@2.13.0': {}
'@eslint-react/eslint-plugin@2.12.4(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)': '@eslint-react/eslint-plugin@2.13.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)':
dependencies: dependencies:
'@eslint-react/eff': 2.12.4 '@eslint-react/eff': 2.13.0
'@eslint-react/shared': 2.12.4(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3) '@eslint-react/shared': 2.13.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)
'@typescript-eslint/scope-manager': 8.55.0 '@typescript-eslint/scope-manager': 8.55.0
'@typescript-eslint/type-utils': 8.55.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3) '@typescript-eslint/type-utils': 8.55.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)
'@typescript-eslint/types': 8.55.0 '@typescript-eslint/types': 8.55.0
'@typescript-eslint/utils': 8.55.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3) '@typescript-eslint/utils': 8.55.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)
eslint: 10.0.0(jiti@2.6.1) eslint: 10.0.0(jiti@2.6.1)
eslint-plugin-react-dom: 2.12.4(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3) eslint-plugin-react-dom: 2.13.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)
eslint-plugin-react-hooks-extra: 2.12.4(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3) eslint-plugin-react-hooks-extra: 2.13.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)
eslint-plugin-react-naming-convention: 2.12.4(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3) eslint-plugin-react-naming-convention: 2.13.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)
eslint-plugin-react-rsc: 2.12.4(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3) eslint-plugin-react-rsc: 2.13.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)
eslint-plugin-react-web-api: 2.12.4(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3) eslint-plugin-react-web-api: 2.13.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)
eslint-plugin-react-x: 2.12.4(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3) eslint-plugin-react-x: 2.13.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)
ts-api-utils: 2.4.0(typescript@5.9.3) ts-api-utils: 2.4.0(typescript@5.9.3)
typescript: 5.9.3 typescript: 5.9.3
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
'@eslint-react/shared@2.12.4(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)': '@eslint-react/shared@2.13.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)':
dependencies: dependencies:
'@eslint-react/eff': 2.12.4 '@eslint-react/eff': 2.13.0
'@typescript-eslint/utils': 8.55.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3) '@typescript-eslint/utils': 8.55.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)
eslint: 10.0.0(jiti@2.6.1) eslint: 10.0.0(jiti@2.6.1)
ts-pattern: 5.9.0 ts-pattern: 5.9.0
@@ -6855,11 +6818,11 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
'@eslint-react/var@2.12.4(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)': '@eslint-react/var@2.13.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)':
dependencies: dependencies:
'@eslint-react/ast': 2.12.4(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3) '@eslint-react/ast': 2.13.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)
'@eslint-react/eff': 2.12.4 '@eslint-react/eff': 2.13.0
'@eslint-react/shared': 2.12.4(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3) '@eslint-react/shared': 2.13.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)
'@typescript-eslint/scope-manager': 8.55.0 '@typescript-eslint/scope-manager': 8.55.0
'@typescript-eslint/types': 8.55.0 '@typescript-eslint/types': 8.55.0
'@typescript-eslint/utils': 8.55.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3) '@typescript-eslint/utils': 8.55.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)
@@ -6873,7 +6836,7 @@ snapshots:
dependencies: dependencies:
'@eslint/object-schema': 3.0.1 '@eslint/object-schema': 3.0.1
debug: 4.4.3 debug: 4.4.3
minimatch: 10.1.2 minimatch: 10.2.0
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@@ -6942,7 +6905,7 @@ snapshots:
local-pkg: 1.1.2 local-pkg: 1.1.2
pathe: 2.0.3 pathe: 2.0.3
svgo: 3.3.2 svgo: 3.3.2
tar: 7.5.7 tar: 7.5.9
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@@ -7057,11 +7020,7 @@ snapshots:
'@img/sharp-win32-x64@0.34.5': '@img/sharp-win32-x64@0.34.5':
optional: true optional: true
'@isaacs/balanced-match@4.0.1': {} '@isaacs/cliui@9.0.0': {}
'@isaacs/brace-expansion@5.0.1':
dependencies:
'@isaacs/balanced-match': 4.0.1
'@isaacs/fs-minipass@4.0.1': '@isaacs/fs-minipass@4.0.1':
dependencies: dependencies:
@@ -7378,7 +7337,7 @@ snapshots:
focus-options-polyfill: 1.6.0 focus-options-polyfill: 1.6.0
swup: 4.8.2 swup: 4.8.2
'@swup/astro@1.7.0(@types/babel__core@7.20.5)': '@swup/astro@1.8.0(@types/babel__core@7.20.5)':
dependencies: dependencies:
'@swup/a11y-plugin': 5.0.0(swup@4.8.2) '@swup/a11y-plugin': 5.0.0(swup@4.8.2)
'@swup/body-class-plugin': 3.3.0(swup@4.8.2) '@swup/body-class-plugin': 3.3.0(swup@4.8.2)
@@ -7858,9 +7817,9 @@ snapshots:
acorn@8.15.0: {} acorn@8.15.0: {}
ajv-draft-04@1.0.0(ajv@8.17.1): ajv-draft-04@1.0.0(ajv@8.18.0):
optionalDependencies: optionalDependencies:
ajv: 8.17.1 ajv: 8.18.0
ajv@6.12.6: ajv@6.12.6:
dependencies: dependencies:
@@ -7869,7 +7828,7 @@ snapshots:
json-schema-traverse: 0.4.1 json-schema-traverse: 0.4.1
uri-js: 4.4.1 uri-js: 4.4.1
ajv@8.17.1: ajv@8.18.0:
dependencies: dependencies:
fast-deep-equal: 3.1.3 fast-deep-equal: 3.1.3
fast-uri: 3.1.0 fast-uri: 3.1.0
@@ -7973,8 +7932,6 @@ snapshots:
get-intrinsic: 1.3.0 get-intrinsic: 1.3.0
is-array-buffer: 3.0.5 is-array-buffer: 3.0.5
astro-compressor@1.2.0: {}
astro-eslint-parser@1.3.0: astro-eslint-parser@1.3.0:
dependencies: dependencies:
'@astrojs/compiler': 2.13.1 '@astrojs/compiler': 2.13.1
@@ -8053,7 +8010,7 @@ snapshots:
tinyglobby: 0.2.15 tinyglobby: 0.2.15
tsconfck: 3.1.6(typescript@5.9.3) tsconfck: 3.1.6(typescript@5.9.3)
ultrahtml: 1.6.0 ultrahtml: 1.6.0
unifont: 0.7.3 unifont: 0.7.4
unist-util-visit: 5.1.0 unist-util-visit: 5.1.0
unstorage: 1.17.4 unstorage: 1.17.4
vfile: 6.0.3 vfile: 6.0.3
@@ -8155,7 +8112,7 @@ snapshots:
tinyglobby: 0.2.15 tinyglobby: 0.2.15
tsconfck: 3.1.6(typescript@5.9.3) tsconfck: 3.1.6(typescript@5.9.3)
ultrahtml: 1.6.0 ultrahtml: 1.6.0
unifont: 0.7.3 unifont: 0.7.4
unist-util-visit: 5.1.0 unist-util-visit: 5.1.0
unstorage: 1.17.4 unstorage: 1.17.4
vfile: 6.0.3 vfile: 6.0.3
@@ -8218,7 +8175,7 @@ snapshots:
autoprefixer@10.4.24(postcss@8.5.6): autoprefixer@10.4.24(postcss@8.5.6):
dependencies: dependencies:
browserslist: 4.28.1 browserslist: 4.28.1
caniuse-lite: 1.0.30001769 caniuse-lite: 1.0.30001770
fraction.js: 5.3.4 fraction.js: 5.3.4
picocolors: 1.1.1 picocolors: 1.1.1
postcss: 8.5.6 postcss: 8.5.6
@@ -8271,6 +8228,10 @@ snapshots:
balanced-match@1.0.2: {} balanced-match@1.0.2: {}
balanced-match@4.0.2:
dependencies:
jackspeak: 4.2.3
base-64@1.0.0: {} base-64@1.0.0: {}
baseline-browser-mapping@2.9.19: {} baseline-browser-mapping@2.9.19: {}
@@ -8299,6 +8260,10 @@ snapshots:
dependencies: dependencies:
balanced-match: 1.0.2 balanced-match: 1.0.2
brace-expansion@5.0.2:
dependencies:
balanced-match: 4.0.2
braces@3.0.3: braces@3.0.3:
dependencies: dependencies:
fill-range: 7.1.1 fill-range: 7.1.1
@@ -8310,7 +8275,7 @@ snapshots:
browserslist@4.28.1: browserslist@4.28.1:
dependencies: dependencies:
baseline-browser-mapping: 2.9.19 baseline-browser-mapping: 2.9.19
caniuse-lite: 1.0.30001769 caniuse-lite: 1.0.30001770
electron-to-chromium: 1.5.286 electron-to-chromium: 1.5.286
node-releases: 2.0.27 node-releases: 2.0.27
update-browserslist-db: 1.2.3(browserslist@4.28.1) update-browserslist-db: 1.2.3(browserslist@4.28.1)
@@ -8352,11 +8317,11 @@ snapshots:
caniuse-api@3.0.0: caniuse-api@3.0.0:
dependencies: dependencies:
browserslist: 4.28.1 browserslist: 4.28.1
caniuse-lite: 1.0.30001769 caniuse-lite: 1.0.30001770
lodash.memoize: 4.1.2 lodash.memoize: 4.1.2
lodash.uniq: 4.5.0 lodash.uniq: 4.5.0
caniuse-lite@1.0.30001769: {} caniuse-lite@1.0.30001770: {}
ccount@2.0.1: {} ccount@2.0.1: {}
@@ -8401,7 +8366,7 @@ snapshots:
parse5: 7.3.0 parse5: 7.3.0
parse5-htmlparser2-tree-adapter: 7.1.0 parse5-htmlparser2-tree-adapter: 7.1.0
parse5-parser-stream: 7.1.2 parse5-parser-stream: 7.1.2
undici: 7.21.0 undici: 7.22.0
whatwg-mimetype: 4.0.0 whatwg-mimetype: 4.0.0
chokidar@4.0.3: chokidar@4.0.3:
@@ -9010,13 +8975,13 @@ snapshots:
prettier: 3.8.1 prettier: 3.8.1
synckit: 0.11.12 synckit: 0.11.12
eslint-plugin-react-dom@2.12.4(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3): eslint-plugin-react-dom@2.13.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3):
dependencies: dependencies:
'@eslint-react/ast': 2.12.4(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3) '@eslint-react/ast': 2.13.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)
'@eslint-react/core': 2.12.4(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3) '@eslint-react/core': 2.13.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)
'@eslint-react/eff': 2.12.4 '@eslint-react/eff': 2.13.0
'@eslint-react/shared': 2.12.4(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3) '@eslint-react/shared': 2.13.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)
'@eslint-react/var': 2.12.4(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3) '@eslint-react/var': 2.13.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)
'@typescript-eslint/scope-manager': 8.55.0 '@typescript-eslint/scope-manager': 8.55.0
'@typescript-eslint/types': 8.55.0 '@typescript-eslint/types': 8.55.0
'@typescript-eslint/utils': 8.55.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3) '@typescript-eslint/utils': 8.55.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)
@@ -9027,13 +8992,13 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
eslint-plugin-react-hooks-extra@2.12.4(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3): eslint-plugin-react-hooks-extra@2.13.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3):
dependencies: dependencies:
'@eslint-react/ast': 2.12.4(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3) '@eslint-react/ast': 2.13.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)
'@eslint-react/core': 2.12.4(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3) '@eslint-react/core': 2.13.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)
'@eslint-react/eff': 2.12.4 '@eslint-react/eff': 2.13.0
'@eslint-react/shared': 2.12.4(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3) '@eslint-react/shared': 2.13.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)
'@eslint-react/var': 2.12.4(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3) '@eslint-react/var': 2.13.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)
'@typescript-eslint/scope-manager': 8.55.0 '@typescript-eslint/scope-manager': 8.55.0
'@typescript-eslint/type-utils': 8.55.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3) '@typescript-eslint/type-utils': 8.55.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)
'@typescript-eslint/types': 8.55.0 '@typescript-eslint/types': 8.55.0
@@ -9055,13 +9020,13 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
eslint-plugin-react-naming-convention@2.12.4(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3): eslint-plugin-react-naming-convention@2.13.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3):
dependencies: dependencies:
'@eslint-react/ast': 2.12.4(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3) '@eslint-react/ast': 2.13.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)
'@eslint-react/core': 2.12.4(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3) '@eslint-react/core': 2.13.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)
'@eslint-react/eff': 2.12.4 '@eslint-react/eff': 2.13.0
'@eslint-react/shared': 2.12.4(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3) '@eslint-react/shared': 2.13.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)
'@eslint-react/var': 2.12.4(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3) '@eslint-react/var': 2.13.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)
'@typescript-eslint/scope-manager': 8.55.0 '@typescript-eslint/scope-manager': 8.55.0
'@typescript-eslint/type-utils': 8.55.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3) '@typescript-eslint/type-utils': 8.55.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)
'@typescript-eslint/types': 8.55.0 '@typescript-eslint/types': 8.55.0
@@ -9078,11 +9043,11 @@ snapshots:
dependencies: dependencies:
eslint: 10.0.0(jiti@2.6.1) eslint: 10.0.0(jiti@2.6.1)
eslint-plugin-react-rsc@2.12.4(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3): eslint-plugin-react-rsc@2.13.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3):
dependencies: dependencies:
'@eslint-react/ast': 2.12.4(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3) '@eslint-react/ast': 2.13.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)
'@eslint-react/shared': 2.12.4(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3) '@eslint-react/shared': 2.13.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)
'@eslint-react/var': 2.12.4(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3) '@eslint-react/var': 2.13.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)
'@typescript-eslint/types': 8.55.0 '@typescript-eslint/types': 8.55.0
'@typescript-eslint/utils': 8.55.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3) '@typescript-eslint/utils': 8.55.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)
eslint: 10.0.0(jiti@2.6.1) eslint: 10.0.0(jiti@2.6.1)
@@ -9091,13 +9056,13 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
eslint-plugin-react-web-api@2.12.4(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3): eslint-plugin-react-web-api@2.13.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3):
dependencies: dependencies:
'@eslint-react/ast': 2.12.4(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3) '@eslint-react/ast': 2.13.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)
'@eslint-react/core': 2.12.4(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3) '@eslint-react/core': 2.13.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)
'@eslint-react/eff': 2.12.4 '@eslint-react/eff': 2.13.0
'@eslint-react/shared': 2.12.4(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3) '@eslint-react/shared': 2.13.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)
'@eslint-react/var': 2.12.4(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3) '@eslint-react/var': 2.13.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)
'@typescript-eslint/scope-manager': 8.55.0 '@typescript-eslint/scope-manager': 8.55.0
'@typescript-eslint/types': 8.55.0 '@typescript-eslint/types': 8.55.0
'@typescript-eslint/utils': 8.55.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3) '@typescript-eslint/utils': 8.55.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)
@@ -9108,13 +9073,13 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
eslint-plugin-react-x@2.12.4(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3): eslint-plugin-react-x@2.13.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3):
dependencies: dependencies:
'@eslint-react/ast': 2.12.4(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3) '@eslint-react/ast': 2.13.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)
'@eslint-react/core': 2.12.4(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3) '@eslint-react/core': 2.13.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)
'@eslint-react/eff': 2.12.4 '@eslint-react/eff': 2.13.0
'@eslint-react/shared': 2.12.4(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3) '@eslint-react/shared': 2.13.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)
'@eslint-react/var': 2.12.4(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3) '@eslint-react/var': 2.13.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)
'@typescript-eslint/scope-manager': 8.55.0 '@typescript-eslint/scope-manager': 8.55.0
'@typescript-eslint/type-utils': 8.55.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3) '@typescript-eslint/type-utils': 8.55.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.9.3)
'@typescript-eslint/types': 8.55.0 '@typescript-eslint/types': 8.55.0
@@ -9197,7 +9162,7 @@ snapshots:
imurmurhash: 0.1.4 imurmurhash: 0.1.4
is-glob: 4.0.3 is-glob: 4.0.3
json-stable-stringify-without-jsonify: 1.0.1 json-stable-stringify-without-jsonify: 1.0.1
minimatch: 10.1.2 minimatch: 10.2.0
natural-compare: 1.4.0 natural-compare: 1.4.0
optionator: 0.9.4 optionator: 0.9.4
optionalDependencies: optionalDependencies:
@@ -9277,7 +9242,7 @@ snapshots:
fast-uri@3.1.0: {} fast-uri@3.1.0: {}
fast-xml-parser@5.3.5: fast-xml-parser@5.3.6:
dependencies: dependencies:
strnum: 2.1.2 strnum: 2.1.2
@@ -9353,15 +9318,6 @@ snapshots:
fraction.js@5.3.4: {} fraction.js@5.3.4: {}
framer-motion@12.34.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4):
dependencies:
motion-dom: 12.34.0
motion-utils: 12.29.2
tslib: 2.8.1
optionalDependencies:
react: 19.2.4
react-dom: 19.2.4(react@19.2.4)
fresh@2.0.0: {} fresh@2.0.0: {}
fs-extra@10.1.0: fs-extra@10.1.0:
@@ -9830,7 +9786,7 @@ snapshots:
dependencies: dependencies:
is-docker: 2.2.1 is-docker: 2.2.1
is-wsl@3.1.0: is-wsl@3.1.1:
dependencies: dependencies:
is-inside-container: 1.0.0 is-inside-container: 1.0.0
@@ -9847,6 +9803,10 @@ snapshots:
has-symbols: 1.1.0 has-symbols: 1.1.0
set-function-name: 2.0.2 set-function-name: 2.0.2
jackspeak@4.2.3:
dependencies:
'@isaacs/cliui': 9.0.0
jake@10.9.4: jake@10.9.4:
dependencies: dependencies:
async: 3.2.6 async: 3.2.6
@@ -10452,9 +10412,9 @@ snapshots:
mini-svg-data-uri@1.4.4: {} mini-svg-data-uri@1.4.4: {}
minimatch@10.1.2: minimatch@10.2.0:
dependencies: dependencies:
'@isaacs/brace-expansion': 5.0.1 brace-expansion: 5.0.2
minimatch@3.1.2: minimatch@3.1.2:
dependencies: dependencies:
@@ -10483,20 +10443,6 @@ snapshots:
morphdom@2.7.8: {} morphdom@2.7.8: {}
motion-dom@12.34.0:
dependencies:
motion-utils: 12.29.2
motion-utils@12.29.2: {}
motion@12.34.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4):
dependencies:
framer-motion: 12.34.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
tslib: 2.8.1
optionalDependencies:
react: 19.2.4
react-dom: 19.2.4(react@19.2.4)
mri@1.2.0: {} mri@1.2.0: {}
mrmime@2.0.1: {} mrmime@2.0.1: {}
@@ -11695,7 +11641,7 @@ snapshots:
tapable@2.3.0: {} tapable@2.3.0: {}
tar@7.5.7: tar@7.5.9:
dependencies: dependencies:
'@isaacs/fs-minipass': 4.0.1 '@isaacs/fs-minipass': 4.0.1
chownr: 3.0.0 chownr: 3.0.0
@@ -11839,7 +11785,7 @@ snapshots:
undici-types@7.16.0: {} undici-types@7.16.0: {}
undici@7.21.0: {} undici@7.22.0: {}
unicode-canonical-property-names-ecmascript@2.0.1: {} unicode-canonical-property-names-ecmascript@2.0.1: {}
@@ -11862,7 +11808,7 @@ snapshots:
trough: 2.2.0 trough: 2.2.0
vfile: 6.0.3 vfile: 6.0.3
unifont@0.7.3: unifont@0.7.4:
dependencies: dependencies:
css-tree: 3.1.0 css-tree: 3.1.0
ofetch: 1.5.1 ofetch: 1.5.1
@@ -12155,8 +12101,8 @@ snapshots:
yaml-language-server@1.19.2: yaml-language-server@1.19.2:
dependencies: dependencies:
'@vscode/l10n': 0.0.18 '@vscode/l10n': 0.0.18
ajv: 8.17.1 ajv: 8.18.0
ajv-draft-04: 1.0.0(ajv@8.17.1) ajv-draft-04: 1.0.0(ajv@8.18.0)
lodash: 4.17.21 lodash: 4.17.21
prettier: 3.8.1 prettier: 3.8.1
request-light: 0.5.8 request-light: 0.5.8

View File

@@ -3,10 +3,11 @@ import { getImage } from 'astro:assets';
import { readSingleton } from '@directus/sdk'; import { readSingleton } from '@directus/sdk';
import directus from '@lib/directus'; import directus from '@lib/directus';
import { SEO } from '@/config';
import brandSrc from '@images/brand_logo.png'; import brandSrc from '@images/brand_logo.png';
import faviconSvgSrc from '@images/favicon_icon.svg'; import faviconSvgSrc from '@images/favicon_icon.svg';
import faviconSrc from '@images/favicon_icon.png'; import faviconSrc from '@images/favicon_icon.png';
import { SEO } from '@/config';
interface Props { interface Props {
title: string; title: string;
@@ -18,6 +19,7 @@ interface Props {
} }
const canonicalURL = Astro.url.href; const canonicalURL = Astro.url.href;
let { let {
title, title,
description, description,
@@ -27,14 +29,14 @@ let {
structuredData = SEO.structuredData, structuredData = SEO.structuredData,
} = Astro.props; } = Astro.props;
const global = await directus.request(readSingleton('site_global'));
let card = 'summary_large_image'; let card = 'summary_large_image';
if (!ogImage) { if (!ogImage) {
ogImage = brandSrc; ogImage = brandSrc;
card = 'summary'; card = 'summary';
} }
const global = await directus.request(readSingleton('site_global'));
const faviconSvg = await getImage({ src: faviconSvgSrc, format: 'svg' }); const faviconSvg = await getImage({ src: faviconSvgSrc, format: 'svg' });
const appleTouchIcon = await getImage({ src: faviconSrc, width: 180, height: 180, format: 'png' }); const appleTouchIcon = await getImage({ src: faviconSrc, width: 180, height: 180, format: 'png' });
const socialImageRes = await getImage({ src: ogImage, width: 1200, height: 600 }); const socialImageRes = await getImage({ src: ogImage, width: 1200, height: 600 });
@@ -62,12 +64,12 @@ if (!socialImage.startsWith('http')) {
<meta http-equiv="X-UA-Compatible" content="ie=edge" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" />
<meta name="mobile-web-app-capable" content="yes" /> <meta name="mobile-web-app-capable" content="yes" />
<meta name="theme-color" content="#facc15" /> <meta name="theme-color" content="#facc15" />
<meta name="robots" content="index, follow" />
<!-- Open Graph --> <!-- Open Graph -->
<meta property="og:type" content="website" /> <meta property="og:type" content="website" />
<meta property="og:locale" content="en_US" /> <meta property="og:locale" content="en_US" />
<meta property="og:url" content={Astro.url} /> <meta property="og:url" content={Astro.url} />
<meta property="og:type" content="website" />
<meta property="og:title" content={ogTitle} /> <meta property="og:title" content={ogTitle} />
<meta property="og:site_name" content={global.name} /> <meta property="og:site_name" content={global.name} />
<meta property="og:description" content={ogDescription} /> <meta property="og:description" content={ogDescription} />
@@ -76,17 +78,10 @@ if (!socialImage.startsWith('http')) {
<meta content="600" property="og:image:height" /> <meta content="600" property="og:image:height" />
<meta content="image/png" property="og:image:type" /> <meta content="image/png" property="og:image:type" />
<!-- Twitter -->
<meta property="twitter:card" content={card} />
<meta property="twitter:url" content={Astro.url} />
<meta property="twitter:domain" content={Astro.url} />
<meta property="twitter:title" content={ogTitle} />
<meta property="twitter:description" content={ogDescription} />
<meta property="twitter:image" content={socialImage} />
<!-- Links --> <!-- Links -->
<link href={canonicalURL} rel="canonical" /> <link href={canonicalURL} rel="canonical" />
<link rel="sitemap" href="/sitemap-index.xml" /> <link rel="sitemap" href="/sitemap-index.xml" />
<link rel="alternate" type="application/rss+xml" title={title} href="/rss.xml" />
<!--<link href="/manifest.json" rel="manifest" />--> <!--<link href="/manifest.json" rel="manifest" />-->
<link href="/favicon.ico" rel="icon" sizes="any" type="image/x-icon" /> <link href="/favicon.ico" rel="icon" sizes="any" type="image/x-icon" />
<link href={faviconSvg.src} rel="icon" type="image/svg+xml" sizes="any" /> <link href={faviconSvg.src} rel="icon" type="image/svg+xml" sizes="any" />

View File

@@ -1,13 +1,15 @@
--- ---
import { readSingleton } from '@directus/sdk'; import { readSingleton } from '@directus/sdk';
import directus from '@lib/directus';
import BrandLogo from '@components/ui/logos/BrandLogo.astro'; import BrandLogo from '@components/ui/logos/BrandLogo.astro';
import Image from '@components/ui/images/Image.astro'; import Image from '@components/ui/images/Image.astro';
import directus from '@lib/directus';
import { NavigationLinks, FooterLinks } from '@/config'; import { NavigationLinks, FooterLinks } from '@/config';
import footerImg from '@images/flowers.png'; import footerImg from '@images/flowers.png';
const global = await directus.request(readSingleton('site_global')); const global = await directus.request(readSingleton('site_global'));
const currentYear = new Date().getFullYear(); const currentYear = new Date().getFullYear();
--- ---

View File

@@ -1,61 +0,0 @@
---
import { Icon } from 'astro-icon/components';
import type { Post } from '@lib/directusTypes';
import { getDirectusImageURL } from '@lib/directusFunctions';
import Image from '@components/ui/images/Image.astro';
import { formatDate } from '@support/time';
interface Props {
post: Post;
}
const { post } = Astro.props;
const baseClasses = 'group group-hover smooth-reveal-cards rounded-xl flex flex-col';
const borderClasses = 'border border-stone-200/50 dark:border-stone-700/50';
const bgColorClasses =
'bg-neutral-100/80 hover:bg-neutral-100 dark:bg-neutral-800/60 dark:hover:bg-neutral-800/90';
const shadowClasses = 'shadow-xs hover:shadow-md dark:shadow-md dark:hover:shadow-lg';
---
<div class={`${baseClasses}`}>
<a
class={`rounded-xl duration-300 transition-all ${borderClasses} ${shadowClasses} ${bgColorClasses}`}
href={`/blog/${post.slug}/`}
data-astro-prefetch
>
<div
class="relative w-full flex-shrink-0 overflow-hidden rounded-t-xl before:absolute before:inset-x-0 before:z-[1] before:size-full"
>
<Image
class="h-auto w-full rounded-t-xl"
src={getDirectusImageURL(post.image)}
alt={post.image_alt}
draggable="false"
loading="eager"
format="webp"
width="800"
height="460"
/>
</div>
<div class="rounded-xl p-4 md:p-5">
<h3 class="text-xl font-bold text-neutral-600 dark:text-neutral-200">
{post.title}
</h3>
<div
class="group-hover:text-steel dark:group-hover:text-bermuda transition-text relative z-10 mx-auto flex min-h-[44px] items-center font-medium text-neutral-600 decoration-2 duration-300 sm:mx-0 sm:mt-4 dark:text-neutral-400"
>
<span class="relative inline-block overflow-hidden"> Read more </span>
<Icon
name="mdi:keyboard-arrow-right"
class="h-3 w-3 translate-y-0.25 transition duration-300 group-hover:translate-x-1 md:h-5 md:w-5"
/>
<p class="ml-auto text-sm text-neutral-600 dark:text-neutral-400">
{formatDate(post.published_date)}
</p>
</div>
</div>
</a>
</div>

View File

@@ -1,44 +0,0 @@
---
import GoLinkPrimaryButton from '@components/buttons/GoLinkPrimaryButton.astro';
import Image from '@components/ui/images/Image.astro';
interface Props {
title: string;
subTitle: string;
btnExists?: boolean;
btnTitle?: string;
btnURL?: string;
img: any;
imgAlt: any;
}
const { title, subTitle, btnExists, btnTitle, btnURL, img, imgAlt } = Astro.props;
---
<section
class="mx-auto max-w-[85rem] items-center gap-8 px-4 py-10 sm:px-6 sm:py-16 md:grid md:grid-cols-2 lg:grid lg:grid-cols-2 lg:px-8 lg:py-14 xl:gap-16 2xl:max-w-full"
>
<Image
class="h-full w-full rounded-xl object-cover sm:max-h-[320px] md:max-h-[360px]"
src={img}
alt={imgAlt}
draggable="false"
loading="lazy"
width="850"
height="420"
/>
<div class="mt-4 md:mt-0">
<h2
class="mb-4 text-4xl font-extrabold tracking-tight text-balance text-neutral-800 dark:text-neutral-200"
>
{title}
</h2>
<p
class="mb-4 max-w-prose font-light text-pretty text-neutral-600 sm:text-lg dark:text-neutral-300"
>
{subTitle}
</p>
{btnExists ? <GoLinkPrimaryButton title={btnTitle} url={btnURL} /> : null}
</div>
</section>

View File

@@ -1,29 +0,0 @@
---
import type { Post } from '@lib/directusTypes';
import BlogCard from '@components/blog/BlogCard.astro';
interface Props {
posts: Post[];
}
const { posts } = Astro.props;
---
<section class="mx-auto mb-10 max-w-[85rem] px-4 py-8 sm:px-6 lg:px-8 2xl:max-w-full">
<div class="text-left">
<h2
id="recent-articles"
class="smooth-reveal-2 mb-10 text-5xl font-extrabold tracking-tight text-balance text-neutral-800 dark:text-neutral-200"
>
Recent Posts
</h2>
</div>
<div class="flex flex-col md:flex-row md:space-x-12 lg:space-x-16">
<div class="w-full">
<div class="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3">
{posts.map((b) => <BlogCard post={b} />)}
</div>
</div>
</div>
</section>

View File

@@ -1,87 +0,0 @@
---
import GoLinkPrimaryButton from '@components/buttons/GoLinkPrimaryButton.astro';
import Image from '@components/ui/images/Image.astro';
interface Props {
title: string;
subTitle: string;
btnExists?: boolean;
btnTitle?: string;
btnURL?: string;
single?: boolean;
imgOne?: any;
imgOneAlt?: any;
imgTwo?: any;
imgTwoAlt?: any;
}
const {
title,
subTitle,
btnExists,
btnTitle,
btnURL,
single,
imgOne,
imgOneAlt,
imgTwo,
imgTwoAlt,
} = Astro.props;
---
<section
class="mx-auto max-w-[85rem] items-center gap-16 px-4 py-10 sm:px-6 lg:grid lg:grid-cols-2 lg:px-8 lg:py-14 2xl:max-w-full"
>
<div>
<h2
class="mb-4 text-4xl font-extrabold tracking-tight text-balance text-neutral-800 dark:text-neutral-200"
>
{title}
</h2>
<p
class="mb-4 max-w-prose font-light text-pretty text-neutral-600 sm:text-lg dark:text-neutral-400"
>
{subTitle}
</p>
{btnExists ? <GoLinkPrimaryButton title={btnTitle} url={btnURL} /> : null}
</div>
{
single ? (
<div class="mt-8">
<Image
class="w-full rounded-lg"
src={imgOne}
alt={imgOneAlt}
format="webp"
loading="lazy"
width="850"
height="420"
/>
</div>
) : (
<div class="mt-8 grid grid-cols-2 gap-4">
<Image
class="w-full rounded-xl"
src={imgOne}
alt={imgOneAlt}
draggable="false"
format="webp"
loading="lazy"
width="400"
height="230"
/>
<Image
class="mt-4 w-full rounded-xl lg:mt-10"
src={imgTwo}
alt={imgTwoAlt}
draggable="false"
format="webp"
loading="lazy"
width="400"
height="230"
/>
</div>
)
}
</section>

View File

@@ -1,44 +0,0 @@
---
import type { Post } from '@lib/directusTypes';
import { getDirectusImageURL } from '@lib/directusFunctions';
import BlogLeftSection from '@components/blog/BlogLeftSection.astro';
import BlogRightSection from '@components/blog/BlogRightSection.astro';
interface Props {
posts: Post[];
}
const { posts } = Astro.props;
---
<section class="smooth-reveal">
{
posts.map((b, index) =>
index % 2 === 0 ? (
<BlogLeftSection
title={b.title}
subTitle={b.description}
btnExists={true}
btnTitle="Read More"
btnURL={`/blog/${b.slug}`}
img={getDirectusImageURL(b.image)}
imgAlt={b.image_alt}
/>
) : (
<BlogRightSection
title={b.title}
subTitle={b.description}
btnExists={true}
btnTitle="Read More"
btnURL={`/blog/${b.slug}`}
single={!b.image_second}
imgOne={getDirectusImageURL(b.image)}
imgOneAlt={b.image_alt}
imgTwo={getDirectusImageURL(b?.image_second)}
imgTwoAlt={b?.image_second_alt}
/>
)
)
}
</section>

View File

@@ -2,11 +2,10 @@
import { Icon } from 'astro-icon/components'; import { Icon } from 'astro-icon/components';
interface Props { interface Props {
title?: string;
url?: string; url?: string;
} }
const { title, url } = Astro.props; const { url } = Astro.props;
--- ---
<a <a

View File

@@ -1,11 +1,5 @@
--- ---
import Icon from '@components/ui/icons/icon.astro'; import Icon from '@components/ui/icons/icon.astro';
interface Props {
noArrow?: boolean;
}
const { noArrow } = Astro.props;
--- ---
<button <button
@@ -14,7 +8,7 @@ const { noArrow } = Astro.props;
data-astro-prefetch data-astro-prefetch
> >
<div class="button-text-title flex relative items-center text-center"> <div class="button-text-title flex relative items-center text-center">
{noArrow ? null : <Icon name="arrowLeft" />} <Icon name="arrowLeft" />
<span class="ml-2"> <span class="ml-2">
Go Back Go Back
</span> </span>

View File

@@ -33,19 +33,20 @@ const socialPlatforms: SocialPlatform[] = [
--- ---
<div class="inline-flex items-center gap-x-2"> <div class="inline-flex items-center gap-x-2">
{ {socialPlatforms.map((platform) => (
socialPlatforms.map((platform) => ( <a
<a class="button-base-hidden group inline-flex rounded-lg gap-x-2"
class="button-base-hidden group inline-flex rounded-lg gap-x-2" href={platform.url}
href={platform.url} target="_blank"
target="_blank" rel="noopener noreferrer"
rel="noopener noreferrer" title={`Share on ${platform.name}`}
title={`Share on ${platform.name}`} >
> <div class="button-text-title-hidden flex relative items-center text-center">
<div class="button-text-title-hidden flex relative items-center text-center"> <Icon
<Icon name={platform.svg} class="h-5 w-5" /> name={platform.svg}
</div> class="h-5 w-5"
</a> />
)) </div>
} </a>
))}
</div> </div>

View File

@@ -0,0 +1,58 @@
---
import { Icon } from 'astro-icon/components';
import type { Post } from '@lib/directusTypes';
import Image from '@components/ui/images/Image.astro';
import { getDirectusImageURL } from '@lib/directusFunctions';
interface Props {
post: Post;
}
const { post } = Astro.props;
---
<div class="smooth-reveal-cards group flex flex-col">
<a
class="card-base border-none!"
href={`/blog/${post.slug}/`}
data-astro-prefetch
>
<div class="relative shrink-0 rounded-t-xl w-full overflow-hidden before:absolute before:inset-x-0 before:z-1 before:size-full">
<Image
class="rounded-t-xl h-auto w-full"
src={getDirectusImageURL(post.image)}
alt={post.image_alt}
draggable="false"
loading="eager"
format="webp"
/>
</div>
<div class="rounded-xl p-4 md:p-5">
<h3 class="card-text-title text-xl">
{post.title}
</h3>
<div class="ml-6 flex">
<div class="relative inline-block w-full">
<div class="card-text-title card-hover-text-title flex relative items-center mx-auto min-h-11 sm:mx-0 sm:mt-4">
<span class="relative inline-block overflow-hidden ml-2">
Read more
</span>
<Icon
name="mdi:keyboard-arrow-right"
class="translate-y-0.5 transition duration-300 group-hover:translate-x-1"
/>
<p class="card-text-description text-sm ml-auto">
{new Date(post.published_date).toLocaleDateString('en-US', {
year: 'numeric',
month: 'short',
day: 'numeric',
})}
</p>
</div>
</div>
</div>
</div>
</a>
</div>

View File

@@ -8,37 +8,30 @@ interface Props {
} }
const { slug, title, description, count, publishDate } = Astro.props; const { slug, title, description, count, publishDate } = Astro.props;
const baseClasses =
'group group-hover rounded-xl flex h-full min-h-[220px] cursor-pointer flex-col overflow-hidden';
const bgColorClasses =
'bg-neutral-100/60 dark:bg-neutral-800/60 hover:bg-neutral-100 dark:hover:bg-neutral-800/90 ';
--- ---
<a class={`rounded-xl`} href={`/categories/${slug}/`} data-astro-prefetch="false"> <div class="smooth-reveal-cards group h-full">
<div class={`${baseClasses}`}> <a
<div class="card-base flex flex-col h-full min-h-55"
class={`relative min-h-0 flex-grow overflow-hidden transition-all duration-300 ${bgColorClasses}`} href={`/categories/${slug}/`}
> data-astro-prefetch
>
<div class="relative grow overflow-hidden">
<div class="absolute inset-1 flex flex-col p-3 md:p-4 lg:p-5"> <div class="absolute inset-1 flex flex-col p-3 md:p-4 lg:p-5">
<div class="overflow-hidden"> <div class="overflow-hidden">
<h2 <h3 class="card-text-title-major card-hover-text-title whitespace-nowrap mb-4">
class="group-hover:text-steel dark:group-hover:text-bermuda transition-text mb-4 text-4xl font-extrabold tracking-tight text-balance whitespace-nowrap text-neutral-800 duration-300 dark:text-neutral-200"
>
{title} {title}
</h2> </h3>
<p class="mb-4 font-light text-neutral-600 sm:text-lg dark:text-neutral-400"> <p class="card-text-description mb-4">
{description} {description}
</p> </p>
</div> </div>
<div <div class="card-text-description flex items-center justify-between text-xs mt-auto pt-1 md:pt-2">
class="mt-auto flex items-center justify-between pt-1 text-xs text-neutral-600 md:pt-2 dark:text-neutral-300"
>
<span class="inline-flex items-center"> <span class="inline-flex items-center">
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
width="12" width="16"
height="12" height="16"
viewBox="0 0 24 24" viewBox="0 0 24 24"
fill="none" fill="none"
stroke="currentColor" stroke="currentColor"
@@ -51,8 +44,8 @@ const bgColorClasses =
<span class="inline-flex items-center"> <span class="inline-flex items-center">
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
width="12" width="16"
height="12" height="16"
viewBox="0 0 24 24" viewBox="0 0 24 24"
fill="none" fill="none"
stroke="currentColor" stroke="currentColor"
@@ -66,5 +59,5 @@ const bgColorClasses =
</div> </div>
</div> </div>
</div> </div>
</div> </a>
</a> </div>

View File

@@ -1,6 +1,8 @@
--- ---
import { Icon } from 'astro-icon/components'; import { Icon } from 'astro-icon/components';
import Logo from '@components/ui/logos/Logo.astro'; import Logo from '@components/ui/logos/Logo.astro';
import { getDirectusImageURL } from '@lib/directusFunctions';
interface Props { interface Props {
topic: string; topic: string;
@@ -12,7 +14,8 @@ interface Props {
logoIcon?: string; logoIcon?: string;
} }
const { topic, area, date, url, logoUrlLight, logoUrlDark, logoIcon } = Astro.props; const { topic, area, date, url, logoUrlLight, logoIcon } = Astro.props;
const logoUrlDark = Astro.props.logoUrlDark || logoUrlLight;
--- ---
<div class="smooth-reveal group flex flex-col"> <div class="smooth-reveal group flex flex-col">
@@ -25,8 +28,8 @@ const { topic, area, date, url, logoUrlLight, logoUrlDark, logoIcon } = Astro.pr
{logoUrlLight ? ( {logoUrlLight ? (
<div class="card-hover-icon-scale mr-5"> <div class="card-hover-icon-scale mr-5">
<Logo <Logo
srcLight={logoUrlLight} srcLight={getDirectusImageURL(logoUrlLight)}
srcDark={logoUrlDark} srcDark={getDirectusImageURL(logoUrlDark!)}
alt={`Logo of ${topic}`} alt={`Logo of ${topic}`}
/> />
</div> </div>

View File

@@ -9,13 +9,11 @@ interface Props {
} }
const { title, description, url, icon } = Astro.props; const { title, description, url, icon } = Astro.props;
const sizeClasses = 'h-30 w-100 md:w-[300px]';
--- ---
<div class="smooth-reveal-2 group flex flex-col"> <div class="smooth-reveal-2 group flex flex-col">
<a <a
class={`card-base flex items-center ${sizeClasses}`} class="card-base flex items-center h-30 w-100 md:w-75"
href={url} href={url}
data-astro-prefetch data-astro-prefetch
> >
@@ -29,9 +27,9 @@ const sizeClasses = 'h-30 w-100 md:w-[300px]';
<span class="card-text-title card-hover-text-title block text-lg"> <span class="card-text-title card-hover-text-title block text-lg">
{title} {title}
</span> </span>
<span class="card-text-description block mt-1"> <p class="card-text-description block mt-1">
{description} {description}
</span> </p>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -39,9 +39,9 @@ const visitClass = visitSource ? 'card-hover-text-gitea' : 'card-hover-text-titl
<span class="card-text-title block text-lg"> <span class="card-text-title block text-lg">
{title} {title}
</span> </span>
<span class="card-text-description block mt-1"> <p class="card-text-description block mt-1">
{description} {description}
</span> </p>
</div> </div>
</div> </div>
{highlights && ( {highlights && (
@@ -55,7 +55,7 @@ const visitClass = visitSource ? 'card-hover-text-gitea' : 'card-hover-text-titl
)} )}
<div class="ml-6 flex"> <div class="ml-6 flex">
<div class="relative inline-block"> <div class="relative inline-block">
<div class={`card-text-title ${visitClass} flex relative items-center mx-auto min-h-11 font-semibold text-md sm:mx-0 sm:mt-4`}> <div class={`card-text-title ${visitClass} flex relative items-center font-semibold text-md min-h-11 mx-auto sm:mx-0 sm:mt-4`}>
{visitSource && <Icon name="pajamas:gitea" />} {visitSource && <Icon name="pajamas:gitea" />}
<span class="relative inline-block overflow-hidden ml-2"> <span class="relative inline-block overflow-hidden ml-2">
{visitText} {visitText}

View File

@@ -0,0 +1,55 @@
---
import { Icon } from 'astro-icon/components';
import Image from '@components/ui/images/Image.astro';
import { getDirectusImageURL } from '@lib/directusFunctions';
interface Props {
title: string;
subTitle: string;
url: string;
img: string;
imgAlt: string;
}
const { title, subTitle, url, img, imgAlt } = Astro.props;
---
<div class="smooth-reveal group">
<a
class="card-base-hidden md:grid md:grid-cols-2 lg:grid lg:grid-cols-2 items-center gap-8 xl:gap-16 max-w-340 2xl:max-w-full px-4 sm:px-6 lg:px-8 py-10 sm:py-16 lg:py-14 mx-auto"
href={url}
data-astro-prefetch
>
<div>
<Image
class="rounded-xl w-full h-full sm:max-h-80 md:max-h-90 object-cover"
src={getDirectusImageURL(img)}
alt={imgAlt}
draggable="false"
loading="lazy"
width="850"
height="420"
/>
</div>
<div>
<h2 class="card-text-header mb-4">
{title}
</h2>
<p class="card-text-title font-light text-pretty sm:text-lg max-w-prose mb-4">
{subTitle}
</p>
<div class="button-base button-bg-teal inline-flex rounded-lg gap-x-2">
<div class="button-text-title flex relative items-center text-center">
<span class="mr-2">
Read More
</span>
<Icon
name="mdi:keyboard-arrow-right"
class="button-hover-arrow"
/>
</div>
</div>
</div>
</a>
</div>

View File

@@ -0,0 +1,83 @@
---
import { Icon } from 'astro-icon/components';
import Image from '@components/ui/images/Image.astro';
import { getDirectusImageURL } from '@lib/directusFunctions';
interface Props {
title: string;
subTitle: string;
url: string;
single?: boolean;
imgOne: any;
imgOneAlt: any;
imgTwo?: any;
imgTwoAlt?: any;
}
const { title, subTitle, url, single, imgOne, imgOneAlt, imgTwo, imgTwoAlt } = Astro.props;
---
<div class="smooth-reveal group">
<a
class="card-base-hidden items-center lg:grid lg:grid-cols-2 gap-16 max-w-340 2xl:max-w-full px-4 py-10 sm:px-6 lg:px-8 lg:py-14 mx-auto"
href={url}
data-astro-prefetch
>
<div>
<h2 class="card-text-header mb-4">
{title}
</h2>
<p class="card-text-title font-light text-pretty sm:text-lg max-w-prose mb-4">
{subTitle}
</p>
<div class="button-base button-bg-teal inline-flex rounded-lg gap-x-2">
<div class="button-text-title flex relative items-center text-center">
<span class="mr-2">
Read More
</span>
<Icon
name="mdi:keyboard-arrow-right"
class="button-hover-arrow"
/>
</div>
</div>
</div>
{single ? (
<div>
<Image
class="rounded-xl w-full"
src={getDirectusImageURL(imgOne)}
alt={imgOneAlt}
format="webp"
loading="lazy"
width="850"
height="420"
/>
</div>
) : (
<div class="grid grid-cols-2 gap-4">
<Image
class="rounded-xl w-full"
src={getDirectusImageURL(imgOne)}
alt={imgOneAlt}
draggable="false"
format="webp"
loading="lazy"
width="400"
height="230"
/>
<Image
class="rounded-xl w-full mt-4 lg:mt-10"
src={getDirectusImageURL(imgTwo)}
alt={imgTwoAlt}
draggable="false"
format="webp"
loading="lazy"
width="400"
height="230"
/>
</div>
)}
</a>
</div>

View File

@@ -7,12 +7,10 @@ interface Props {
} }
const { dayName, label, icon, temp } = Astro.props; const { dayName, label, icon, temp } = Astro.props;
const sizeClasses = 'w-32 md:w-40';
--- ---
<div class="smooth-reveal-2 group flex flex-col"> <div class="smooth-reveal-2 group flex flex-col">
<div class={`card-base ${sizeClasses}`}> <div class="card-base w-32 md:w-40">
<div class="p-5 text-center"> <div class="p-5 text-center">
<span class="card-text-description block font-bold text-xs uppercase tracking-widest"> <span class="card-text-description block font-bold text-xs uppercase tracking-widest">
{dayName} {dayName}

View File

@@ -3,8 +3,8 @@ import { readItems } from '@directus/sdk';
import type { Application } from '@lib/directusTypes'; import type { Application } from '@lib/directusTypes';
import directus from '@lib/directus';
import HighlightsCard from '@components/cards/HighlightsCard.astro'; import HighlightsCard from '@components/cards/HighlightsCard.astro';
import directus from '@lib/directus';
const applications = ((await directus.request( const applications = ((await directus.request(
readItems('site_applications' as any, { readItems('site_applications' as any, {

View File

@@ -0,0 +1,93 @@
---
import { getCollection } from 'astro:content';
import { readItems } from '@directus/sdk';
import type { Post } from '@lib/directusTypes';
import CategoryCard from '@components/cards/CategoryCard.astro';
import directus from '@lib/directus';
import { timeago } from '@support/time';
const posts = await directus.request(
readItems('posts', {
filter: { published: { _eq: true } },
fields: ['*'],
sort: ['-published_date'],
})
);
const layoutPattern = [
{ col: 2, row: 2 },
{ col: 2, row: 1 },
{ col: 1, row: 1 },
{ col: 1, row: 1 },
{ col: 1, row: 2 },
{ col: 2, row: 1 },
{ col: 1, row: 1 },
{ col: 1, row: 1 },
{ col: 1, row: 1 },
{ col: 1, row: 1 },
];
const postMap: Map<string, Post[]> = posts
.sort((a: Post, b: Post) => b.published_date.valueOf() - a.published_date.valueOf())
.reduce((acc, obj) => {
let posts = acc.get(obj.category);
if (!posts) {
posts = [];
}
posts.push(obj);
acc.set(obj.category, posts);
return acc;
}, new Map<string, Post[]>());
const categories = (await getCollection('categories'))
.sort((a, b) => {
const aCount = postMap.get(a.slug)?.length ?? 0;
const bCount = postMap.get(b.slug)?.length ?? 0;
return bCount - aCount;
})
.map((c, index) => {
const posts = postMap.get(c.slug);
const pattern = layoutPattern[index % layoutPattern.length];
const smColSpan = Math.min(pattern.col, 2);
const mdColSpan = Math.min(pattern.col, 4);
const rowSpan = pattern.row;
const rowSpanClass = rowSpan > 1 ? `row-span-${rowSpan}` : 'row-span-1';
const gridItemClass = `col-span-${smColSpan} md:col-span-${mdColSpan} ${rowSpanClass}`;
return {
...c,
posts,
gridItemClass,
layoutPattern: {
smCol: smColSpan,
mdCol: mdColSpan,
row: rowSpan,
index,
},
};
});
---
<section class="mx-auto px-4 py-10 sm:px-6 lg:px-8 lg:py-14 lg:pt-10 2xl:max-w-full">
<div class="grid grid-flow-row-dense grid-cols-2 md:grid-cols-4 gap-4">
{categories.map((category) => {
return (
<div
class={category.gridItemClass}
style={category.layoutPattern.row > 1 ? 'grid-row: span 2 / span 2;' : ''}
>
<CategoryCard
slug={category.slug}
title={category.data.title}
description={category.data.description}
count={postMap.get(category.slug)?.length ?? 0}
publishDate={timeago(postMap.get(category.slug)?.[0]?.published_date)}
/>
</div>
);
})}
</div>
</section>

View File

@@ -3,9 +3,8 @@ import { readItems } from '@directus/sdk';
import type { Education, Certificate} from '@lib/directusTypes'; import type { Education, Certificate} from '@lib/directusTypes';
import directus from '@lib/directus';
import { getDirectusImageURL } from '@lib/directusFunctions';
import EducationCard from '@components/cards/EducationCard.astro'; import EducationCard from '@components/cards/EducationCard.astro';
import directus from '@lib/directus';
const educations = ((await directus.request( const educations = ((await directus.request(
readItems('site_education' as any, { readItems('site_education' as any, {
@@ -37,8 +36,8 @@ const certificates = ((await directus.request(
area={education.area} area={education.area}
date={education.graduationDate} date={education.graduationDate}
url={education.url} url={education.url}
logoUrlLight={getDirectusImageURL(education.logo)} logoUrlLight={education.logo}
logoUrlDark={getDirectusImageURL(education.logoDark)} logoUrlDark={education.logoDark}
/> />
))} ))}
</div> </div>

View File

@@ -78,7 +78,7 @@ const experiences = ((await directus.request(
</div> </div>
)} )}
{(experience.responsibilities || experience.achievements) && ( {(experience.responsibilities || experience.achievements) && (
<div class="relative flex flex-col gap-4 max-sm:h-auto! md:after:absolute md:after:bottom-0 md:after:h-12 md:after:w-full md:after:bg-gradient-to-t md:after:from-neutral-200 dark:md:after:from-stone-700 md:after:content-[''] " :class="expanded ? 'after:hidden' : ''" x-show="expanded" x-collapse.min.50px> <div class="relative flex flex-col gap-4 max-sm:h-auto! md:after:absolute md:after:bottom-0 md:after:h-12 md:after:w-full md:after:bg-linear-to-t md:after:from-neutral-200 dark:md:after:from-stone-700 md:after:content-[''] " :class="expanded ? 'after:hidden' : ''" x-show="expanded" x-collapse.min.50px>
{experience.responsibilities && ( {experience.responsibilities && (
<div class="flex flex-col gap-1"> <div class="flex flex-col gap-1">
<h4 class="text-header font-semibold"> <h4 class="text-header font-semibold">

View File

@@ -1,8 +1,8 @@
--- ---
import { readSingleton } from '@directus/sdk'; import { readSingleton } from '@directus/sdk';
import directus from '@lib/directus';
import FeaturesCard from '@components/cards/FeaturesCard.astro'; import FeaturesCard from '@components/cards/FeaturesCard.astro';
import directus from '@lib/directus';
const global = await directus.request(readSingleton('site_global')); const global = await directus.request(readSingleton('site_global'));
--- ---

View File

@@ -1,36 +0,0 @@
---
import { readItems } from '@directus/sdk';
import type { Post } from '@lib/directusTypes';
import directus from '@lib/directus';
import BlogCard from '@components/blog/BlogCard.astro';
const posts = await directus.request(
readItems('posts', {
filter: { published: { _eq: true } },
fields: ['*'],
sort: ['-published_date'],
})
);
const recentPosts = posts
.sort((a: Post, b: Post) => (new Date(b.published_date).getTime()) - (new Date(a.published_date).getTime()))
.slice(0, 3);
---
<section class="mx-auto mb-20 max-w-340 px-4 py-10 sm:px-6 lg:px-8 lg:py-14 2xl:max-w-full">
<div class="mx-auto mb-10 max-w-2xl text-center lg:mb-14">
<h1 class="smooth-reveal card-text-header block">
Latest Posts
</h1>
<div class="smooth-reveal mx-auto mt-5 max-w-3xl text-center">
<span class="card-text-header-description">
Checkout my most recent thoughts here
</span>
</div>
</div>
<div class="grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
{recentPosts.map((b) => <BlogCard post={b} />)}
</div>
</section>

View File

@@ -3,8 +3,8 @@ import { readItems } from '@directus/sdk';
import type { Project } from '@lib/directusTypes'; import type { Project } from '@lib/directusTypes';
import directus from '@lib/directus';
import HighlightsCard from '@components/cards/HighlightsCard.astro'; import HighlightsCard from '@components/cards/HighlightsCard.astro';
import directus from '@lib/directus';
const projects = ((await directus.request( const projects = ((await directus.request(
readItems('site_projects' as any, { readItems('site_projects' as any, {

View File

@@ -0,0 +1,29 @@
---
import type { Post } from '@lib/directusTypes';
import BlogCard from '@components/cards/BlogCard.astro';
interface Props {
posts: Post[];
title: string;
subTitle?: string;
}
const { posts, title, subTitle } = Astro.props;
---
<section class="mx-auto mb-20 max-w-340 px-4 py-10 sm:px-6 lg:px-8 lg:py-14 2xl:max-w-full">
<div class="mx-auto mb-10 max-w-2xl text-center lg:mb-14">
<h1 class="smooth-reveal card-text-header block">
{title}
</h1>
<div class="smooth-reveal mx-auto mt-5 max-w-3xl text-center">
<span class="card-text-header-description">
{subTitle}
</span>
</div>
</div>
<div class="grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
{posts.map((b) => <BlogCard post={b} />)}
</div>
</section>

View File

@@ -0,0 +1,35 @@
---
import type { Post } from '@lib/directusTypes';
import LargeBlogLeftCard from '@components/cards/LargeBlogLeftCard.astro';
import LargeBlogRightCard from '@components/cards/LargeBlogRightCard.astro';
interface Props {
posts: Post[];
}
const { posts } = Astro.props;
---
<section class="smooth-reveal">
{posts.map((post, index) => index % 2 === 0 ? (
<LargeBlogLeftCard
title={post.title}
subTitle={post.description}
url={`/blog/${post.slug}`}
img={post.image}
imgAlt={post.image_alt}
/>
) : (
<LargeBlogRightCard
title={post.title}
subTitle={post.description}
url={`/blog/${post.slug}`}
single={!post.image_second}
imgOne={post.image}
imgOneAlt={post.image_alt}
imgTwo={post?.image_second}
imgTwoAlt={post?.image_second_alt}
/>
))}
</section>

View File

@@ -3,6 +3,7 @@ import WeatherCard from '@components/cards/WeatherCard.astro';
import { getFiveDayForecast } from '@support/weather'; import { getFiveDayForecast } from '@support/weather';
const { latitude = "44.95", longitude = "-93.09", cityName = "St. Paul, Minnesota", timezone = "America/Chicago" } = Astro.props; const { latitude = "44.95", longitude = "-93.09", cityName = "St. Paul, Minnesota", timezone = "America/Chicago" } = Astro.props;
const { forecastDays, error } = await getFiveDayForecast(latitude, longitude, timezone); const { forecastDays, error } = await getFiveDayForecast(latitude, longitude, timezone);
--- ---

View File

@@ -28,6 +28,7 @@ const global = await directus.request(readSingleton('site_global'));
}, },
}} }}
> >
<section class="mt-20 grid place-content-center"> <section class="mt-20 grid place-content-center">
<div class="mx-auto max-w-7xl px-4 py-8 lg:px-6 lg:py-16"> <div class="mx-auto max-w-7xl px-4 py-8 lg:px-6 lg:py-16">
<div class="mx-auto max-w-screen-sm text-center"> <div class="mx-auto max-w-screen-sm text-center">
@@ -67,6 +68,7 @@ const global = await directus.request(readSingleton('site_global'));
</div> </div>
</div> </div>
</section> </section>
</BaseLayout> </BaseLayout>
<script> <script>

View File

@@ -1,18 +1,20 @@
--- ---
import { type CollectionEntry, getCollection } from 'astro:content'; import { type CollectionEntry, getCollection } from 'astro:content';
import getReadingTime from 'reading-time'; import getReadingTime from 'reading-time';
import { readItems, readSingleton } from '@directus/sdk';
import directus from '@lib/directus';
import { marked } from 'marked'; import { marked } from 'marked';
import markedShiki from 'marked-shiki'; import markedShiki from 'marked-shiki';
import { createHighlighter } from 'shiki'; import { createHighlighter } from 'shiki';
import { getDirectusImageURL } from '@lib/directusFunctions'; import { readItems, readSingleton } from '@directus/sdk';
import BaseLayout from '@layouts/BaseLayout.astro';
import Image from '@components/ui/images/Image.astro'; import Image from '@components/ui/images/Image.astro';
import SocialShareButton from '@components/buttons/SocialShareButton.astro'; import SocialShareButton from '@components/buttons/SocialShareButton.astro';
import BaseLayout from '@layouts/BaseLayout.astro';
import directus from '@lib/directus';
import { getDirectusImageURL } from '@lib/directusFunctions';
import { formatDateTime } from '@support/time'; import { formatDateTime } from '@support/time';
const post = Astro.props;
export async function getStaticPaths() { export async function getStaticPaths() {
const posts = await directus.request(readItems('posts')); const posts = await directus.request(readItems('posts'));
return posts.map((post) => ({ return posts.map((post) => ({
@@ -20,18 +22,19 @@ export async function getStaticPaths() {
props: post, props: post,
})); }));
} }
const post = Astro.props;
const global = await directus.request(readSingleton('site_global')); const global = await directus.request(readSingleton('site_global'));
const category: CollectionEntry<'categories'> = (await getCollection('categories')) const category: CollectionEntry<'categories'> = (await getCollection('categories'))
.filter((c) => c.slug === post.category) .filter((c) => c.slug === post.category)
.pop() as CollectionEntry<'categories'>; .pop() as CollectionEntry<'categories'>;
const readingTime = getReadingTime(post.content); const readingTime = getReadingTime(post.content);
const highlighter = await createHighlighter({ const highlighter = await createHighlighter({
themes: ['github-light', 'github-dark', 'monokai'], themes: ['github-light', 'github-dark', 'monokai'],
langs: ['typescript', 'python', 'css', 'html', 'yaml', 'bash', 'json'], langs: ['typescript', 'python', 'css', 'html', 'yaml', 'bash', 'json'],
}); });
marked.use(markedShiki({ marked.use(markedShiki({
highlight(code, lang) { highlight(code, lang) {
return highlighter.codeToHtml(code, { return highlighter.codeToHtml(code, {
@@ -44,6 +47,7 @@ marked.use(markedShiki({
}); });
} }
})); }));
const content = marked.parse(post.content); const content = marked.parse(post.content);
--- ---
@@ -79,6 +83,7 @@ const content = marked.parse(post.content);
], ],
}} }}
> >
<section class="mx-auto max-w-6xl px-4 pt-8 pb-12 sm:px-6 lg:px-8 lg:pt-12"> <section class="mx-auto max-w-6xl px-4 pt-8 pb-12 sm:px-6 lg:px-8 lg:pt-12">
<div class="smooth-reveal relative w-full"> <div class="smooth-reveal relative w-full">
<div class="mt-4 rounded-2xl shadow-none sm:mt-0 sm:shadow-sm"> <div class="mt-4 rounded-2xl shadow-none sm:mt-0 sm:shadow-sm">
@@ -171,6 +176,7 @@ const content = marked.parse(post.content);
</div> </div>
</div> </div>
</section> </section>
<style is:inline> <style is:inline>
code[data-theme*=' '], code[data-theme*=' '],
code[data-theme*=' '] span { code[data-theme*=' '] span {
@@ -184,6 +190,7 @@ const content = marked.parse(post.content);
} }
} }
</style> </style>
</BaseLayout> </BaseLayout>
<script> <script>

View File

@@ -3,11 +3,12 @@ import { readItems, readSingleton } from '@directus/sdk';
import type { Post } from '@lib/directusTypes'; import type { Post } from '@lib/directusTypes';
import directus from '@lib/directus';
import BaseLayout from '@layouts/BaseLayout.astro';
import BlogSelectedArticles from '@components/blog/BlogSelectedArticles.astro';
import BlogRecentArticles from '@components/blog/BlogRecentArticles.astro';
import HeroSection from '@components/sections/HeroSection.astro'; import HeroSection from '@components/sections/HeroSection.astro';
import SelectedPostsSection from '@components/sections/SelectedPostsSection.astro';
import RecentPostsSection from '@components/sections/RecentPostsSection.astro';
import BaseLayout from '@layouts/BaseLayout.astro';
import directus from '@lib/directus';
import blogImg from '@images/autumn_tree.png'; import blogImg from '@images/autumn_tree.png';
const global = await directus.request(readSingleton('site_global')); const global = await directus.request(readSingleton('site_global'));
@@ -18,10 +19,11 @@ const posts = await directus.request(
sort: ['-published_date'], sort: ['-published_date'],
}) })
); );
const selectedPosts: Post[] = posts.filter((p) => p.selected).slice(0, 4);
const selectedPosts: Post[] = posts.filter((p) => p.selected).slice(0, 3);
const recentPosts: Post[] = posts.filter( const recentPosts: Post[] = posts.filter(
(p) => !selectedPosts.some((selected) => selected.slug === p.slug) (p) => !selectedPosts.some((selected) => selected.slug === p.slug)
).slice(0, 6); ).slice(0, 9);
--- ---
<BaseLayout <BaseLayout
@@ -43,10 +45,21 @@ const recentPosts: Post[] = posts.filter(
}, },
}} }}
> >
<HeroSection title="Blog" subTitle={global.about_blog} src={blogImg} alt={global.blog_image_alt} />
<BlogSelectedArticles posts={selectedPosts} /> <HeroSection
<BlogRecentArticles posts={recentPosts} /> title="Blog"
subTitle={global.about_blog}
src={blogImg}
alt={global.blog_image_alt}
/>
<SelectedPostsSection posts={selectedPosts} />
<RecentPostsSection
posts={recentPosts}
title="Recent Posts"
/>
</BaseLayout> </BaseLayout>
<script> <script>

View File

@@ -2,11 +2,12 @@
import { getCollection } from 'astro:content'; import { getCollection } from 'astro:content';
import { readItems, readSingleton } from '@directus/sdk'; import { readItems, readSingleton } from '@directus/sdk';
import directus from '@lib/directus';
import type { Post } from '@lib/directusTypes'; import type { Post } from '@lib/directusTypes';
import BaseLayout from '@layouts/BaseLayout.astro';
import BlogCard from '@components/blog/BlogCard.astro'; import BlogCard from '@components/cards/BlogCard.astro';
import HeaderSection from '@components/sections/HeaderSection.astro'; import HeaderSection from '@components/sections/HeaderSection.astro';
import BaseLayout from '@layouts/BaseLayout.astro';
import directus from '@lib/directus';
export async function getStaticPaths() { export async function getStaticPaths() {
const categories = await getCollection('categories'); const categories = await getCollection('categories');
@@ -26,6 +27,7 @@ const posts = await directus.request(
sort: ['-published_date'], sort: ['-published_date'],
}) })
); );
const categoriesPosts = posts const categoriesPosts = posts
.sort((a: Post, b: Post) => b.published_date.valueOf() - a.published_date.valueOf()) .sort((a: Post, b: Post) => b.published_date.valueOf() - a.published_date.valueOf())
.filter((b) => { .filter((b) => {
@@ -51,6 +53,7 @@ const categoriesPosts = posts
}, },
}} }}
> >
<HeaderSection <HeaderSection
title={category.data.title} title={category.data.title}
subTitle={category.data.description} subTitle={category.data.description}
@@ -59,9 +62,12 @@ const categoriesPosts = posts
btnURL="/categories" btnURL="/categories"
/> />
<section class="mx-auto mt-10 mb-10 max-w-[85rem] px-4 py-8 sm:px-6 lg:px-8 2xl:max-w-full"> <section class="max-w-340 2xl:max-w-full mx-auto mt-10 mb-10 px-4 py-8 sm:px-6 lg:px-8">
<div class="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3"> <div class="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3">
{categoriesPosts.map((b) => <BlogCard post={b} />)} {categoriesPosts.map((b) =>
<BlogCard post={b} />
)}
</div> </div>
</section> </section>
</BaseLayout> </BaseLayout>

View File

@@ -1,78 +1,14 @@
--- ---
import { getCollection } from 'astro:content'; import { readSingleton } from '@directus/sdk';
import { readItems, readSingleton } from '@directus/sdk';
import type { Post } from '@lib/directusTypes';
import directus from '@lib/directus'; import directus from '@lib/directus';
import BaseLayout from '@layouts/BaseLayout.astro'; import BaseLayout from '@layouts/BaseLayout.astro';
import BlogCategoryCard from '@components/blog/BlogCategoryCard.astro';
import HeroSection from '@components/sections/HeroSection.astro'; import HeroSection from '@components/sections/HeroSection.astro';
import { timeago } from '@support/time'; import CategorySection from '@components/sections/CategorySection.astro';
import categoryImg from '@images/autumn_bench.png'; import categoryImg from '@images/autumn_bench.png';
const global = await directus.request(readSingleton('site_global')); const global = await directus.request(readSingleton('site_global'));
const posts = await directus.request(
readItems('posts', {
filter: { published: { _eq: true } },
fields: ['*'],
sort: ['-published_date'],
})
);
const postMap: Map<string, Post[]> = posts
.sort((a: Post, b: Post) => b.published_date.valueOf() - a.published_date.valueOf())
.reduce((acc, obj) => {
let posts = acc.get(obj.category);
if (!posts) {
posts = [];
}
posts.push(obj);
acc.set(obj.category, posts);
return acc;
}, new Map<string, Post[]>());
const layoutPattern = [
{ col: 2, row: 2 },
{ col: 2, row: 1 },
{ col: 1, row: 1 },
{ col: 1, row: 1 },
{ col: 1, row: 2 },
{ col: 2, row: 1 },
{ col: 1, row: 1 },
{ col: 1, row: 1 },
{ col: 1, row: 1 },
{ col: 1, row: 1 },
];
const categories = (await getCollection('categories'))
.sort((a, b) => {
const aCount = postMap.get(a.slug)?.length ?? 0;
const bCount = postMap.get(b.slug)?.length ?? 0;
return bCount - aCount;
})
.map((c, index) => {
const posts = postMap.get(c.slug);
const pattern = layoutPattern[index % layoutPattern.length];
const smColSpan = Math.min(pattern.col, 2);
const mdColSpan = Math.min(pattern.col, 4);
const rowSpan = pattern.row;
const rowSpanClass = rowSpan > 1 ? `row-span-${rowSpan}` : 'row-span-1';
const gridItemClass = `col-span-${smColSpan} md:col-span-${mdColSpan} ${rowSpanClass} smooth-reveal-cards rounded-xl transition-all duration-300 shadow-xs hover:shadow-md dark:shadow-md dark:hover:shadow-lg border border-stone-200/50 dark:border-stone-700/50`;
return {
...c,
posts,
gridItemClass,
layoutPattern: {
smCol: smColSpan,
mdCol: mdColSpan,
row: rowSpan,
index,
},
};
});
--- ---
<BaseLayout <BaseLayout
@@ -94,6 +30,7 @@ const categories = (await getCollection('categories'))
}, },
}} }}
> >
<HeroSection <HeroSection
title="Categories" title="Categories"
subTitle={global.about_categories} subTitle={global.about_categories}
@@ -101,28 +38,8 @@ const categories = (await getCollection('categories'))
alt={global.categories_image_alt} alt={global.categories_image_alt}
/> />
<section class="mx-auto px-4 py-10 sm:px-6 lg:px-8 lg:py-14 lg:pt-10 2xl:max-w-full"> <CategorySection />
<div class="grid grid-flow-row-dense grid-cols-2 gap-4 md:grid-cols-4">
{
categories.map((category) => {
return (
<div
class={category.gridItemClass}
style={category.layoutPattern.row > 1 ? 'grid-row: span 2 / span 2;' : ''}
>
<BlogCategoryCard
slug={category.slug}
title={category.data.title}
description={category.data.description}
count={postMap.get(category.slug)?.length ?? 0}
publishDate={timeago(postMap.get(category.slug)?.[0]?.published_date)}
/>
</div>
);
})
}
</div>
</section>
</BaseLayout> </BaseLayout>
<script> <script>

View File

@@ -1,18 +1,31 @@
--- ---
import { readSingleton } from '@directus/sdk'; import { readSingleton, readItems } from '@directus/sdk';
import type { Post } from '@lib/directusTypes';
import directus from '@lib/directus'; import directus from '@lib/directus';
import BaseLayout from '@layouts/BaseLayout.astro'; import BaseLayout from '@layouts/BaseLayout.astro';
import HeroSection from '@components/sections/HeroSection.astro'; import HeroSection from '@components/sections/HeroSection.astro';
import FeaturesSection from '@components/sections/FeaturesSection.astro'; import FeatureSection from '@components/sections/FeatureSection.astro';
import WeatherSection from '@components/sections/WeatherSection.astro'; import WeatherSection from '@components/sections/WeatherSection.astro';
import LatestPostsSection from '@components/sections/LatestPostsSection.astro'; import RecentPostsSection from '@components/sections/RecentPostsSection.astro';
import GiteaSection from '@components/sections/GiteaSection.astro'; import GiteaSection from '@components/sections/GiteaSection.astro';
import homeImg from '@images/autumn_mountain.png'; import homeImg from '@images/autumn_mountain.png';
const global = await directus.request(readSingleton('site_global')); const global = await directus.request(readSingleton('site_global'));
const weather = await directus.request(readSingleton('site_weather')); const weather = await directus.request(readSingleton('site_weather'));
const posts = await directus.request(
readItems('posts', {
filter: { published: { _eq: true } },
fields: ['*'],
sort: ['-published_date'],
})
);
const recentPosts = posts
.sort((a: Post, b: Post) => (new Date(b.published_date).getTime()) - (new Date(a.published_date).getTime()))
.slice(0, 3);
--- ---
<BaseLayout <BaseLayout
@@ -34,6 +47,7 @@ const weather = await directus.request(readSingleton('site_weather'));
}, },
}} }}
> >
<HeroSection <HeroSection
title={`Hello, I'm <span class="text-steel dark:text-steel">Alex Lebens</span>`} title={`Hello, I'm <span class="text-steel dark:text-steel">Alex Lebens</span>`}
subTitle={global.about_description} subTitle={global.about_description}
@@ -43,7 +57,7 @@ const weather = await directus.request(readSingleton('site_weather'));
alt={global.home_image_alt} alt={global.home_image_alt}
/> />
<FeaturesSection /> <FeatureSection />
<WeatherSection <WeatherSection
server:defer server:defer
@@ -51,16 +65,20 @@ const weather = await directus.request(readSingleton('site_weather'));
longitude={weather.longitude} longitude={weather.longitude}
cityName={weather.location} cityName={weather.location}
timezone={weather.timezone} timezone={weather.timezone}
> />
</WeatherSection>
<LatestPostsSection /> <RecentPostsSection
posts={recentPosts}
title="Latest Posts"
subTitle="Checkout my most recent thoughts here"
/>
<GiteaSection <GiteaSection
title="Follow me on Gitea" title="Follow me on Gitea"
subTitle="I love open source and have my code availabile on my Gitea server." subTitle="I love open source and have my code availabile on my Gitea server."
url="https://gitea.alexlebens.dev" url="https://gitea.alexlebens.dev"
/> />
</BaseLayout> </BaseLayout>
<script> <script>

View File

@@ -37,7 +37,7 @@
@utility button-bg-teal { @utility button-bg-teal {
@apply transition-all duration-300 @apply transition-all duration-300
bg-bermuda hover:bg-turquoise dark:bg-turquoise dark:hover:bg-bermuda bg-bermuda hover:bg-turquoise group-hover:bg-turquoise dark:bg-turquoise dark:hover:bg-bermuda dark:group-hover:bg-bermuda
} }
@utility button-bg-neutral { @utility button-bg-neutral {
@@ -53,12 +53,20 @@
/* Card classes */ /* Card classes */
@utility card-base { @utility card-base {
@apply rounded-xl @apply transition-all duration-300
rounded-xl
border border-neutral-100 dark:border-stone-500/20 border border-neutral-100 dark:border-stone-500/20
bg-neutral-100/80 hover:bg-neutral-100 dark:bg-neutral-800/60 dark:hover:bg-neutral-800/90 bg-neutral-100/80 hover:bg-neutral-100 dark:bg-neutral-800/60 dark:hover:bg-neutral-800/90
shadow-xs hover:shadow-md dark:shadow-md dark:hover:shadow-lg shadow-xs hover:shadow-md dark:shadow-md dark:hover:shadow-lg
} }
@utility card-base-hidden {
@apply transition-all duration-300
rounded-xl
border border-transparent
hover:bg-neutral-400/20 dark:hover:bg-neutral-800/40
}
@utility card-hover-icon-color { @utility card-hover-icon-color {
@apply transition-all duration-300 @apply transition-all duration-300
text-primary text-primary
@@ -79,9 +87,8 @@
@utility card-text-header-minor { @utility card-text-header-minor {
@apply text-header @apply text-header
md:text-3xl text-2xl md:text-3xl
text-2xl font-semibold leading-tight tracking-tight text-balance
font-semibold
} }
@utility card-text-header-description { @utility card-text-header-description {
@@ -95,6 +102,12 @@
font-bold font-bold
} }
@utility card-text-title-major {
@apply text-header
text-4xl md:text-3xl
font-bold leading-tight tracking-tight text-balance
}
@utility card-hover-text-title { @utility card-hover-text-title {
@apply transition-all duration-300 @apply transition-all duration-300
group-hover:text-main group-hover:text-main