Set up tailwind and nano theme
This commit is contained in:
parent
5e5d6166d5
commit
a5c1eaedc7
@ -2,14 +2,19 @@
|
|||||||
import { defineConfig } from 'astro/config';
|
import { defineConfig } from 'astro/config';
|
||||||
|
|
||||||
import mdx from '@astrojs/mdx';
|
import mdx from '@astrojs/mdx';
|
||||||
|
|
||||||
import node from '@astrojs/node';
|
import node from '@astrojs/node';
|
||||||
|
import tailwindcss from '@tailwindcss/vite';
|
||||||
|
|
||||||
// https://astro.build/config
|
// https://astro.build/config
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
|
site: 'https://ryanpandya.com',
|
||||||
integrations: [mdx()],
|
integrations: [mdx()],
|
||||||
|
|
||||||
adapter: node({
|
adapter: node({
|
||||||
mode: 'standalone'
|
mode: 'standalone'
|
||||||
})
|
}),
|
||||||
|
|
||||||
|
vite: {
|
||||||
|
plugins: [tailwindcss()],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
10
package.json
10
package.json
@ -11,6 +11,14 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@astrojs/mdx": "^4.3.13",
|
"@astrojs/mdx": "^4.3.13",
|
||||||
"@astrojs/node": "^9.5.1",
|
"@astrojs/node": "^9.5.1",
|
||||||
"astro": "^5.16.6"
|
"@fontsource-variable/ibm-plex-sans": "^5.2.8",
|
||||||
|
"@fontsource/martel": "^5.2.8",
|
||||||
|
"@tailwindcss/postcss": "^4.1.18",
|
||||||
|
"@tailwindcss/typography": "^0.5.19",
|
||||||
|
"@tailwindcss/vite": "^4.1.18",
|
||||||
|
"astro": "^5.16.6",
|
||||||
|
"clsx": "^2.1.1",
|
||||||
|
"tailwind-merge": "^3.4.0",
|
||||||
|
"tailwindcss": "^4.1.18"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
458
pnpm-lock.yaml
generated
458
pnpm-lock.yaml
generated
@ -10,16 +10,44 @@ importers:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@astrojs/mdx':
|
'@astrojs/mdx':
|
||||||
specifier: ^4.3.13
|
specifier: ^4.3.13
|
||||||
version: 4.3.13(astro@5.16.6(@types/node@25.0.3)(rollup@4.54.0)(typescript@5.9.3))
|
version: 4.3.13(astro@5.16.6(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.54.0)(typescript@5.9.3)(yaml@2.8.2))
|
||||||
'@astrojs/node':
|
'@astrojs/node':
|
||||||
specifier: ^9.5.1
|
specifier: ^9.5.1
|
||||||
version: 9.5.1(astro@5.16.6(@types/node@25.0.3)(rollup@4.54.0)(typescript@5.9.3))
|
version: 9.5.1(astro@5.16.6(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.54.0)(typescript@5.9.3)(yaml@2.8.2))
|
||||||
|
'@fontsource-variable/ibm-plex-sans':
|
||||||
|
specifier: ^5.2.8
|
||||||
|
version: 5.2.8
|
||||||
|
'@fontsource/martel':
|
||||||
|
specifier: ^5.2.8
|
||||||
|
version: 5.2.8
|
||||||
|
'@tailwindcss/postcss':
|
||||||
|
specifier: ^4.1.18
|
||||||
|
version: 4.1.18
|
||||||
|
'@tailwindcss/typography':
|
||||||
|
specifier: ^0.5.19
|
||||||
|
version: 0.5.19(tailwindcss@4.1.18)
|
||||||
|
'@tailwindcss/vite':
|
||||||
|
specifier: ^4.1.18
|
||||||
|
version: 4.1.18(vite@6.4.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2))
|
||||||
astro:
|
astro:
|
||||||
specifier: ^5.16.6
|
specifier: ^5.16.6
|
||||||
version: 5.16.6(@types/node@25.0.3)(rollup@4.54.0)(typescript@5.9.3)
|
version: 5.16.6(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.54.0)(typescript@5.9.3)(yaml@2.8.2)
|
||||||
|
clsx:
|
||||||
|
specifier: ^2.1.1
|
||||||
|
version: 2.1.1
|
||||||
|
tailwind-merge:
|
||||||
|
specifier: ^3.4.0
|
||||||
|
version: 3.4.0
|
||||||
|
tailwindcss:
|
||||||
|
specifier: ^4.1.18
|
||||||
|
version: 4.1.18
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
|
|
||||||
|
'@alloc/quick-lru@5.2.0':
|
||||||
|
resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
|
||||||
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
'@astrojs/compiler@2.13.0':
|
'@astrojs/compiler@2.13.0':
|
||||||
resolution: {integrity: sha512-mqVORhUJViA28fwHYaWmsXSzLO9osbdZ5ImUfxBarqsYdMlPbqAqGJCxsNzvppp1BEzc1mJNjOVvQqeDN8Vspw==}
|
resolution: {integrity: sha512-mqVORhUJViA28fwHYaWmsXSzLO9osbdZ5ImUfxBarqsYdMlPbqAqGJCxsNzvppp1BEzc1mJNjOVvQqeDN8Vspw==}
|
||||||
|
|
||||||
@ -228,6 +256,12 @@ packages:
|
|||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [win32]
|
os: [win32]
|
||||||
|
|
||||||
|
'@fontsource-variable/ibm-plex-sans@5.2.8':
|
||||||
|
resolution: {integrity: sha512-n5PF2iFa0CZT0QYTPzxvZ39opC9LnU0zdoRccoADbs+Dtsd+lbXOZF7RNuIPHcQX1dKjF63sxnRImQIB5eD0Ag==}
|
||||||
|
|
||||||
|
'@fontsource/martel@5.2.8':
|
||||||
|
resolution: {integrity: sha512-5leWG3FVh2BS+4TfVYoaUoDGizhjmR98e0j2UpalfYu008Oe5s5XgIqhXCDCqaWBtXmZOb2I1Q9S47YLiXGEiQ==}
|
||||||
|
|
||||||
'@img/colour@1.0.0':
|
'@img/colour@1.0.0':
|
||||||
resolution: {integrity: sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==}
|
resolution: {integrity: sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
@ -365,9 +399,22 @@ packages:
|
|||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [win32]
|
os: [win32]
|
||||||
|
|
||||||
|
'@jridgewell/gen-mapping@0.3.13':
|
||||||
|
resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==}
|
||||||
|
|
||||||
|
'@jridgewell/remapping@2.3.5':
|
||||||
|
resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==}
|
||||||
|
|
||||||
|
'@jridgewell/resolve-uri@3.1.2':
|
||||||
|
resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
|
||||||
|
engines: {node: '>=6.0.0'}
|
||||||
|
|
||||||
'@jridgewell/sourcemap-codec@1.5.5':
|
'@jridgewell/sourcemap-codec@1.5.5':
|
||||||
resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==}
|
resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==}
|
||||||
|
|
||||||
|
'@jridgewell/trace-mapping@0.3.31':
|
||||||
|
resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
|
||||||
|
|
||||||
'@mdx-js/mdx@3.1.1':
|
'@mdx-js/mdx@3.1.1':
|
||||||
resolution: {integrity: sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==}
|
resolution: {integrity: sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==}
|
||||||
|
|
||||||
@ -517,6 +564,104 @@ packages:
|
|||||||
'@swc/helpers@0.5.18':
|
'@swc/helpers@0.5.18':
|
||||||
resolution: {integrity: sha512-TXTnIcNJQEKwThMMqBXsZ4VGAza6bvN4pa41Rkqoio6QBKMvo+5lexeTMScGCIxtzgQJzElcvIltani+adC5PQ==}
|
resolution: {integrity: sha512-TXTnIcNJQEKwThMMqBXsZ4VGAza6bvN4pa41Rkqoio6QBKMvo+5lexeTMScGCIxtzgQJzElcvIltani+adC5PQ==}
|
||||||
|
|
||||||
|
'@tailwindcss/node@4.1.18':
|
||||||
|
resolution: {integrity: sha512-DoR7U1P7iYhw16qJ49fgXUlry1t4CpXeErJHnQ44JgTSKMaZUdf17cfn5mHchfJ4KRBZRFA/Coo+MUF5+gOaCQ==}
|
||||||
|
|
||||||
|
'@tailwindcss/oxide-android-arm64@4.1.18':
|
||||||
|
resolution: {integrity: sha512-dJHz7+Ugr9U/diKJA0W6N/6/cjI+ZTAoxPf9Iz9BFRF2GzEX8IvXxFIi/dZBloVJX/MZGvRuFA9rqwdiIEZQ0Q==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [android]
|
||||||
|
|
||||||
|
'@tailwindcss/oxide-darwin-arm64@4.1.18':
|
||||||
|
resolution: {integrity: sha512-Gc2q4Qhs660bhjyBSKgq6BYvwDz4G+BuyJ5H1xfhmDR3D8HnHCmT/BSkvSL0vQLy/nkMLY20PQ2OoYMO15Jd0A==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [darwin]
|
||||||
|
|
||||||
|
'@tailwindcss/oxide-darwin-x64@4.1.18':
|
||||||
|
resolution: {integrity: sha512-FL5oxr2xQsFrc3X9o1fjHKBYBMD1QZNyc1Xzw/h5Qu4XnEBi3dZn96HcHm41c/euGV+GRiXFfh2hUCyKi/e+yw==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [darwin]
|
||||||
|
|
||||||
|
'@tailwindcss/oxide-freebsd-x64@4.1.18':
|
||||||
|
resolution: {integrity: sha512-Fj+RHgu5bDodmV1dM9yAxlfJwkkWvLiRjbhuO2LEtwtlYlBgiAT4x/j5wQr1tC3SANAgD+0YcmWVrj8R9trVMA==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [freebsd]
|
||||||
|
|
||||||
|
'@tailwindcss/oxide-linux-arm-gnueabihf@4.1.18':
|
||||||
|
resolution: {integrity: sha512-Fp+Wzk/Ws4dZn+LV2Nqx3IilnhH51YZoRaYHQsVq3RQvEl+71VGKFpkfHrLM/Li+kt5c0DJe/bHXK1eHgDmdiA==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [arm]
|
||||||
|
os: [linux]
|
||||||
|
|
||||||
|
'@tailwindcss/oxide-linux-arm64-gnu@4.1.18':
|
||||||
|
resolution: {integrity: sha512-S0n3jboLysNbh55Vrt7pk9wgpyTTPD0fdQeh7wQfMqLPM/Hrxi+dVsLsPrycQjGKEQk85Kgbx+6+QnYNiHalnw==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [linux]
|
||||||
|
|
||||||
|
'@tailwindcss/oxide-linux-arm64-musl@4.1.18':
|
||||||
|
resolution: {integrity: sha512-1px92582HkPQlaaCkdRcio71p8bc8i/ap5807tPRDK/uw953cauQBT8c5tVGkOwrHMfc2Yh6UuxaH4vtTjGvHg==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [linux]
|
||||||
|
|
||||||
|
'@tailwindcss/oxide-linux-x64-gnu@4.1.18':
|
||||||
|
resolution: {integrity: sha512-v3gyT0ivkfBLoZGF9LyHmts0Isc8jHZyVcbzio6Wpzifg/+5ZJpDiRiUhDLkcr7f/r38SWNe7ucxmGW3j3Kb/g==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [linux]
|
||||||
|
|
||||||
|
'@tailwindcss/oxide-linux-x64-musl@4.1.18':
|
||||||
|
resolution: {integrity: sha512-bhJ2y2OQNlcRwwgOAGMY0xTFStt4/wyU6pvI6LSuZpRgKQwxTec0/3Scu91O8ir7qCR3AuepQKLU/kX99FouqQ==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [linux]
|
||||||
|
|
||||||
|
'@tailwindcss/oxide-wasm32-wasi@4.1.18':
|
||||||
|
resolution: {integrity: sha512-LffYTvPjODiP6PT16oNeUQJzNVyJl1cjIebq/rWWBF+3eDst5JGEFSc5cWxyRCJ0Mxl+KyIkqRxk1XPEs9x8TA==}
|
||||||
|
engines: {node: '>=14.0.0'}
|
||||||
|
cpu: [wasm32]
|
||||||
|
bundledDependencies:
|
||||||
|
- '@napi-rs/wasm-runtime'
|
||||||
|
- '@emnapi/core'
|
||||||
|
- '@emnapi/runtime'
|
||||||
|
- '@tybys/wasm-util'
|
||||||
|
- '@emnapi/wasi-threads'
|
||||||
|
- tslib
|
||||||
|
|
||||||
|
'@tailwindcss/oxide-win32-arm64-msvc@4.1.18':
|
||||||
|
resolution: {integrity: sha512-HjSA7mr9HmC8fu6bdsZvZ+dhjyGCLdotjVOgLA2vEqxEBZaQo9YTX4kwgEvPCpRh8o4uWc4J/wEoFzhEmjvPbA==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [win32]
|
||||||
|
|
||||||
|
'@tailwindcss/oxide-win32-x64-msvc@4.1.18':
|
||||||
|
resolution: {integrity: sha512-bJWbyYpUlqamC8dpR7pfjA0I7vdF6t5VpUGMWRkXVE3AXgIZjYUYAK7II1GNaxR8J1SSrSrppRar8G++JekE3Q==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [win32]
|
||||||
|
|
||||||
|
'@tailwindcss/oxide@4.1.18':
|
||||||
|
resolution: {integrity: sha512-EgCR5tTS5bUSKQgzeMClT6iCY3ToqE1y+ZB0AKldj809QXk1Y+3jB0upOYZrn9aGIzPtUsP7sX4QQ4XtjBB95A==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
|
||||||
|
'@tailwindcss/postcss@4.1.18':
|
||||||
|
resolution: {integrity: sha512-Ce0GFnzAOuPyfV5SxjXGn0CubwGcuDB0zcdaPuCSzAa/2vII24JTkH+I6jcbXLb1ctjZMZZI6OjDaLPJQL1S0g==}
|
||||||
|
|
||||||
|
'@tailwindcss/typography@0.5.19':
|
||||||
|
resolution: {integrity: sha512-w31dd8HOx3k9vPtcQh5QHP9GwKcgbMp87j58qi6xgiBnFFtKEAgCWnDw4qUT8aHwkCp8bKvb/KGKWWHedP0AAg==}
|
||||||
|
peerDependencies:
|
||||||
|
tailwindcss: '>=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1'
|
||||||
|
|
||||||
|
'@tailwindcss/vite@4.1.18':
|
||||||
|
resolution: {integrity: sha512-jVA+/UpKL1vRLg6Hkao5jldawNmRo7mQYrZtNHMIVpLfLhDml5nMRUo/8MwoX2vNXvnaXNNMedrMfMugAVX1nA==}
|
||||||
|
peerDependencies:
|
||||||
|
vite: ^5.2.0 || ^6 || ^7
|
||||||
|
|
||||||
'@types/debug@4.1.12':
|
'@types/debug@4.1.12':
|
||||||
resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==}
|
resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==}
|
||||||
|
|
||||||
@ -797,6 +942,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==}
|
resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==}
|
||||||
engines: {node: '>= 0.8'}
|
engines: {node: '>= 0.8'}
|
||||||
|
|
||||||
|
enhanced-resolve@5.18.4:
|
||||||
|
resolution: {integrity: sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==}
|
||||||
|
engines: {node: '>=10.13.0'}
|
||||||
|
|
||||||
entities@4.5.0:
|
entities@4.5.0:
|
||||||
resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
|
resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
|
||||||
engines: {node: '>=0.12'}
|
engines: {node: '>=0.12'}
|
||||||
@ -898,6 +1047,9 @@ packages:
|
|||||||
github-slugger@2.0.0:
|
github-slugger@2.0.0:
|
||||||
resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==}
|
resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==}
|
||||||
|
|
||||||
|
graceful-fs@4.2.11:
|
||||||
|
resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
|
||||||
|
|
||||||
h3@1.15.4:
|
h3@1.15.4:
|
||||||
resolution: {integrity: sha512-z5cFQWDffyOe4vQ9xIqNfCZdV4p//vy6fBnr8Q1AWnVZ0teurKMG66rLj++TKwKPUP3u7iMUvrvKaEUiQw2QWQ==}
|
resolution: {integrity: sha512-z5cFQWDffyOe4vQ9xIqNfCZdV4p//vy6fBnr8Q1AWnVZ0teurKMG66rLj++TKwKPUP3u7iMUvrvKaEUiQw2QWQ==}
|
||||||
|
|
||||||
@ -996,6 +1148,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==}
|
resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==}
|
||||||
engines: {node: '>=16'}
|
engines: {node: '>=16'}
|
||||||
|
|
||||||
|
jiti@2.6.1:
|
||||||
|
resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
js-yaml@4.1.1:
|
js-yaml@4.1.1:
|
||||||
resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==}
|
resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
@ -1004,6 +1160,76 @@ packages:
|
|||||||
resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==}
|
resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
|
|
||||||
|
lightningcss-android-arm64@1.30.2:
|
||||||
|
resolution: {integrity: sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==}
|
||||||
|
engines: {node: '>= 12.0.0'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [android]
|
||||||
|
|
||||||
|
lightningcss-darwin-arm64@1.30.2:
|
||||||
|
resolution: {integrity: sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==}
|
||||||
|
engines: {node: '>= 12.0.0'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [darwin]
|
||||||
|
|
||||||
|
lightningcss-darwin-x64@1.30.2:
|
||||||
|
resolution: {integrity: sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==}
|
||||||
|
engines: {node: '>= 12.0.0'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [darwin]
|
||||||
|
|
||||||
|
lightningcss-freebsd-x64@1.30.2:
|
||||||
|
resolution: {integrity: sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==}
|
||||||
|
engines: {node: '>= 12.0.0'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [freebsd]
|
||||||
|
|
||||||
|
lightningcss-linux-arm-gnueabihf@1.30.2:
|
||||||
|
resolution: {integrity: sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==}
|
||||||
|
engines: {node: '>= 12.0.0'}
|
||||||
|
cpu: [arm]
|
||||||
|
os: [linux]
|
||||||
|
|
||||||
|
lightningcss-linux-arm64-gnu@1.30.2:
|
||||||
|
resolution: {integrity: sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==}
|
||||||
|
engines: {node: '>= 12.0.0'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [linux]
|
||||||
|
|
||||||
|
lightningcss-linux-arm64-musl@1.30.2:
|
||||||
|
resolution: {integrity: sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==}
|
||||||
|
engines: {node: '>= 12.0.0'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [linux]
|
||||||
|
|
||||||
|
lightningcss-linux-x64-gnu@1.30.2:
|
||||||
|
resolution: {integrity: sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==}
|
||||||
|
engines: {node: '>= 12.0.0'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [linux]
|
||||||
|
|
||||||
|
lightningcss-linux-x64-musl@1.30.2:
|
||||||
|
resolution: {integrity: sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==}
|
||||||
|
engines: {node: '>= 12.0.0'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [linux]
|
||||||
|
|
||||||
|
lightningcss-win32-arm64-msvc@1.30.2:
|
||||||
|
resolution: {integrity: sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==}
|
||||||
|
engines: {node: '>= 12.0.0'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [win32]
|
||||||
|
|
||||||
|
lightningcss-win32-x64-msvc@1.30.2:
|
||||||
|
resolution: {integrity: sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==}
|
||||||
|
engines: {node: '>= 12.0.0'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [win32]
|
||||||
|
|
||||||
|
lightningcss@1.30.2:
|
||||||
|
resolution: {integrity: sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==}
|
||||||
|
engines: {node: '>= 12.0.0'}
|
||||||
|
|
||||||
longest-streak@3.1.0:
|
longest-streak@3.1.0:
|
||||||
resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==}
|
resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==}
|
||||||
|
|
||||||
@ -1282,6 +1508,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==}
|
resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
|
postcss-selector-parser@6.0.10:
|
||||||
|
resolution: {integrity: sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==}
|
||||||
|
engines: {node: '>=4'}
|
||||||
|
|
||||||
postcss@8.5.6:
|
postcss@8.5.6:
|
||||||
resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==}
|
resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==}
|
||||||
engines: {node: ^10 || ^12 || >=14}
|
engines: {node: ^10 || ^12 || >=14}
|
||||||
@ -1462,6 +1692,16 @@ packages:
|
|||||||
engines: {node: '>=16'}
|
engines: {node: '>=16'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
tailwind-merge@3.4.0:
|
||||||
|
resolution: {integrity: sha512-uSaO4gnW+b3Y2aWoWfFpX62vn2sR3skfhbjsEnaBI81WD1wBLlHZe5sWf0AqjksNdYTbGBEd0UasQMT3SNV15g==}
|
||||||
|
|
||||||
|
tailwindcss@4.1.18:
|
||||||
|
resolution: {integrity: sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw==}
|
||||||
|
|
||||||
|
tapable@2.3.0:
|
||||||
|
resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==}
|
||||||
|
engines: {node: '>=6'}
|
||||||
|
|
||||||
tiny-inflate@1.0.3:
|
tiny-inflate@1.0.3:
|
||||||
resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==}
|
resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==}
|
||||||
|
|
||||||
@ -1621,6 +1861,9 @@ packages:
|
|||||||
uploadthing:
|
uploadthing:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
util-deprecate@1.0.2:
|
||||||
|
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
|
||||||
|
|
||||||
vfile-location@5.0.3:
|
vfile-location@5.0.3:
|
||||||
resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==}
|
resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==}
|
||||||
|
|
||||||
@ -1696,6 +1939,11 @@ packages:
|
|||||||
xxhash-wasm@1.1.0:
|
xxhash-wasm@1.1.0:
|
||||||
resolution: {integrity: sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA==}
|
resolution: {integrity: sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA==}
|
||||||
|
|
||||||
|
yaml@2.8.2:
|
||||||
|
resolution: {integrity: sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==}
|
||||||
|
engines: {node: '>= 14.6'}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
yargs-parser@21.1.1:
|
yargs-parser@21.1.1:
|
||||||
resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
|
resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
@ -1731,6 +1979,8 @@ packages:
|
|||||||
|
|
||||||
snapshots:
|
snapshots:
|
||||||
|
|
||||||
|
'@alloc/quick-lru@5.2.0': {}
|
||||||
|
|
||||||
'@astrojs/compiler@2.13.0': {}
|
'@astrojs/compiler@2.13.0': {}
|
||||||
|
|
||||||
'@astrojs/internal-helpers@0.7.5': {}
|
'@astrojs/internal-helpers@0.7.5': {}
|
||||||
@ -1761,12 +2011,12 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
'@astrojs/mdx@4.3.13(astro@5.16.6(@types/node@25.0.3)(rollup@4.54.0)(typescript@5.9.3))':
|
'@astrojs/mdx@4.3.13(astro@5.16.6(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.54.0)(typescript@5.9.3)(yaml@2.8.2))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@astrojs/markdown-remark': 6.3.10
|
'@astrojs/markdown-remark': 6.3.10
|
||||||
'@mdx-js/mdx': 3.1.1
|
'@mdx-js/mdx': 3.1.1
|
||||||
acorn: 8.15.0
|
acorn: 8.15.0
|
||||||
astro: 5.16.6(@types/node@25.0.3)(rollup@4.54.0)(typescript@5.9.3)
|
astro: 5.16.6(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.54.0)(typescript@5.9.3)(yaml@2.8.2)
|
||||||
es-module-lexer: 1.7.0
|
es-module-lexer: 1.7.0
|
||||||
estree-util-visit: 2.0.0
|
estree-util-visit: 2.0.0
|
||||||
hast-util-to-html: 9.0.5
|
hast-util-to-html: 9.0.5
|
||||||
@ -1780,10 +2030,10 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
'@astrojs/node@9.5.1(astro@5.16.6(@types/node@25.0.3)(rollup@4.54.0)(typescript@5.9.3))':
|
'@astrojs/node@9.5.1(astro@5.16.6(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.54.0)(typescript@5.9.3)(yaml@2.8.2))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@astrojs/internal-helpers': 0.7.5
|
'@astrojs/internal-helpers': 0.7.5
|
||||||
astro: 5.16.6(@types/node@25.0.3)(rollup@4.54.0)(typescript@5.9.3)
|
astro: 5.16.6(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.54.0)(typescript@5.9.3)(yaml@2.8.2)
|
||||||
send: 1.2.1
|
send: 1.2.1
|
||||||
server-destroy: 1.0.1
|
server-destroy: 1.0.1
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
@ -1905,6 +2155,10 @@ snapshots:
|
|||||||
'@esbuild/win32-x64@0.25.12':
|
'@esbuild/win32-x64@0.25.12':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
'@fontsource-variable/ibm-plex-sans@5.2.8': {}
|
||||||
|
|
||||||
|
'@fontsource/martel@5.2.8': {}
|
||||||
|
|
||||||
'@img/colour@1.0.0':
|
'@img/colour@1.0.0':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
@ -2002,8 +2256,25 @@ snapshots:
|
|||||||
'@img/sharp-win32-x64@0.34.5':
|
'@img/sharp-win32-x64@0.34.5':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
'@jridgewell/gen-mapping@0.3.13':
|
||||||
|
dependencies:
|
||||||
|
'@jridgewell/sourcemap-codec': 1.5.5
|
||||||
|
'@jridgewell/trace-mapping': 0.3.31
|
||||||
|
|
||||||
|
'@jridgewell/remapping@2.3.5':
|
||||||
|
dependencies:
|
||||||
|
'@jridgewell/gen-mapping': 0.3.13
|
||||||
|
'@jridgewell/trace-mapping': 0.3.31
|
||||||
|
|
||||||
|
'@jridgewell/resolve-uri@3.1.2': {}
|
||||||
|
|
||||||
'@jridgewell/sourcemap-codec@1.5.5': {}
|
'@jridgewell/sourcemap-codec@1.5.5': {}
|
||||||
|
|
||||||
|
'@jridgewell/trace-mapping@0.3.31':
|
||||||
|
dependencies:
|
||||||
|
'@jridgewell/resolve-uri': 3.1.2
|
||||||
|
'@jridgewell/sourcemap-codec': 1.5.5
|
||||||
|
|
||||||
'@mdx-js/mdx@3.1.1':
|
'@mdx-js/mdx@3.1.1':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/estree': 1.0.8
|
'@types/estree': 1.0.8
|
||||||
@ -2147,6 +2418,87 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
tslib: 2.8.1
|
tslib: 2.8.1
|
||||||
|
|
||||||
|
'@tailwindcss/node@4.1.18':
|
||||||
|
dependencies:
|
||||||
|
'@jridgewell/remapping': 2.3.5
|
||||||
|
enhanced-resolve: 5.18.4
|
||||||
|
jiti: 2.6.1
|
||||||
|
lightningcss: 1.30.2
|
||||||
|
magic-string: 0.30.21
|
||||||
|
source-map-js: 1.2.1
|
||||||
|
tailwindcss: 4.1.18
|
||||||
|
|
||||||
|
'@tailwindcss/oxide-android-arm64@4.1.18':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@tailwindcss/oxide-darwin-arm64@4.1.18':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@tailwindcss/oxide-darwin-x64@4.1.18':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@tailwindcss/oxide-freebsd-x64@4.1.18':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@tailwindcss/oxide-linux-arm-gnueabihf@4.1.18':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@tailwindcss/oxide-linux-arm64-gnu@4.1.18':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@tailwindcss/oxide-linux-arm64-musl@4.1.18':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@tailwindcss/oxide-linux-x64-gnu@4.1.18':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@tailwindcss/oxide-linux-x64-musl@4.1.18':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@tailwindcss/oxide-wasm32-wasi@4.1.18':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@tailwindcss/oxide-win32-arm64-msvc@4.1.18':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@tailwindcss/oxide-win32-x64-msvc@4.1.18':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@tailwindcss/oxide@4.1.18':
|
||||||
|
optionalDependencies:
|
||||||
|
'@tailwindcss/oxide-android-arm64': 4.1.18
|
||||||
|
'@tailwindcss/oxide-darwin-arm64': 4.1.18
|
||||||
|
'@tailwindcss/oxide-darwin-x64': 4.1.18
|
||||||
|
'@tailwindcss/oxide-freebsd-x64': 4.1.18
|
||||||
|
'@tailwindcss/oxide-linux-arm-gnueabihf': 4.1.18
|
||||||
|
'@tailwindcss/oxide-linux-arm64-gnu': 4.1.18
|
||||||
|
'@tailwindcss/oxide-linux-arm64-musl': 4.1.18
|
||||||
|
'@tailwindcss/oxide-linux-x64-gnu': 4.1.18
|
||||||
|
'@tailwindcss/oxide-linux-x64-musl': 4.1.18
|
||||||
|
'@tailwindcss/oxide-wasm32-wasi': 4.1.18
|
||||||
|
'@tailwindcss/oxide-win32-arm64-msvc': 4.1.18
|
||||||
|
'@tailwindcss/oxide-win32-x64-msvc': 4.1.18
|
||||||
|
|
||||||
|
'@tailwindcss/postcss@4.1.18':
|
||||||
|
dependencies:
|
||||||
|
'@alloc/quick-lru': 5.2.0
|
||||||
|
'@tailwindcss/node': 4.1.18
|
||||||
|
'@tailwindcss/oxide': 4.1.18
|
||||||
|
postcss: 8.5.6
|
||||||
|
tailwindcss: 4.1.18
|
||||||
|
|
||||||
|
'@tailwindcss/typography@0.5.19(tailwindcss@4.1.18)':
|
||||||
|
dependencies:
|
||||||
|
postcss-selector-parser: 6.0.10
|
||||||
|
tailwindcss: 4.1.18
|
||||||
|
|
||||||
|
'@tailwindcss/vite@4.1.18(vite@6.4.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2))':
|
||||||
|
dependencies:
|
||||||
|
'@tailwindcss/node': 4.1.18
|
||||||
|
'@tailwindcss/oxide': 4.1.18
|
||||||
|
tailwindcss: 4.1.18
|
||||||
|
vite: 6.4.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)
|
||||||
|
|
||||||
'@types/debug@4.1.12':
|
'@types/debug@4.1.12':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/ms': 2.1.0
|
'@types/ms': 2.1.0
|
||||||
@ -2216,7 +2568,7 @@ snapshots:
|
|||||||
|
|
||||||
astring@1.9.0: {}
|
astring@1.9.0: {}
|
||||||
|
|
||||||
astro@5.16.6(@types/node@25.0.3)(rollup@4.54.0)(typescript@5.9.3):
|
astro@5.16.6(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.54.0)(typescript@5.9.3)(yaml@2.8.2):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@astrojs/compiler': 2.13.0
|
'@astrojs/compiler': 2.13.0
|
||||||
'@astrojs/internal-helpers': 0.7.5
|
'@astrojs/internal-helpers': 0.7.5
|
||||||
@ -2273,8 +2625,8 @@ snapshots:
|
|||||||
unist-util-visit: 5.0.0
|
unist-util-visit: 5.0.0
|
||||||
unstorage: 1.17.3
|
unstorage: 1.17.3
|
||||||
vfile: 6.0.3
|
vfile: 6.0.3
|
||||||
vite: 6.4.1(@types/node@25.0.3)
|
vite: 6.4.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)
|
||||||
vitefu: 1.1.1(vite@6.4.1(@types/node@25.0.3))
|
vitefu: 1.1.1(vite@6.4.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2))
|
||||||
xxhash-wasm: 1.1.0
|
xxhash-wasm: 1.1.0
|
||||||
yargs-parser: 21.1.1
|
yargs-parser: 21.1.1
|
||||||
yocto-spinner: 0.2.3
|
yocto-spinner: 0.2.3
|
||||||
@ -2427,8 +2779,7 @@ snapshots:
|
|||||||
|
|
||||||
destr@2.0.5: {}
|
destr@2.0.5: {}
|
||||||
|
|
||||||
detect-libc@2.1.2:
|
detect-libc@2.1.2: {}
|
||||||
optional: true
|
|
||||||
|
|
||||||
deterministic-object-hash@2.0.2:
|
deterministic-object-hash@2.0.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -2474,6 +2825,11 @@ snapshots:
|
|||||||
|
|
||||||
encodeurl@2.0.0: {}
|
encodeurl@2.0.0: {}
|
||||||
|
|
||||||
|
enhanced-resolve@5.18.4:
|
||||||
|
dependencies:
|
||||||
|
graceful-fs: 4.2.11
|
||||||
|
tapable: 2.3.0
|
||||||
|
|
||||||
entities@4.5.0: {}
|
entities@4.5.0: {}
|
||||||
|
|
||||||
entities@6.0.1: {}
|
entities@6.0.1: {}
|
||||||
@ -2602,6 +2958,8 @@ snapshots:
|
|||||||
|
|
||||||
github-slugger@2.0.0: {}
|
github-slugger@2.0.0: {}
|
||||||
|
|
||||||
|
graceful-fs@4.2.11: {}
|
||||||
|
|
||||||
h3@1.15.4:
|
h3@1.15.4:
|
||||||
dependencies:
|
dependencies:
|
||||||
cookie-es: 1.2.2
|
cookie-es: 1.2.2
|
||||||
@ -2789,12 +3147,63 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
is-inside-container: 1.0.0
|
is-inside-container: 1.0.0
|
||||||
|
|
||||||
|
jiti@2.6.1: {}
|
||||||
|
|
||||||
js-yaml@4.1.1:
|
js-yaml@4.1.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
argparse: 2.0.1
|
argparse: 2.0.1
|
||||||
|
|
||||||
kleur@3.0.3: {}
|
kleur@3.0.3: {}
|
||||||
|
|
||||||
|
lightningcss-android-arm64@1.30.2:
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
lightningcss-darwin-arm64@1.30.2:
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
lightningcss-darwin-x64@1.30.2:
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
lightningcss-freebsd-x64@1.30.2:
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
lightningcss-linux-arm-gnueabihf@1.30.2:
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
lightningcss-linux-arm64-gnu@1.30.2:
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
lightningcss-linux-arm64-musl@1.30.2:
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
lightningcss-linux-x64-gnu@1.30.2:
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
lightningcss-linux-x64-musl@1.30.2:
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
lightningcss-win32-arm64-msvc@1.30.2:
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
lightningcss-win32-x64-msvc@1.30.2:
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
lightningcss@1.30.2:
|
||||||
|
dependencies:
|
||||||
|
detect-libc: 2.1.2
|
||||||
|
optionalDependencies:
|
||||||
|
lightningcss-android-arm64: 1.30.2
|
||||||
|
lightningcss-darwin-arm64: 1.30.2
|
||||||
|
lightningcss-darwin-x64: 1.30.2
|
||||||
|
lightningcss-freebsd-x64: 1.30.2
|
||||||
|
lightningcss-linux-arm-gnueabihf: 1.30.2
|
||||||
|
lightningcss-linux-arm64-gnu: 1.30.2
|
||||||
|
lightningcss-linux-arm64-musl: 1.30.2
|
||||||
|
lightningcss-linux-x64-gnu: 1.30.2
|
||||||
|
lightningcss-linux-x64-musl: 1.30.2
|
||||||
|
lightningcss-win32-arm64-msvc: 1.30.2
|
||||||
|
lightningcss-win32-x64-msvc: 1.30.2
|
||||||
|
|
||||||
longest-streak@3.1.0: {}
|
longest-streak@3.1.0: {}
|
||||||
|
|
||||||
lru-cache@10.4.3: {}
|
lru-cache@10.4.3: {}
|
||||||
@ -3344,6 +3753,11 @@ snapshots:
|
|||||||
|
|
||||||
picomatch@4.0.3: {}
|
picomatch@4.0.3: {}
|
||||||
|
|
||||||
|
postcss-selector-parser@6.0.10:
|
||||||
|
dependencies:
|
||||||
|
cssesc: 3.0.0
|
||||||
|
util-deprecate: 1.0.2
|
||||||
|
|
||||||
postcss@8.5.6:
|
postcss@8.5.6:
|
||||||
dependencies:
|
dependencies:
|
||||||
nanoid: 3.3.11
|
nanoid: 3.3.11
|
||||||
@ -3662,6 +4076,12 @@ snapshots:
|
|||||||
picocolors: 1.1.1
|
picocolors: 1.1.1
|
||||||
sax: 1.4.3
|
sax: 1.4.3
|
||||||
|
|
||||||
|
tailwind-merge@3.4.0: {}
|
||||||
|
|
||||||
|
tailwindcss@4.1.18: {}
|
||||||
|
|
||||||
|
tapable@2.3.0: {}
|
||||||
|
|
||||||
tiny-inflate@1.0.3: {}
|
tiny-inflate@1.0.3: {}
|
||||||
|
|
||||||
tinyexec@1.0.2: {}
|
tinyexec@1.0.2: {}
|
||||||
@ -3778,6 +4198,8 @@ snapshots:
|
|||||||
ofetch: 1.5.1
|
ofetch: 1.5.1
|
||||||
ufo: 1.6.1
|
ufo: 1.6.1
|
||||||
|
|
||||||
|
util-deprecate@1.0.2: {}
|
||||||
|
|
||||||
vfile-location@5.0.3:
|
vfile-location@5.0.3:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/unist': 3.0.3
|
'@types/unist': 3.0.3
|
||||||
@ -3793,7 +4215,7 @@ snapshots:
|
|||||||
'@types/unist': 3.0.3
|
'@types/unist': 3.0.3
|
||||||
vfile-message: 4.0.3
|
vfile-message: 4.0.3
|
||||||
|
|
||||||
vite@6.4.1(@types/node@25.0.3):
|
vite@6.4.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2):
|
||||||
dependencies:
|
dependencies:
|
||||||
esbuild: 0.25.12
|
esbuild: 0.25.12
|
||||||
fdir: 6.5.0(picomatch@4.0.3)
|
fdir: 6.5.0(picomatch@4.0.3)
|
||||||
@ -3804,10 +4226,13 @@ snapshots:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@types/node': 25.0.3
|
'@types/node': 25.0.3
|
||||||
fsevents: 2.3.3
|
fsevents: 2.3.3
|
||||||
|
jiti: 2.6.1
|
||||||
|
lightningcss: 1.30.2
|
||||||
|
yaml: 2.8.2
|
||||||
|
|
||||||
vitefu@1.1.1(vite@6.4.1(@types/node@25.0.3)):
|
vitefu@1.1.1(vite@6.4.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)):
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
vite: 6.4.1(@types/node@25.0.3)
|
vite: 6.4.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)
|
||||||
|
|
||||||
web-namespaces@2.0.1: {}
|
web-namespaces@2.0.1: {}
|
||||||
|
|
||||||
@ -3825,6 +4250,9 @@ snapshots:
|
|||||||
|
|
||||||
xxhash-wasm@1.1.0: {}
|
xxhash-wasm@1.1.0: {}
|
||||||
|
|
||||||
|
yaml@2.8.2:
|
||||||
|
optional: true
|
||||||
|
|
||||||
yargs-parser@21.1.1: {}
|
yargs-parser@21.1.1: {}
|
||||||
|
|
||||||
yocto-queue@1.2.2: {}
|
yocto-queue@1.2.2: {}
|
||||||
|
|||||||
27
src/components/ArrowCard.astro
Normal file
27
src/components/ArrowCard.astro
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
---
|
||||||
|
import type { CollectionEntry } from "astro:content";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
entry: CollectionEntry<"blog"> | CollectionEntry<"projects">;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { entry } = Astro.props;
|
||||||
|
---
|
||||||
|
|
||||||
|
<a href={`/${entry.collection}/${entry.slug}`} class="relative group flex flex-nowrap py-3 px-4 pr-10 rounded-lg border border-black/15 dark:border-white/20 hover:bg-black/5 dark:hover:bg-white/5 hover:text-black dark:hover:text-white transition-colors duration-300 ease-in-out">
|
||||||
|
<div class="flex flex-col flex-1 truncate">
|
||||||
|
<div class="font-semibold">
|
||||||
|
{entry.data.title}
|
||||||
|
</div>
|
||||||
|
<div class="text-sm">
|
||||||
|
{entry.data.description}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
class="absolute top-1/2 right-2 -translate-y-1/2 size-5 stroke-2 fill-none stroke-current">
|
||||||
|
<line x1="5" y1="12" x2="19" y2="12" class="translate-x-3 group-hover:translate-x-0 scale-x-0 group-hover:scale-x-100 transition-transform duration-300 ease-in-out" />
|
||||||
|
<polyline points="12 5 19 12 12 19" class="-translate-x-1 group-hover:translate-x-0 transition-transform duration-300 ease-in-out" />
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
20
src/components/BackToPrev.astro
Normal file
20
src/components/BackToPrev.astro
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
---
|
||||||
|
type Props = {
|
||||||
|
href: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { href } = Astro.props;
|
||||||
|
---
|
||||||
|
|
||||||
|
<a href={href} class="relative group w-fit flex pl-7 pr-3 py-1.5 flex-nowrap rounded border border-black/15 dark:border-white/20 hover:bg-black/5 dark:hover:bg-white/5 hover:text-black dark:hover:text-white transition-colors duration-300 ease-in-out">
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
class="absolute top-1/2 left-2 -translate-y-1/2 size-4 stroke-2 fill-none stroke-current">
|
||||||
|
<line x1="5" y1="12" x2="19" y2="12" class="translate-x-2 group-hover:translate-x-0 scale-x-0 group-hover:scale-x-100 transition-transform duration-300 ease-in-out" />
|
||||||
|
<polyline points="12 5 5 12 12 19" class="translate-x-1 group-hover:translate-x-0 transition-transform duration-300 ease-in-out" />
|
||||||
|
</svg>
|
||||||
|
<div class="text-sm">
|
||||||
|
<slot/>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
12
src/components/BackToTop.astro
Normal file
12
src/components/BackToTop.astro
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<button id="back-to-top" class="relative group w-fit flex pl-8 pr-3 py-1.5 flex-nowrap rounded border border-black/15 dark:border-white/20 hover:bg-black/5 dark:hover:bg-white/5 hover:text-black dark:hover:text-white transition-colors duration-300 ease-in-out">
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
class="absolute top-1/2 left-2 -translate-y-1/2 size-4 stroke-2 fill-none stroke-current rotate-90">
|
||||||
|
<line x1="5" y1="12" x2="19" y2="12" class="translate-x-2 group-hover:translate-x-0 scale-x-0 group-hover:scale-x-100 transition-transform duration-300 ease-in-out" />
|
||||||
|
<polyline points="12 5 5 12 12 19" class="translate-x-1 group-hover:translate-x-0 transition-transform duration-300 ease-in-out" />
|
||||||
|
</svg>
|
||||||
|
<div class="text-sm">
|
||||||
|
Back to top
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
7
src/components/Container.astro
Normal file
7
src/components/Container.astro
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<div class="mx-auto max-w-screen-sm px-5">
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
93
src/components/Footer.astro
Normal file
93
src/components/Footer.astro
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
---
|
||||||
|
import Container from "@components/Container.astro";
|
||||||
|
import { SITE } from "@consts";
|
||||||
|
import BackToTop from "@components/BackToTop.astro";
|
||||||
|
---
|
||||||
|
|
||||||
|
<footer class="animate">
|
||||||
|
<Container>
|
||||||
|
<div class="relative">
|
||||||
|
<div class="absolute right-0 -top-20">
|
||||||
|
<BackToTop />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex justify-between items-center">
|
||||||
|
<div>
|
||||||
|
© {new Date().getFullYear()} ·
|
||||||
|
{SITE.NAME}
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-wrap gap-1 items-center">
|
||||||
|
<button
|
||||||
|
id="light-theme-button"
|
||||||
|
aria-label="Light theme"
|
||||||
|
class="group size-8 flex items-center justify-center rounded-full"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="18"
|
||||||
|
height="18"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="1.5"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
class="group-hover:stroke-black group-hover:dark:stroke-white transition-colors duration-300 ease-in-out"
|
||||||
|
>
|
||||||
|
<circle cx="12" cy="12" r="5"></circle>
|
||||||
|
<line x1="12" y1="1" x2="12" y2="3"></line>
|
||||||
|
<line x1="12" y1="21" x2="12" y2="23"></line>
|
||||||
|
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
|
||||||
|
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
|
||||||
|
<line x1="1" y1="12" x2="3" y2="12"></line>
|
||||||
|
<line x1="21" y1="12" x2="23" y2="12"></line>
|
||||||
|
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
|
||||||
|
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
id="dark-theme-button"
|
||||||
|
aria-label="Dark theme"
|
||||||
|
class="group size-8 flex items-center justify-center rounded-full"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="18"
|
||||||
|
height="18"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="1.5"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
class="group-hover:stroke-black group-hover:dark:stroke-white transition-colors duration-300 ease-in-out"
|
||||||
|
>
|
||||||
|
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
id="system-theme-button"
|
||||||
|
aria-label="System theme"
|
||||||
|
class="group size-8 flex items-center justify-center rounded-full"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="18"
|
||||||
|
height="18"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="1.5"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
class="group-hover:stroke-black group-hover:dark:stroke-white transition-colors duration-300 ease-in-out"
|
||||||
|
>
|
||||||
|
<rect x="2" y="3" width="20" height="14" rx="2" ry="2"></rect>
|
||||||
|
<line x1="8" y1="21" x2="16" y2="21"></line>
|
||||||
|
<line x1="12" y1="17" x2="12" y2="21"></line>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Container>
|
||||||
|
</footer>
|
||||||
17
src/components/FormattedDate.astro
Normal file
17
src/components/FormattedDate.astro
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
---
|
||||||
|
interface Props {
|
||||||
|
date: Date;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { date } = Astro.props;
|
||||||
|
---
|
||||||
|
|
||||||
|
<time datetime={date.toISOString()}>
|
||||||
|
{
|
||||||
|
date.toLocaleDateString("en-us", {
|
||||||
|
month: "short",
|
||||||
|
day: "numeric",
|
||||||
|
year: "numeric",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</time>
|
||||||
198
src/components/Head.astro
Normal file
198
src/components/Head.astro
Normal file
@ -0,0 +1,198 @@
|
|||||||
|
---
|
||||||
|
import "../styles/global.css";
|
||||||
|
import "@fontsource/martel/latin-400.css";
|
||||||
|
import "@fontsource/martel/latin-600.css";
|
||||||
|
import "@fontsource-variable/ibm-plex-sans";
|
||||||
|
// import martel400 from "@fontsource/martel/files/martel-latin-400-normal.woff2";
|
||||||
|
// import martel600 from "@fontsource/martel/files/martel-latin-600-normal.woff2";
|
||||||
|
// import plex from "@fontsource/ibm-plex-sans/files/ibm-plex-sans-latin-400-normal.woff2";
|
||||||
|
|
||||||
|
import { ClientRouter } from "astro:transitions";
|
||||||
|
import { SITE } from "@consts";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
image?: string;
|
||||||
|
}
|
||||||
|
const canonicalURL = new URL(Astro.url.pathname, Astro.site);
|
||||||
|
|
||||||
|
const { title, description, image = "/nano.png" } = Astro.props;
|
||||||
|
---
|
||||||
|
|
||||||
|
<!-- Global Metadata -->
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||||
|
<link
|
||||||
|
rel="icon"
|
||||||
|
type="image/svg+xml"
|
||||||
|
href="/favicon-dark.svg"
|
||||||
|
media="(prefers-color-scheme: dark)"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="icon"
|
||||||
|
type="image/svg+xml"
|
||||||
|
href="/favicon-light.svg"
|
||||||
|
media="(prefers-color-scheme: light)"
|
||||||
|
/>
|
||||||
|
<link rel="icon" type="image/x-icon" href="/favicon-light.svg" />
|
||||||
|
<meta name="generator" content={Astro.generator} />
|
||||||
|
|
||||||
|
<!-- Font preloads -->
|
||||||
|
<!-- <link rel="preload" href={martel400} as="font" type="font/woff2" crossorigin />
|
||||||
|
<link rel="preload" href={martel600} as="font" type="font/woff2" crossorigin />
|
||||||
|
<link rel="preload" href={plex400} as="font" type="font/woff2" crossorigin />
|
||||||
|
<link rel="preload" href={plex600} as="font" type="font/woff2" crossorigin /> -->
|
||||||
|
|
||||||
|
<!-- Canonical URL -->
|
||||||
|
<link rel="canonical" href={canonicalURL} />
|
||||||
|
|
||||||
|
<!-- Primary Meta Tags -->
|
||||||
|
<title>{title}</title>
|
||||||
|
<meta name="title" content={title} />
|
||||||
|
<meta name="description" content={description} />
|
||||||
|
|
||||||
|
<!-- Open Graph / Facebook -->
|
||||||
|
<meta property="og:type" content="website" />
|
||||||
|
<meta property="og:url" content={Astro.url} />
|
||||||
|
<meta property="og:title" content={title} />
|
||||||
|
<meta property="og:description" content={description} />
|
||||||
|
<meta property="og:image" content={new URL(image, Astro.url)} />
|
||||||
|
|
||||||
|
<!-- Twitter -->
|
||||||
|
<meta property="twitter:card" content="summary_large_image" />
|
||||||
|
<meta property="twitter:url" content={Astro.url} />
|
||||||
|
<meta property="twitter:title" content={title} />
|
||||||
|
<meta property="twitter:description" content={description} />
|
||||||
|
<meta property="twitter:image" content={new URL(image, Astro.url)} />
|
||||||
|
|
||||||
|
<ClientRouter />
|
||||||
|
|
||||||
|
<!-- RSS Link -->
|
||||||
|
<link
|
||||||
|
rel="alternate"
|
||||||
|
type="application/rss+xml"
|
||||||
|
title={SITE.NAME}
|
||||||
|
href={new URL("rss.xml", Astro.site)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import type { TransitionBeforeSwapEvent } from "astro:transitions/client";
|
||||||
|
document.addEventListener("astro:before-swap", (e) =>
|
||||||
|
[
|
||||||
|
...(e as TransitionBeforeSwapEvent).newDocument.head.querySelectorAll(
|
||||||
|
'link[as="font"]'
|
||||||
|
),
|
||||||
|
].forEach((link) => link.remove())
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script is:inline>
|
||||||
|
function init() {
|
||||||
|
preloadTheme();
|
||||||
|
onScroll();
|
||||||
|
animate();
|
||||||
|
|
||||||
|
const backToTop = document.getElementById("back-to-top");
|
||||||
|
backToTop?.addEventListener("click", (event) => scrollToTop(event));
|
||||||
|
|
||||||
|
const backToPrev = document.getElementById("back-to-prev");
|
||||||
|
backToPrev?.addEventListener("click", () => window.history.back());
|
||||||
|
|
||||||
|
const lightThemeButton = document.getElementById("light-theme-button");
|
||||||
|
lightThemeButton?.addEventListener("click", () => {
|
||||||
|
localStorage.setItem("theme", "light");
|
||||||
|
toggleTheme(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
const darkThemeButton = document.getElementById("dark-theme-button");
|
||||||
|
darkThemeButton?.addEventListener("click", () => {
|
||||||
|
localStorage.setItem("theme", "dark");
|
||||||
|
toggleTheme(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
const systemThemeButton = document.getElementById("system-theme-button");
|
||||||
|
systemThemeButton?.addEventListener("click", () => {
|
||||||
|
localStorage.setItem("theme", "system");
|
||||||
|
toggleTheme(window.matchMedia("(prefers-color-scheme: dark)").matches);
|
||||||
|
});
|
||||||
|
|
||||||
|
window
|
||||||
|
.matchMedia("(prefers-color-scheme: dark)")
|
||||||
|
.addEventListener("change", (event) => {
|
||||||
|
if (localStorage.theme === "system" || !localStorage.theme) {
|
||||||
|
toggleTheme(event.matches);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
document.addEventListener("scroll", onScroll);
|
||||||
|
}
|
||||||
|
|
||||||
|
function animate() {
|
||||||
|
const animateElements = document.querySelectorAll(".animate");
|
||||||
|
|
||||||
|
animateElements.forEach((element, index) => {
|
||||||
|
setTimeout(() => {
|
||||||
|
element.classList.add("show");
|
||||||
|
}, index * 150);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function onScroll() {
|
||||||
|
if (window.scrollY > 0) {
|
||||||
|
document.documentElement.classList.add("scrolled");
|
||||||
|
} else {
|
||||||
|
document.documentElement.classList.remove("scrolled");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function scrollToTop(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
window.scrollTo({
|
||||||
|
top: 0,
|
||||||
|
behavior: "smooth",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleTheme(dark) {
|
||||||
|
const css = document.createElement("style");
|
||||||
|
|
||||||
|
css.appendChild(
|
||||||
|
document.createTextNode(
|
||||||
|
`* {
|
||||||
|
-webkit-transition: none !important;
|
||||||
|
-moz-transition: none !important;
|
||||||
|
-o-transition: none !important;
|
||||||
|
-ms-transition: none !important;
|
||||||
|
transition: none !important;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
document.head.appendChild(css);
|
||||||
|
|
||||||
|
if (dark) {
|
||||||
|
document.documentElement.classList.add("dark");
|
||||||
|
} else {
|
||||||
|
document.documentElement.classList.remove("dark");
|
||||||
|
}
|
||||||
|
|
||||||
|
window.getComputedStyle(css).opacity;
|
||||||
|
document.head.removeChild(css);
|
||||||
|
}
|
||||||
|
|
||||||
|
function preloadTheme() {
|
||||||
|
const userTheme = localStorage.theme;
|
||||||
|
|
||||||
|
if (userTheme === "light" || userTheme === "dark") {
|
||||||
|
toggleTheme(userTheme === "dark");
|
||||||
|
} else {
|
||||||
|
toggleTheme(window.matchMedia("(prefers-color-scheme: dark)").matches);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener("DOMContentLoaded", () => init());
|
||||||
|
document.addEventListener("astro:after-swap", () => init());
|
||||||
|
preloadTheme();
|
||||||
|
</script>
|
||||||
34
src/components/Header.astro
Normal file
34
src/components/Header.astro
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
---
|
||||||
|
import Container from "@components/Container.astro";
|
||||||
|
import Link from "@components/Link.astro";
|
||||||
|
import { SITE } from "@consts";
|
||||||
|
---
|
||||||
|
|
||||||
|
<header>
|
||||||
|
<Container>
|
||||||
|
<div class="flex flex-wrap gap-y-2 justify-between">
|
||||||
|
<Link href="/" underline={false}>
|
||||||
|
<div class="font-semibold">
|
||||||
|
{SITE.NAME}
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
<nav class="flex gap-1">
|
||||||
|
<Link href="/blog">
|
||||||
|
blog
|
||||||
|
</Link>
|
||||||
|
<span>
|
||||||
|
{`/`}
|
||||||
|
</span>
|
||||||
|
<Link href="/work">
|
||||||
|
work
|
||||||
|
</Link>
|
||||||
|
<span>
|
||||||
|
{`/`}
|
||||||
|
</span>
|
||||||
|
<Link href="/projects">
|
||||||
|
projects
|
||||||
|
</Link>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</Container>
|
||||||
|
</header>
|
||||||
19
src/components/Link.astro
Normal file
19
src/components/Link.astro
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
---
|
||||||
|
import { cn } from "@lib/utils";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
href: string;
|
||||||
|
external?: boolean;
|
||||||
|
underline?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { href, external, underline = true, ...rest } = Astro.props;
|
||||||
|
---
|
||||||
|
|
||||||
|
<a
|
||||||
|
href={href}
|
||||||
|
target={ external ? "_blank" : "_self" }
|
||||||
|
class={cn("inline-block decoration-black/15 dark:decoration-white/30 hover:decoration-black/25 hover:dark:decoration-white/50 text-current hover:text-black hover:dark:text-white transition-colors duration-300 ease-in-out", underline && "underline underline-offset-2")}
|
||||||
|
{...rest}>
|
||||||
|
<slot/>
|
||||||
|
</a>
|
||||||
44
src/consts.ts
Normal file
44
src/consts.ts
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
import type { Site, Metadata, Socials } from "@types";
|
||||||
|
|
||||||
|
export const SITE: Site = {
|
||||||
|
NAME: "Ryan Pandya",
|
||||||
|
EMAIL: "ryan@ryanpandya.com",
|
||||||
|
NUM_POSTS_ON_HOMEPAGE: 3,
|
||||||
|
NUM_WORKS_ON_HOMEPAGE: 2,
|
||||||
|
NUM_PROJECTS_ON_HOMEPAGE: 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const HOME: Metadata = {
|
||||||
|
TITLE: "Home",
|
||||||
|
DESCRIPTION: "Astro Nano is a minimal and lightweight blog and portfolio.",
|
||||||
|
};
|
||||||
|
|
||||||
|
export const BLOG: Metadata = {
|
||||||
|
TITLE: "Blog",
|
||||||
|
DESCRIPTION: "A collection of articles on topics I am passionate about.",
|
||||||
|
};
|
||||||
|
|
||||||
|
export const WORK: Metadata = {
|
||||||
|
TITLE: "Work",
|
||||||
|
DESCRIPTION: "Where I have worked and what I have done.",
|
||||||
|
};
|
||||||
|
|
||||||
|
export const PROJECTS: Metadata = {
|
||||||
|
TITLE: "Projects",
|
||||||
|
DESCRIPTION: "A collection of my projects, with links to repositories and demos.",
|
||||||
|
};
|
||||||
|
|
||||||
|
export const SOCIALS: Socials = [
|
||||||
|
{
|
||||||
|
NAME: "twitter-x",
|
||||||
|
HREF: "https://twitter.com/markhorn_dev",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
NAME: "github",
|
||||||
|
HREF: "https://github.com/markhorn-dev"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
NAME: "linkedin",
|
||||||
|
HREF: "https://www.linkedin.com/in/markhorn-dev",
|
||||||
|
}
|
||||||
|
];
|
||||||
13
src/content/config.ts
Normal file
13
src/content/config.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import { defineCollection, z } from "astro:content";
|
||||||
|
|
||||||
|
const blog = defineCollection({
|
||||||
|
type: "content",
|
||||||
|
schema: z.object({
|
||||||
|
title: z.string(),
|
||||||
|
description: z.string(),
|
||||||
|
date: z.coerce.date(),
|
||||||
|
draft: z.boolean().optional(),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const collections = { blog };
|
||||||
27
src/layouts/PageLayout.astro
Normal file
27
src/layouts/PageLayout.astro
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
---
|
||||||
|
import Head from "@components/Head.astro";
|
||||||
|
import Header from "@components/Header.astro";
|
||||||
|
import Footer from "@components/Footer.astro";
|
||||||
|
import { SITE } from "@consts";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const { title, description } = Astro.props;
|
||||||
|
---
|
||||||
|
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<Head title={`${title} | ${SITE.NAME}`} description={description} />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<Header />
|
||||||
|
<main>
|
||||||
|
<slot />
|
||||||
|
</main>
|
||||||
|
<Footer />
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
40
src/lib/utils.ts
Normal file
40
src/lib/utils.ts
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import { clsx, type ClassValue } from "clsx";
|
||||||
|
import { twMerge } from "tailwind-merge";
|
||||||
|
|
||||||
|
export function cn(...inputs: ClassValue[]) {
|
||||||
|
return twMerge(clsx(inputs));
|
||||||
|
}
|
||||||
|
|
||||||
|
export function formatDate(date: Date) {
|
||||||
|
return Intl.DateTimeFormat("en-US", {
|
||||||
|
month: "short",
|
||||||
|
day: "2-digit",
|
||||||
|
year: "numeric"
|
||||||
|
}).format(date);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function readingTime(html: string) {
|
||||||
|
const textOnly = html.replace(/<[^>]+>/g, "");
|
||||||
|
const wordCount = textOnly.split(/\s+/).length;
|
||||||
|
const readingTimeMinutes = ((wordCount / 200) + 1).toFixed();
|
||||||
|
return `${readingTimeMinutes} min read`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function dateRange(startDate: Date, endDate?: Date | string): string {
|
||||||
|
const startMonth = startDate.toLocaleString("default", { month: "short" });
|
||||||
|
const startYear = startDate.getFullYear().toString();
|
||||||
|
let endMonth;
|
||||||
|
let endYear;
|
||||||
|
|
||||||
|
if (endDate) {
|
||||||
|
if (typeof endDate === "string") {
|
||||||
|
endMonth = "";
|
||||||
|
endYear = endDate;
|
||||||
|
} else {
|
||||||
|
endMonth = endDate.toLocaleString("default", { month: "short" });
|
||||||
|
endYear = endDate.getFullYear().toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return `${startMonth}${startYear} - ${endMonth}${endYear}`;
|
||||||
|
}
|
||||||
52
src/pages/blog/index.astro
Normal file
52
src/pages/blog/index.astro
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
---
|
||||||
|
import { type CollectionEntry, getCollection } from "astro:content";
|
||||||
|
import PageLayout from "@layouts/PageLayout.astro";
|
||||||
|
import Container from "@components/Container.astro";
|
||||||
|
import ArrowCard from "@components/ArrowCard.astro";
|
||||||
|
import { BLOG } from "@consts";
|
||||||
|
|
||||||
|
const data = (await getCollection("blog"))
|
||||||
|
.filter((post) => !post.data.draft)
|
||||||
|
.sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf());
|
||||||
|
|
||||||
|
type Acc = {
|
||||||
|
[year: string]: CollectionEntry<"blog">[];
|
||||||
|
};
|
||||||
|
|
||||||
|
const posts = data.reduce((acc: Acc, post) => {
|
||||||
|
const year = post.data.date.getFullYear().toString();
|
||||||
|
if (!acc[year]) {
|
||||||
|
acc[year] = [];
|
||||||
|
}
|
||||||
|
acc[year].push(post);
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
const years = Object.keys(posts).sort((a, b) => parseInt(b) - parseInt(a));
|
||||||
|
---
|
||||||
|
|
||||||
|
<PageLayout title={BLOG.TITLE} description={BLOG.DESCRIPTION}>
|
||||||
|
<Container>
|
||||||
|
<div class="space-y-10">
|
||||||
|
<div class="animate font-semibold text-black dark:text-white">Blog</div>
|
||||||
|
<div class="space-y-4">
|
||||||
|
{
|
||||||
|
years.map((year) => (
|
||||||
|
<section class="animate space-y-4">
|
||||||
|
<div class="font-semibold text-black dark:text-white">{year}</div>
|
||||||
|
<div>
|
||||||
|
<ul class="flex flex-col gap-4">
|
||||||
|
{posts[year].map((post) => (
|
||||||
|
<li>
|
||||||
|
<ArrowCard entry={post} />
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Container>
|
||||||
|
</PageLayout>
|
||||||
72
src/styles/global.css
Normal file
72
src/styles/global.css
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
@import "tailwindcss";
|
||||||
|
@plugin "@tailwindcss/typography";
|
||||||
|
|
||||||
|
html {
|
||||||
|
overflow-y: scroll;
|
||||||
|
color-scheme: light;
|
||||||
|
}
|
||||||
|
|
||||||
|
html.dark {
|
||||||
|
color-scheme: dark;
|
||||||
|
}
|
||||||
|
|
||||||
|
html,
|
||||||
|
body {
|
||||||
|
@apply size-full;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
@apply font-sans antialiased;
|
||||||
|
@apply flex flex-col;
|
||||||
|
@apply bg-stone-100 dark:bg-stone-900;
|
||||||
|
@apply text-black/50 dark:text-white/75;
|
||||||
|
}
|
||||||
|
|
||||||
|
header {
|
||||||
|
@apply fixed top-0 left-0 right-0 z-50 py-5;
|
||||||
|
@apply bg-stone-100/75 dark:bg-stone-900/25;
|
||||||
|
@apply backdrop-blur-sm saturate-200;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
@apply flex-1 py-32;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer {
|
||||||
|
@apply py-5 text-sm;
|
||||||
|
}
|
||||||
|
|
||||||
|
article {
|
||||||
|
@apply max-w-full prose dark:prose-invert prose-img:mx-auto prose-img:my-auto;
|
||||||
|
@apply prose-headings:font-semibold prose-p:font-serif;
|
||||||
|
@apply prose-headings:text-black prose-headings:dark:text-white;
|
||||||
|
}
|
||||||
|
|
||||||
|
@layer utilities {
|
||||||
|
article a {
|
||||||
|
@apply font-sans text-current underline underline-offset-2;
|
||||||
|
@apply decoration-black/15 dark:decoration-white/30;
|
||||||
|
@apply transition-colors duration-300 ease-in-out;
|
||||||
|
}
|
||||||
|
article a:hover {
|
||||||
|
@apply text-black dark:text-white;
|
||||||
|
@apply decoration-black/25 dark:decoration-white/50;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate {
|
||||||
|
@apply opacity-0 translate-y-3;
|
||||||
|
@apply transition-all duration-700 ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate.show {
|
||||||
|
@apply opacity-100 translate-y-0;
|
||||||
|
}
|
||||||
|
|
||||||
|
html #back-to-top {
|
||||||
|
@apply opacity-0 pointer-events-none;
|
||||||
|
}
|
||||||
|
|
||||||
|
html.scrolled #back-to-top {
|
||||||
|
@apply opacity-100 pointer-events-auto;
|
||||||
|
}
|
||||||
17
src/types.ts
Normal file
17
src/types.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
export type Site = {
|
||||||
|
NAME: string;
|
||||||
|
EMAIL: string;
|
||||||
|
NUM_POSTS_ON_HOMEPAGE: number;
|
||||||
|
NUM_WORKS_ON_HOMEPAGE: number;
|
||||||
|
NUM_PROJECTS_ON_HOMEPAGE: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type Metadata = {
|
||||||
|
TITLE: string;
|
||||||
|
DESCRIPTION: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type Socials = {
|
||||||
|
NAME: string;
|
||||||
|
HREF: string;
|
||||||
|
}[];
|
||||||
20
tailwind.config.mjs
Normal file
20
tailwind.config.mjs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import defaultTheme from "tailwindcss/defaultTheme";
|
||||||
|
|
||||||
|
/** @type {import('tailwindcss').Config} */
|
||||||
|
export default {
|
||||||
|
darkMode: ["class"],
|
||||||
|
content: [
|
||||||
|
"./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}",
|
||||||
|
],
|
||||||
|
theme: {
|
||||||
|
extend: {
|
||||||
|
fontFamily: {
|
||||||
|
sans: ["IBM Plex Sans", ...defaultTheme.fontFamily.sans],
|
||||||
|
serif: ["Martel", ...defaultTheme.fontFamily.serif],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
plugins: [require("@tailwindcss/typography"),
|
||||||
|
require("@tailwindcss/postcss")
|
||||||
|
],
|
||||||
|
};
|
||||||
@ -1,5 +1,12 @@
|
|||||||
{
|
{
|
||||||
"extends": "astro/tsconfigs/strict",
|
"extends": "astro/tsconfigs/strict",
|
||||||
"include": [".astro/types.d.ts", "**/*"],
|
"include": [".astro/types.d.ts", "**/*"],
|
||||||
"exclude": ["dist"]
|
"exclude": ["dist"],
|
||||||
}
|
"compilerOptions": {
|
||||||
|
"strictNullChecks": true,
|
||||||
|
"baseUrl": ".",
|
||||||
|
"paths": {
|
||||||
|
"@*": ["./src/*"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user