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 mdx from '@astrojs/mdx';
|
||||
|
||||
import node from '@astrojs/node';
|
||||
import tailwindcss from '@tailwindcss/vite';
|
||||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
site: 'https://ryanpandya.com',
|
||||
integrations: [mdx()],
|
||||
|
||||
adapter: node({
|
||||
mode: 'standalone'
|
||||
})
|
||||
}),
|
||||
|
||||
vite: {
|
||||
plugins: [tailwindcss()],
|
||||
},
|
||||
});
|
||||
10
package.json
10
package.json
@ -11,6 +11,14 @@
|
||||
"dependencies": {
|
||||
"@astrojs/mdx": "^4.3.13",
|
||||
"@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:
|
||||
'@astrojs/mdx':
|
||||
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':
|
||||
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:
|
||||
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:
|
||||
|
||||
'@alloc/quick-lru@5.2.0':
|
||||
resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
'@astrojs/compiler@2.13.0':
|
||||
resolution: {integrity: sha512-mqVORhUJViA28fwHYaWmsXSzLO9osbdZ5ImUfxBarqsYdMlPbqAqGJCxsNzvppp1BEzc1mJNjOVvQqeDN8Vspw==}
|
||||
|
||||
@ -228,6 +256,12 @@ packages:
|
||||
cpu: [x64]
|
||||
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':
|
||||
resolution: {integrity: sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==}
|
||||
engines: {node: '>=18'}
|
||||
@ -365,9 +399,22 @@ packages:
|
||||
cpu: [x64]
|
||||
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':
|
||||
resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==}
|
||||
|
||||
'@jridgewell/trace-mapping@0.3.31':
|
||||
resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
|
||||
|
||||
'@mdx-js/mdx@3.1.1':
|
||||
resolution: {integrity: sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==}
|
||||
|
||||
@ -517,6 +564,104 @@ packages:
|
||||
'@swc/helpers@0.5.18':
|
||||
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':
|
||||
resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==}
|
||||
|
||||
@ -797,6 +942,10 @@ packages:
|
||||
resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==}
|
||||
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:
|
||||
resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
|
||||
engines: {node: '>=0.12'}
|
||||
@ -898,6 +1047,9 @@ packages:
|
||||
github-slugger@2.0.0:
|
||||
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:
|
||||
resolution: {integrity: sha512-z5cFQWDffyOe4vQ9xIqNfCZdV4p//vy6fBnr8Q1AWnVZ0teurKMG66rLj++TKwKPUP3u7iMUvrvKaEUiQw2QWQ==}
|
||||
|
||||
@ -996,6 +1148,10 @@ packages:
|
||||
resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==}
|
||||
engines: {node: '>=16'}
|
||||
|
||||
jiti@2.6.1:
|
||||
resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==}
|
||||
hasBin: true
|
||||
|
||||
js-yaml@4.1.1:
|
||||
resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==}
|
||||
hasBin: true
|
||||
@ -1004,6 +1160,76 @@ packages:
|
||||
resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==}
|
||||
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:
|
||||
resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==}
|
||||
|
||||
@ -1282,6 +1508,10 @@ packages:
|
||||
resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
postcss-selector-parser@6.0.10:
|
||||
resolution: {integrity: sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
postcss@8.5.6:
|
||||
resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==}
|
||||
engines: {node: ^10 || ^12 || >=14}
|
||||
@ -1462,6 +1692,16 @@ packages:
|
||||
engines: {node: '>=16'}
|
||||
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:
|
||||
resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==}
|
||||
|
||||
@ -1621,6 +1861,9 @@ packages:
|
||||
uploadthing:
|
||||
optional: true
|
||||
|
||||
util-deprecate@1.0.2:
|
||||
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
|
||||
|
||||
vfile-location@5.0.3:
|
||||
resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==}
|
||||
|
||||
@ -1696,6 +1939,11 @@ packages:
|
||||
xxhash-wasm@1.1.0:
|
||||
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:
|
||||
resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
|
||||
engines: {node: '>=12'}
|
||||
@ -1731,6 +1979,8 @@ packages:
|
||||
|
||||
snapshots:
|
||||
|
||||
'@alloc/quick-lru@5.2.0': {}
|
||||
|
||||
'@astrojs/compiler@2.13.0': {}
|
||||
|
||||
'@astrojs/internal-helpers@0.7.5': {}
|
||||
@ -1761,12 +2011,12 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- 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:
|
||||
'@astrojs/markdown-remark': 6.3.10
|
||||
'@mdx-js/mdx': 3.1.1
|
||||
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
|
||||
estree-util-visit: 2.0.0
|
||||
hast-util-to-html: 9.0.5
|
||||
@ -1780,10 +2030,10 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- 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:
|
||||
'@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
|
||||
server-destroy: 1.0.1
|
||||
transitivePeerDependencies:
|
||||
@ -1905,6 +2155,10 @@ snapshots:
|
||||
'@esbuild/win32-x64@0.25.12':
|
||||
optional: true
|
||||
|
||||
'@fontsource-variable/ibm-plex-sans@5.2.8': {}
|
||||
|
||||
'@fontsource/martel@5.2.8': {}
|
||||
|
||||
'@img/colour@1.0.0':
|
||||
optional: true
|
||||
|
||||
@ -2002,8 +2256,25 @@ snapshots:
|
||||
'@img/sharp-win32-x64@0.34.5':
|
||||
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/trace-mapping@0.3.31':
|
||||
dependencies:
|
||||
'@jridgewell/resolve-uri': 3.1.2
|
||||
'@jridgewell/sourcemap-codec': 1.5.5
|
||||
|
||||
'@mdx-js/mdx@3.1.1':
|
||||
dependencies:
|
||||
'@types/estree': 1.0.8
|
||||
@ -2147,6 +2418,87 @@ snapshots:
|
||||
dependencies:
|
||||
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':
|
||||
dependencies:
|
||||
'@types/ms': 2.1.0
|
||||
@ -2216,7 +2568,7 @@ snapshots:
|
||||
|
||||
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:
|
||||
'@astrojs/compiler': 2.13.0
|
||||
'@astrojs/internal-helpers': 0.7.5
|
||||
@ -2273,8 +2625,8 @@ snapshots:
|
||||
unist-util-visit: 5.0.0
|
||||
unstorage: 1.17.3
|
||||
vfile: 6.0.3
|
||||
vite: 6.4.1(@types/node@25.0.3)
|
||||
vitefu: 1.1.1(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)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2))
|
||||
xxhash-wasm: 1.1.0
|
||||
yargs-parser: 21.1.1
|
||||
yocto-spinner: 0.2.3
|
||||
@ -2427,8 +2779,7 @@ snapshots:
|
||||
|
||||
destr@2.0.5: {}
|
||||
|
||||
detect-libc@2.1.2:
|
||||
optional: true
|
||||
detect-libc@2.1.2: {}
|
||||
|
||||
deterministic-object-hash@2.0.2:
|
||||
dependencies:
|
||||
@ -2474,6 +2825,11 @@ snapshots:
|
||||
|
||||
encodeurl@2.0.0: {}
|
||||
|
||||
enhanced-resolve@5.18.4:
|
||||
dependencies:
|
||||
graceful-fs: 4.2.11
|
||||
tapable: 2.3.0
|
||||
|
||||
entities@4.5.0: {}
|
||||
|
||||
entities@6.0.1: {}
|
||||
@ -2602,6 +2958,8 @@ snapshots:
|
||||
|
||||
github-slugger@2.0.0: {}
|
||||
|
||||
graceful-fs@4.2.11: {}
|
||||
|
||||
h3@1.15.4:
|
||||
dependencies:
|
||||
cookie-es: 1.2.2
|
||||
@ -2789,12 +3147,63 @@ snapshots:
|
||||
dependencies:
|
||||
is-inside-container: 1.0.0
|
||||
|
||||
jiti@2.6.1: {}
|
||||
|
||||
js-yaml@4.1.1:
|
||||
dependencies:
|
||||
argparse: 2.0.1
|
||||
|
||||
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: {}
|
||||
|
||||
lru-cache@10.4.3: {}
|
||||
@ -3344,6 +3753,11 @@ snapshots:
|
||||
|
||||
picomatch@4.0.3: {}
|
||||
|
||||
postcss-selector-parser@6.0.10:
|
||||
dependencies:
|
||||
cssesc: 3.0.0
|
||||
util-deprecate: 1.0.2
|
||||
|
||||
postcss@8.5.6:
|
||||
dependencies:
|
||||
nanoid: 3.3.11
|
||||
@ -3662,6 +4076,12 @@ snapshots:
|
||||
picocolors: 1.1.1
|
||||
sax: 1.4.3
|
||||
|
||||
tailwind-merge@3.4.0: {}
|
||||
|
||||
tailwindcss@4.1.18: {}
|
||||
|
||||
tapable@2.3.0: {}
|
||||
|
||||
tiny-inflate@1.0.3: {}
|
||||
|
||||
tinyexec@1.0.2: {}
|
||||
@ -3778,6 +4198,8 @@ snapshots:
|
||||
ofetch: 1.5.1
|
||||
ufo: 1.6.1
|
||||
|
||||
util-deprecate@1.0.2: {}
|
||||
|
||||
vfile-location@5.0.3:
|
||||
dependencies:
|
||||
'@types/unist': 3.0.3
|
||||
@ -3793,7 +4215,7 @@ snapshots:
|
||||
'@types/unist': 3.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:
|
||||
esbuild: 0.25.12
|
||||
fdir: 6.5.0(picomatch@4.0.3)
|
||||
@ -3804,10 +4226,13 @@ snapshots:
|
||||
optionalDependencies:
|
||||
'@types/node': 25.0.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:
|
||||
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: {}
|
||||
|
||||
@ -3825,6 +4250,9 @@ snapshots:
|
||||
|
||||
xxhash-wasm@1.1.0: {}
|
||||
|
||||
yaml@2.8.2:
|
||||
optional: true
|
||||
|
||||
yargs-parser@21.1.1: {}
|
||||
|
||||
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",
|
||||
"include": [".astro/types.d.ts", "**/*"],
|
||||
"exclude": ["dist"]
|
||||
"exclude": ["dist"],
|
||||
"compilerOptions": {
|
||||
"strictNullChecks": true,
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@*": ["./src/*"]
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user