version 2 of my website
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

wip yooper button

+1001 -77
+3 -1
astro.config.mjs
··· 5 5 6 6 import mdx from '@astrojs/mdx'; 7 7 8 + import react from '@astrojs/react'; 9 + 8 10 // https://astro.build/config 9 11 export default defineConfig({ 10 12 vite: { 11 13 plugins: [tailwindcss()] 12 14 }, 13 15 14 - integrations: [mdx()] 16 + integrations: [mdx(), react()] 15 17 });
+647 -6
package-lock.json
··· 9 9 "version": "0.0.1", 10 10 "dependencies": { 11 11 "@astrojs/mdx": "^4.2.6", 12 + "@astrojs/react": "^4.3.0", 12 13 "@lucide/astro": "^0.507.0", 14 + "@nanostores/react": "^1.0.0", 13 15 "@tailwindcss/vite": "^4.1.5", 16 + "@types/react": "^19.1.5", 17 + "@types/react-dom": "^19.1.5", 14 18 "astro": "^5.7.10", 19 + "nanostores": "^1.0.1", 20 + "react": "^19.1.0", 21 + "react-dom": "^19.1.0", 15 22 "tailwindcss": "^4.1.5" 23 + } 24 + }, 25 + "node_modules/@ampproject/remapping": { 26 + "version": "2.3.0", 27 + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", 28 + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", 29 + "license": "Apache-2.0", 30 + "dependencies": { 31 + "@jridgewell/gen-mapping": "^0.3.5", 32 + "@jridgewell/trace-mapping": "^0.3.24" 33 + }, 34 + "engines": { 35 + "node": ">=6.0.0" 16 36 } 17 37 }, 18 38 "node_modules/@astrojs/compiler": { ··· 95 115 "node": "^18.17.1 || ^20.3.0 || >=22.0.0" 96 116 } 97 117 }, 118 + "node_modules/@astrojs/react": { 119 + "version": "4.3.0", 120 + "resolved": "https://registry.npmjs.org/@astrojs/react/-/react-4.3.0.tgz", 121 + "integrity": "sha512-N02aj52Iezn69qHyx5+XvPqgsPMEnel9mI5JMbGiRMTzzLMuNaxRVoQTaq2024Dpr7BLsxCjqMkNvelqMDhaHA==", 122 + "license": "MIT", 123 + "dependencies": { 124 + "@vitejs/plugin-react": "^4.4.1", 125 + "ultrahtml": "^1.6.0", 126 + "vite": "^6.3.5" 127 + }, 128 + "engines": { 129 + "node": "18.20.8 || ^20.3.0 || >=22.0.0" 130 + }, 131 + "peerDependencies": { 132 + "@types/react": "^17.0.50 || ^18.0.21 || ^19.0.0", 133 + "@types/react-dom": "^17.0.17 || ^18.0.6 || ^19.0.0", 134 + "react": "^17.0.2 || ^18.0.0 || ^19.0.0", 135 + "react-dom": "^17.0.2 || ^18.0.0 || ^19.0.0" 136 + } 137 + }, 98 138 "node_modules/@astrojs/telemetry": { 99 139 "version": "3.2.1", 100 140 "resolved": "https://registry.npmjs.org/@astrojs/telemetry/-/telemetry-3.2.1.tgz", ··· 113 153 "node": "^18.17.1 || ^20.3.0 || >=22.0.0" 114 154 } 115 155 }, 156 + "node_modules/@babel/code-frame": { 157 + "version": "7.27.1", 158 + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", 159 + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", 160 + "license": "MIT", 161 + "dependencies": { 162 + "@babel/helper-validator-identifier": "^7.27.1", 163 + "js-tokens": "^4.0.0", 164 + "picocolors": "^1.1.1" 165 + }, 166 + "engines": { 167 + "node": ">=6.9.0" 168 + } 169 + }, 170 + "node_modules/@babel/compat-data": { 171 + "version": "7.27.2", 172 + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.27.2.tgz", 173 + "integrity": "sha512-TUtMJYRPyUb/9aU8f3K0mjmjf6M9N5Woshn2CS6nqJSeJtTtQcpLUXjGt9vbF8ZGff0El99sWkLgzwW3VXnxZQ==", 174 + "license": "MIT", 175 + "engines": { 176 + "node": ">=6.9.0" 177 + } 178 + }, 179 + "node_modules/@babel/core": { 180 + "version": "7.27.1", 181 + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.27.1.tgz", 182 + "integrity": "sha512-IaaGWsQqfsQWVLqMn9OB92MNN7zukfVA4s7KKAI0KfrrDsZ0yhi5uV4baBuLuN7n3vsZpwP8asPPcVwApxvjBQ==", 183 + "license": "MIT", 184 + "dependencies": { 185 + "@ampproject/remapping": "^2.2.0", 186 + "@babel/code-frame": "^7.27.1", 187 + "@babel/generator": "^7.27.1", 188 + "@babel/helper-compilation-targets": "^7.27.1", 189 + "@babel/helper-module-transforms": "^7.27.1", 190 + "@babel/helpers": "^7.27.1", 191 + "@babel/parser": "^7.27.1", 192 + "@babel/template": "^7.27.1", 193 + "@babel/traverse": "^7.27.1", 194 + "@babel/types": "^7.27.1", 195 + "convert-source-map": "^2.0.0", 196 + "debug": "^4.1.0", 197 + "gensync": "^1.0.0-beta.2", 198 + "json5": "^2.2.3", 199 + "semver": "^6.3.1" 200 + }, 201 + "engines": { 202 + "node": ">=6.9.0" 203 + }, 204 + "funding": { 205 + "type": "opencollective", 206 + "url": "https://opencollective.com/babel" 207 + } 208 + }, 209 + "node_modules/@babel/core/node_modules/semver": { 210 + "version": "6.3.1", 211 + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", 212 + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", 213 + "license": "ISC", 214 + "bin": { 215 + "semver": "bin/semver.js" 216 + } 217 + }, 218 + "node_modules/@babel/generator": { 219 + "version": "7.27.1", 220 + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.1.tgz", 221 + "integrity": "sha512-UnJfnIpc/+JO0/+KRVQNGU+y5taA5vCbwN8+azkX6beii/ZF+enZJSOKo11ZSzGJjlNfJHfQtmQT8H+9TXPG2w==", 222 + "license": "MIT", 223 + "dependencies": { 224 + "@babel/parser": "^7.27.1", 225 + "@babel/types": "^7.27.1", 226 + "@jridgewell/gen-mapping": "^0.3.5", 227 + "@jridgewell/trace-mapping": "^0.3.25", 228 + "jsesc": "^3.0.2" 229 + }, 230 + "engines": { 231 + "node": ">=6.9.0" 232 + } 233 + }, 234 + "node_modules/@babel/helper-compilation-targets": { 235 + "version": "7.27.2", 236 + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", 237 + "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", 238 + "license": "MIT", 239 + "dependencies": { 240 + "@babel/compat-data": "^7.27.2", 241 + "@babel/helper-validator-option": "^7.27.1", 242 + "browserslist": "^4.24.0", 243 + "lru-cache": "^5.1.1", 244 + "semver": "^6.3.1" 245 + }, 246 + "engines": { 247 + "node": ">=6.9.0" 248 + } 249 + }, 250 + "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { 251 + "version": "5.1.1", 252 + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", 253 + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", 254 + "license": "ISC", 255 + "dependencies": { 256 + "yallist": "^3.0.2" 257 + } 258 + }, 259 + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { 260 + "version": "6.3.1", 261 + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", 262 + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", 263 + "license": "ISC", 264 + "bin": { 265 + "semver": "bin/semver.js" 266 + } 267 + }, 268 + "node_modules/@babel/helper-module-imports": { 269 + "version": "7.27.1", 270 + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", 271 + "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", 272 + "license": "MIT", 273 + "dependencies": { 274 + "@babel/traverse": "^7.27.1", 275 + "@babel/types": "^7.27.1" 276 + }, 277 + "engines": { 278 + "node": ">=6.9.0" 279 + } 280 + }, 281 + "node_modules/@babel/helper-module-transforms": { 282 + "version": "7.27.1", 283 + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.27.1.tgz", 284 + "integrity": "sha512-9yHn519/8KvTU5BjTVEEeIM3w9/2yXNKoD82JifINImhpKkARMJKPP59kLo+BafpdN5zgNeIcS4jsGDmd3l58g==", 285 + "license": "MIT", 286 + "dependencies": { 287 + "@babel/helper-module-imports": "^7.27.1", 288 + "@babel/helper-validator-identifier": "^7.27.1", 289 + "@babel/traverse": "^7.27.1" 290 + }, 291 + "engines": { 292 + "node": ">=6.9.0" 293 + }, 294 + "peerDependencies": { 295 + "@babel/core": "^7.0.0" 296 + } 297 + }, 298 + "node_modules/@babel/helper-plugin-utils": { 299 + "version": "7.27.1", 300 + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", 301 + "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", 302 + "license": "MIT", 303 + "engines": { 304 + "node": ">=6.9.0" 305 + } 306 + }, 116 307 "node_modules/@babel/helper-string-parser": { 117 308 "version": "7.27.1", 118 309 "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", ··· 131 322 "node": ">=6.9.0" 132 323 } 133 324 }, 134 - "node_modules/@babel/parser": { 325 + "node_modules/@babel/helper-validator-option": { 326 + "version": "7.27.1", 327 + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", 328 + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", 329 + "license": "MIT", 330 + "engines": { 331 + "node": ">=6.9.0" 332 + } 333 + }, 334 + "node_modules/@babel/helpers": { 135 335 "version": "7.27.1", 136 - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.1.tgz", 137 - "integrity": "sha512-I0dZ3ZpCrJ1c04OqlNsQcKiZlsrXf/kkE4FXzID9rIOYICsAbA8mMDzhW/luRNAHdCNt7os/u8wenklZDlUVUQ==", 336 + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.1.tgz", 337 + "integrity": "sha512-FCvFTm0sWV8Fxhpp2McP5/W53GPllQ9QeQ7SiqGWjMf/LVG07lFa5+pgK05IRhVwtvafT22KF+ZSnM9I545CvQ==", 338 + "license": "MIT", 339 + "dependencies": { 340 + "@babel/template": "^7.27.1", 341 + "@babel/types": "^7.27.1" 342 + }, 343 + "engines": { 344 + "node": ">=6.9.0" 345 + } 346 + }, 347 + "node_modules/@babel/parser": { 348 + "version": "7.27.2", 349 + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.2.tgz", 350 + "integrity": "sha512-QYLs8299NA7WM/bZAdp+CviYYkVoYXlDW2rzliy3chxd1PQjej7JORuMJDJXJUb9g0TT+B99EwaVLKmX+sPXWw==", 138 351 "license": "MIT", 139 352 "dependencies": { 140 353 "@babel/types": "^7.27.1" ··· 144 357 }, 145 358 "engines": { 146 359 "node": ">=6.0.0" 360 + } 361 + }, 362 + "node_modules/@babel/plugin-transform-react-jsx-self": { 363 + "version": "7.27.1", 364 + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", 365 + "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", 366 + "license": "MIT", 367 + "dependencies": { 368 + "@babel/helper-plugin-utils": "^7.27.1" 369 + }, 370 + "engines": { 371 + "node": ">=6.9.0" 372 + }, 373 + "peerDependencies": { 374 + "@babel/core": "^7.0.0-0" 375 + } 376 + }, 377 + "node_modules/@babel/plugin-transform-react-jsx-source": { 378 + "version": "7.27.1", 379 + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz", 380 + "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", 381 + "license": "MIT", 382 + "dependencies": { 383 + "@babel/helper-plugin-utils": "^7.27.1" 384 + }, 385 + "engines": { 386 + "node": ">=6.9.0" 387 + }, 388 + "peerDependencies": { 389 + "@babel/core": "^7.0.0-0" 390 + } 391 + }, 392 + "node_modules/@babel/template": { 393 + "version": "7.27.2", 394 + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", 395 + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", 396 + "license": "MIT", 397 + "dependencies": { 398 + "@babel/code-frame": "^7.27.1", 399 + "@babel/parser": "^7.27.2", 400 + "@babel/types": "^7.27.1" 401 + }, 402 + "engines": { 403 + "node": ">=6.9.0" 404 + } 405 + }, 406 + "node_modules/@babel/traverse": { 407 + "version": "7.27.1", 408 + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.1.tgz", 409 + "integrity": "sha512-ZCYtZciz1IWJB4U61UPu4KEaqyfj+r5T1Q5mqPo+IBpcG9kHv30Z0aD8LXPgC1trYa6rK0orRyAhqUgk4MjmEg==", 410 + "license": "MIT", 411 + "dependencies": { 412 + "@babel/code-frame": "^7.27.1", 413 + "@babel/generator": "^7.27.1", 414 + "@babel/parser": "^7.27.1", 415 + "@babel/template": "^7.27.1", 416 + "@babel/types": "^7.27.1", 417 + "debug": "^4.3.1", 418 + "globals": "^11.1.0" 419 + }, 420 + "engines": { 421 + "node": ">=6.9.0" 147 422 } 148 423 }, 149 424 "node_modules/@babel/types": { ··· 941 1216 "url": "https://opencollective.com/libvips" 942 1217 } 943 1218 }, 1219 + "node_modules/@jridgewell/gen-mapping": { 1220 + "version": "0.3.8", 1221 + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", 1222 + "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", 1223 + "license": "MIT", 1224 + "dependencies": { 1225 + "@jridgewell/set-array": "^1.2.1", 1226 + "@jridgewell/sourcemap-codec": "^1.4.10", 1227 + "@jridgewell/trace-mapping": "^0.3.24" 1228 + }, 1229 + "engines": { 1230 + "node": ">=6.0.0" 1231 + } 1232 + }, 1233 + "node_modules/@jridgewell/resolve-uri": { 1234 + "version": "3.1.2", 1235 + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", 1236 + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", 1237 + "license": "MIT", 1238 + "engines": { 1239 + "node": ">=6.0.0" 1240 + } 1241 + }, 1242 + "node_modules/@jridgewell/set-array": { 1243 + "version": "1.2.1", 1244 + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", 1245 + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", 1246 + "license": "MIT", 1247 + "engines": { 1248 + "node": ">=6.0.0" 1249 + } 1250 + }, 944 1251 "node_modules/@jridgewell/sourcemap-codec": { 945 1252 "version": "1.5.0", 946 1253 "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", 947 1254 "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", 948 1255 "license": "MIT" 1256 + }, 1257 + "node_modules/@jridgewell/trace-mapping": { 1258 + "version": "0.3.25", 1259 + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", 1260 + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", 1261 + "license": "MIT", 1262 + "dependencies": { 1263 + "@jridgewell/resolve-uri": "^3.1.0", 1264 + "@jridgewell/sourcemap-codec": "^1.4.14" 1265 + } 949 1266 }, 950 1267 "node_modules/@lucide/astro": { 951 1268 "version": "0.507.0", ··· 992 1309 "url": "https://opencollective.com/unified" 993 1310 } 994 1311 }, 1312 + "node_modules/@nanostores/react": { 1313 + "version": "1.0.0", 1314 + "resolved": "https://registry.npmjs.org/@nanostores/react/-/react-1.0.0.tgz", 1315 + "integrity": "sha512-eDduyNy+lbQJMg6XxZ/YssQqF6b4OXMFEZMYKPJCCmBevp1lg0g+4ZRi94qGHirMtsNfAWKNwsjOhC+q1gvC+A==", 1316 + "funding": [ 1317 + { 1318 + "type": "github", 1319 + "url": "https://github.com/sponsors/ai" 1320 + } 1321 + ], 1322 + "license": "MIT", 1323 + "engines": { 1324 + "node": "^20.0.0 || >=22.0.0" 1325 + }, 1326 + "peerDependencies": { 1327 + "nanostores": "^0.9.0 || ^0.10.0 || ^0.11.0 || ^1.0.0", 1328 + "react": ">=18.0.0" 1329 + } 1330 + }, 995 1331 "node_modules/@oslojs/encoding": { 996 1332 "version": "1.1.0", 997 1333 "resolved": "https://registry.npmjs.org/@oslojs/encoding/-/encoding-1.1.0.tgz", 998 1334 "integrity": "sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==", 1335 + "license": "MIT" 1336 + }, 1337 + "node_modules/@rolldown/pluginutils": { 1338 + "version": "1.0.0-beta.9", 1339 + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.9.tgz", 1340 + "integrity": "sha512-e9MeMtVWo186sgvFFJOPGy7/d2j2mZhLJIdVW0C/xDluuOvymEATqz6zKsP0ZmXGzQtqlyjz5sC1sYQUoJG98w==", 999 1341 "license": "MIT" 1000 1342 }, 1001 1343 "node_modules/@rollup/pluginutils": { ··· 1616 1958 "vite": "^5.2.0 || ^6" 1617 1959 } 1618 1960 }, 1961 + "node_modules/@types/babel__core": { 1962 + "version": "7.20.5", 1963 + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", 1964 + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", 1965 + "license": "MIT", 1966 + "dependencies": { 1967 + "@babel/parser": "^7.20.7", 1968 + "@babel/types": "^7.20.7", 1969 + "@types/babel__generator": "*", 1970 + "@types/babel__template": "*", 1971 + "@types/babel__traverse": "*" 1972 + } 1973 + }, 1974 + "node_modules/@types/babel__generator": { 1975 + "version": "7.27.0", 1976 + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", 1977 + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", 1978 + "license": "MIT", 1979 + "dependencies": { 1980 + "@babel/types": "^7.0.0" 1981 + } 1982 + }, 1983 + "node_modules/@types/babel__template": { 1984 + "version": "7.4.4", 1985 + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", 1986 + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", 1987 + "license": "MIT", 1988 + "dependencies": { 1989 + "@babel/parser": "^7.1.0", 1990 + "@babel/types": "^7.0.0" 1991 + } 1992 + }, 1993 + "node_modules/@types/babel__traverse": { 1994 + "version": "7.20.7", 1995 + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.7.tgz", 1996 + "integrity": "sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==", 1997 + "license": "MIT", 1998 + "dependencies": { 1999 + "@babel/types": "^7.20.7" 2000 + } 2001 + }, 1619 2002 "node_modules/@types/debug": { 1620 2003 "version": "4.1.12", 1621 2004 "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", ··· 1679 2062 "@types/unist": "*" 1680 2063 } 1681 2064 }, 2065 + "node_modules/@types/react": { 2066 + "version": "19.1.5", 2067 + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.5.tgz", 2068 + "integrity": "sha512-piErsCVVbpMMT2r7wbawdZsq4xMvIAhQuac2gedQHysu1TZYEigE6pnFfgZT+/jQnrRuF5r+SHzuehFjfRjr4g==", 2069 + "license": "MIT", 2070 + "dependencies": { 2071 + "csstype": "^3.0.2" 2072 + } 2073 + }, 2074 + "node_modules/@types/react-dom": { 2075 + "version": "19.1.5", 2076 + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.1.5.tgz", 2077 + "integrity": "sha512-CMCjrWucUBZvohgZxkjd6S9h0nZxXjzus6yDfUb+xLxYM7VvjKNH1tQrE9GWLql1XoOP4/Ds3bwFqShHUYraGg==", 2078 + "license": "MIT", 2079 + "peerDependencies": { 2080 + "@types/react": "^19.0.0" 2081 + } 2082 + }, 1682 2083 "node_modules/@types/unist": { 1683 2084 "version": "3.0.3", 1684 2085 "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", ··· 1691 2092 "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", 1692 2093 "license": "ISC" 1693 2094 }, 2095 + "node_modules/@vitejs/plugin-react": { 2096 + "version": "4.5.0", 2097 + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.5.0.tgz", 2098 + "integrity": "sha512-JuLWaEqypaJmOJPLWwO335Ig6jSgC1FTONCWAxnqcQthLTK/Yc9aH6hr9z/87xciejbQcnP3GnA1FWUSWeXaeg==", 2099 + "license": "MIT", 2100 + "dependencies": { 2101 + "@babel/core": "^7.26.10", 2102 + "@babel/plugin-transform-react-jsx-self": "^7.25.9", 2103 + "@babel/plugin-transform-react-jsx-source": "^7.25.9", 2104 + "@rolldown/pluginutils": "1.0.0-beta.9", 2105 + "@types/babel__core": "^7.20.5", 2106 + "react-refresh": "^0.17.0" 2107 + }, 2108 + "engines": { 2109 + "node": "^14.18.0 || >=16.0.0" 2110 + }, 2111 + "peerDependencies": { 2112 + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0" 2113 + } 2114 + }, 1694 2115 "node_modules/acorn": { 1695 2116 "version": "8.14.1", 1696 2117 "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", ··· 2023 2444 "base64-js": "^1.1.2" 2024 2445 } 2025 2446 }, 2447 + "node_modules/browserslist": { 2448 + "version": "4.24.5", 2449 + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.5.tgz", 2450 + "integrity": "sha512-FDToo4Wo82hIdgc1CQ+NQD0hEhmpPjrZ3hiUgwgOG6IuTdlpr8jdjyG24P6cNP1yJpTLzS5OcGgSw0xmDU1/Tw==", 2451 + "funding": [ 2452 + { 2453 + "type": "opencollective", 2454 + "url": "https://opencollective.com/browserslist" 2455 + }, 2456 + { 2457 + "type": "tidelift", 2458 + "url": "https://tidelift.com/funding/github/npm/browserslist" 2459 + }, 2460 + { 2461 + "type": "github", 2462 + "url": "https://github.com/sponsors/ai" 2463 + } 2464 + ], 2465 + "license": "MIT", 2466 + "dependencies": { 2467 + "caniuse-lite": "^1.0.30001716", 2468 + "electron-to-chromium": "^1.5.149", 2469 + "node-releases": "^2.0.19", 2470 + "update-browserslist-db": "^1.1.3" 2471 + }, 2472 + "bin": { 2473 + "browserslist": "cli.js" 2474 + }, 2475 + "engines": { 2476 + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" 2477 + } 2478 + }, 2026 2479 "node_modules/camelcase": { 2027 2480 "version": "8.0.0", 2028 2481 "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-8.0.0.tgz", ··· 2034 2487 "funding": { 2035 2488 "url": "https://github.com/sponsors/sindresorhus" 2036 2489 } 2490 + }, 2491 + "node_modules/caniuse-lite": { 2492 + "version": "1.0.30001718", 2493 + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001718.tgz", 2494 + "integrity": "sha512-AflseV1ahcSunK53NfEs9gFWgOEmzr0f+kaMFA4xiLZlr9Hzt7HxcSpIFcnNCUkz6R6dWKa54rUz3HUmI3nVcw==", 2495 + "funding": [ 2496 + { 2497 + "type": "opencollective", 2498 + "url": "https://opencollective.com/browserslist" 2499 + }, 2500 + { 2501 + "type": "tidelift", 2502 + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" 2503 + }, 2504 + { 2505 + "type": "github", 2506 + "url": "https://github.com/sponsors/ai" 2507 + } 2508 + ], 2509 + "license": "CC-BY-4.0" 2037 2510 }, 2038 2511 "node_modules/ccount": { 2039 2512 "version": "2.0.1", ··· 2228 2701 "integrity": "sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==", 2229 2702 "license": "ISC" 2230 2703 }, 2704 + "node_modules/convert-source-map": { 2705 + "version": "2.0.0", 2706 + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", 2707 + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", 2708 + "license": "MIT" 2709 + }, 2231 2710 "node_modules/cookie": { 2232 2711 "version": "1.0.2", 2233 2712 "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz", ··· 2286 2765 "node": ">=4" 2287 2766 } 2288 2767 }, 2768 + "node_modules/csstype": { 2769 + "version": "3.1.3", 2770 + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", 2771 + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", 2772 + "license": "MIT" 2773 + }, 2289 2774 "node_modules/debug": { 2290 2775 "version": "4.4.0", 2291 2776 "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", ··· 2407 2892 "node": ">=4" 2408 2893 } 2409 2894 }, 2895 + "node_modules/electron-to-chromium": { 2896 + "version": "1.5.157", 2897 + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.157.tgz", 2898 + "integrity": "sha512-/0ybgsQd1muo8QlnuTpKwtl0oX5YMlUGbm8xyqgDU00motRkKFFbUJySAQBWcY79rVqNLWIWa87BGVGClwAB2w==", 2899 + "license": "ISC" 2900 + }, 2410 2901 "node_modules/emoji-regex": { 2411 2902 "version": "10.4.0", 2412 2903 "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", ··· 2514 3005 "@esbuild/win32-arm64": "0.25.3", 2515 3006 "@esbuild/win32-ia32": "0.25.3", 2516 3007 "@esbuild/win32-x64": "0.25.3" 3008 + } 3009 + }, 3010 + "node_modules/escalade": { 3011 + "version": "3.2.0", 3012 + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", 3013 + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", 3014 + "license": "MIT", 3015 + "engines": { 3016 + "node": ">=6" 2517 3017 } 2518 3018 }, 2519 3019 "node_modules/escape-string-regexp": { ··· 2691 3191 "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 2692 3192 } 2693 3193 }, 3194 + "node_modules/gensync": { 3195 + "version": "1.0.0-beta.2", 3196 + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", 3197 + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", 3198 + "license": "MIT", 3199 + "engines": { 3200 + "node": ">=6.9.0" 3201 + } 3202 + }, 2694 3203 "node_modules/get-east-asian-width": { 2695 3204 "version": "1.3.0", 2696 3205 "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.3.0.tgz", ··· 2709 3218 "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==", 2710 3219 "license": "ISC" 2711 3220 }, 3221 + "node_modules/globals": { 3222 + "version": "11.12.0", 3223 + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", 3224 + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", 3225 + "license": "MIT", 3226 + "engines": { 3227 + "node": ">=4" 3228 + } 3229 + }, 2712 3230 "node_modules/graceful-fs": { 2713 3231 "version": "4.2.11", 2714 3232 "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", ··· 3150 3668 "jiti": "lib/jiti-cli.mjs" 3151 3669 } 3152 3670 }, 3671 + "node_modules/js-tokens": { 3672 + "version": "4.0.0", 3673 + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", 3674 + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", 3675 + "license": "MIT" 3676 + }, 3153 3677 "node_modules/js-yaml": { 3154 3678 "version": "4.1.0", 3155 3679 "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", ··· 3160 3684 }, 3161 3685 "bin": { 3162 3686 "js-yaml": "bin/js-yaml.js" 3687 + } 3688 + }, 3689 + "node_modules/jsesc": { 3690 + "version": "3.1.0", 3691 + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", 3692 + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", 3693 + "license": "MIT", 3694 + "bin": { 3695 + "jsesc": "bin/jsesc" 3696 + }, 3697 + "engines": { 3698 + "node": ">=6" 3699 + } 3700 + }, 3701 + "node_modules/json5": { 3702 + "version": "2.2.3", 3703 + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", 3704 + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", 3705 + "license": "MIT", 3706 + "bin": { 3707 + "json5": "lib/cli.js" 3708 + }, 3709 + "engines": { 3710 + "node": ">=6" 3163 3711 } 3164 3712 }, 3165 3713 "node_modules/kleur": { ··· 4515 5063 "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" 4516 5064 } 4517 5065 }, 5066 + "node_modules/nanostores": { 5067 + "version": "1.0.1", 5068 + "resolved": "https://registry.npmjs.org/nanostores/-/nanostores-1.0.1.tgz", 5069 + "integrity": "sha512-kNZ9xnoJYKg/AfxjrVL4SS0fKX++4awQReGqWnwTRHxeHGZ1FJFVgTqr/eMrNQdp0Tz7M7tG/TDaX8QfHDwVCw==", 5070 + "funding": [ 5071 + { 5072 + "type": "github", 5073 + "url": "https://github.com/sponsors/ai" 5074 + } 5075 + ], 5076 + "license": "MIT", 5077 + "engines": { 5078 + "node": "^20.0.0 || >=22.0.0" 5079 + } 5080 + }, 4518 5081 "node_modules/neotraverse": { 4519 5082 "version": "0.6.18", 4520 5083 "resolved": "https://registry.npmjs.org/neotraverse/-/neotraverse-0.6.18.tgz", ··· 4569 5132 "integrity": "sha512-0uGYQ1WQL1M5kKvGRXWQ3uZCHtLTO8hln3oBjIusM75WoesZ909uQJs/Hb946i2SS+Gsrhkaa6iAO17jRIv6DQ==", 4570 5133 "license": "MIT" 4571 5134 }, 5135 + "node_modules/node-releases": { 5136 + "version": "2.0.19", 5137 + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", 5138 + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", 5139 + "license": "MIT" 5140 + }, 4572 5141 "node_modules/normalize-path": { 4573 5142 "version": "3.0.0", 4574 5143 "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", ··· 4815 5384 "integrity": "sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==", 4816 5385 "license": "MIT" 4817 5386 }, 5387 + "node_modules/react": { 5388 + "version": "19.1.0", 5389 + "resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz", 5390 + "integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==", 5391 + "license": "MIT", 5392 + "engines": { 5393 + "node": ">=0.10.0" 5394 + } 5395 + }, 5396 + "node_modules/react-dom": { 5397 + "version": "19.1.0", 5398 + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz", 5399 + "integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==", 5400 + "license": "MIT", 5401 + "dependencies": { 5402 + "scheduler": "^0.26.0" 5403 + }, 5404 + "peerDependencies": { 5405 + "react": "^19.1.0" 5406 + } 5407 + }, 5408 + "node_modules/react-refresh": { 5409 + "version": "0.17.0", 5410 + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", 5411 + "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==", 5412 + "license": "MIT", 5413 + "engines": { 5414 + "node": ">=0.10.0" 5415 + } 5416 + }, 4818 5417 "node_modules/readdirp": { 4819 5418 "version": "4.1.2", 4820 5419 "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", ··· 5192 5791 "@rollup/rollup-win32-x64-msvc": "4.40.1", 5193 5792 "fsevents": "~2.3.2" 5194 5793 } 5794 + }, 5795 + "node_modules/scheduler": { 5796 + "version": "0.26.0", 5797 + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", 5798 + "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==", 5799 + "license": "MIT" 5195 5800 }, 5196 5801 "node_modules/semver": { 5197 5802 "version": "7.7.1", ··· 5797 6402 } 5798 6403 } 5799 6404 }, 6405 + "node_modules/update-browserslist-db": { 6406 + "version": "1.1.3", 6407 + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", 6408 + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", 6409 + "funding": [ 6410 + { 6411 + "type": "opencollective", 6412 + "url": "https://opencollective.com/browserslist" 6413 + }, 6414 + { 6415 + "type": "tidelift", 6416 + "url": "https://tidelift.com/funding/github/npm/browserslist" 6417 + }, 6418 + { 6419 + "type": "github", 6420 + "url": "https://github.com/sponsors/ai" 6421 + } 6422 + ], 6423 + "license": "MIT", 6424 + "dependencies": { 6425 + "escalade": "^3.2.0", 6426 + "picocolors": "^1.1.1" 6427 + }, 6428 + "bin": { 6429 + "update-browserslist-db": "cli.js" 6430 + }, 6431 + "peerDependencies": { 6432 + "browserslist": ">= 4.21.0" 6433 + } 6434 + }, 5800 6435 "node_modules/vfile": { 5801 6436 "version": "6.0.3", 5802 6437 "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", ··· 5840 6475 } 5841 6476 }, 5842 6477 "node_modules/vite": { 5843 - "version": "6.3.4", 5844 - "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.4.tgz", 5845 - "integrity": "sha512-BiReIiMS2fyFqbqNT/Qqt4CVITDU9M9vE+DKcVAsB+ZV0wvTKd+3hMbkpxz1b+NmEDMegpVbisKiAZOnvO92Sw==", 6478 + "version": "6.3.5", 6479 + "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz", 6480 + "integrity": "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==", 5846 6481 "license": "MIT", 5847 6482 "dependencies": { 5848 6483 "esbuild": "^0.25.0", ··· 6003 6638 "resolved": "https://registry.npmjs.org/xxhash-wasm/-/xxhash-wasm-1.1.0.tgz", 6004 6639 "integrity": "sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA==", 6005 6640 "license": "MIT" 6641 + }, 6642 + "node_modules/yallist": { 6643 + "version": "3.1.1", 6644 + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", 6645 + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", 6646 + "license": "ISC" 6006 6647 }, 6007 6648 "node_modules/yargs-parser": { 6008 6649 "version": "21.1.1",
+7
package.json
··· 10 10 }, 11 11 "dependencies": { 12 12 "@astrojs/mdx": "^4.2.6", 13 + "@astrojs/react": "^4.3.0", 13 14 "@lucide/astro": "^0.507.0", 15 + "@nanostores/react": "^1.0.0", 14 16 "@tailwindcss/vite": "^4.1.5", 17 + "@types/react": "^19.1.5", 18 + "@types/react-dom": "^19.1.5", 15 19 "astro": "^5.7.10", 20 + "nanostores": "^1.0.1", 21 + "react": "^19.1.0", 22 + "react-dom": "^19.1.0", 16 23 "tailwindcss": "^4.1.5" 17 24 } 18 25 }
src/assets/edmund_fitzgerald.png

This is a binary file and will not be displayed.

+1 -1
src/components/header.astro
··· 2 2 import { Moon, Sun } from "@lucide/astro"; 3 3 --- 4 4 5 - <header class="m-3 flex justify-end items-center w-dvw"> 5 + <header class="m-3 flex justify-end items-center"> 6 6 <!-- <h1>dustycode</h1> --> 7 7 <button type="button" id="theme-selector" class="p-2 rounded-lg hover:bg-gray-0 transition-colors"> 8 8 <span class="sr-only">
+8 -7
src/components/intro.astro
··· 1 1 --- 2 2 import Links from "./links.astro" 3 3 --- 4 - 5 - <div class="border-1 border-solid rounded-lg p-4"> 6 - <h1 class="text-5xl font-normal">Hello, I'm Dustin!</h1> 7 - <p class="text-lg"> 8 - A software engineer, nature enjoyer, and overall chill dude. 9 - </p> 10 - <Links /> 4 + <div> 5 + <div class="border-1 border-solid rounded-lg p-4"> 6 + <h1 class="text-5xl font-normal">Hello, I'm Dustin!</h1> 7 + <p class="text-lg"> 8 + A software engineer, nature enjoyer, and overall chill dude. 9 + </p> 10 + <Links /> 11 + </div> 11 12 </div>
+45 -47
src/components/links.astro
··· 7 7 import { Mail } from "@lucide/astro"; 8 8 --- 9 9 10 - <div class="flex gap-3 py-3 h-7"> 11 - <a 12 - href="https://bsky.app/profile/dustycode.dev" 13 - aria-label="Bluesky" 14 - target="_blank" 15 - class="" 16 - > 17 - <Bluesky class="h-7 fill-foreground" /> 18 - </a> 19 - <a 20 - href="https://github.com/DustinsCode" 21 - aria-label="Github" 22 - target="_blank" 23 - class="" 24 - > 25 - <Github class="h-7 fill-foreground" /> 26 - </a> 27 - <a 28 - href="https://discordapp.com/users/195312689839341569" 29 - aria-label="Discord" 30 - target="_blank" 31 - class="" 32 - > 33 - <Discord class="h-7 w-fit fill-foreground" /> 34 - </a> 35 - <a 36 - href="https://www.last.fm/user/dustycode" 37 - aria-label="last.fm" 38 - target="_blank" 39 - class="" 40 - > 41 - <LastFM class="h-7 w-fit fill-foreground" /> 42 - </a> 43 - <a 44 - href="https://www.linkedin.com/in/dustycode/" 45 - aria-label="LinkedIn" 46 - target="_blank" 47 - class="" 48 - > 49 - <LinkedIn class="h-7 w-fit fill-foreground" /> 50 - </a> 51 - <a 52 - href="mailto:dustin@dustycode.dev" 53 - > 54 - <Mail class="h-7 w-fit " /> 55 - </a> 56 - </div> 10 + <div class="flex gap-3 h-7 my-3 items-center"> 11 + <a 12 + href="https://bsky.app/profile/dustycode.dev" 13 + aria-label="Bluesky" 14 + target="_blank" 15 + class="" 16 + > 17 + <Bluesky class="h-7 fill-foreground" /> 18 + </a> 19 + <a 20 + href="https://github.com/DustinsCode" 21 + aria-label="Github" 22 + target="_blank" 23 + class="" 24 + > 25 + <Github class="h-6 fill-foreground" /> 26 + </a> 27 + <a 28 + href="https://discordapp.com/users/195312689839341569" 29 + aria-label="Discord" 30 + target="_blank" 31 + class="" 32 + > 33 + <Discord class="h-7 w-fit fill-foreground" /> 34 + </a> 35 + <a 36 + href="https://www.last.fm/user/dustycode" 37 + aria-label="last.fm" 38 + target="_blank" 39 + class="" 40 + > 41 + <LastFM class="h-7 w-fit fill-foreground" /> 42 + </a> 43 + <a 44 + href="https://www.linkedin.com/in/dustycode/" 45 + aria-label="LinkedIn" 46 + target="_blank" 47 + class="" 48 + > 49 + <LinkedIn class="h-6 w-fit fill-foreground" /> 50 + </a> 51 + <a href="mailto:dustin@dustycode.dev" aria-label="email"> 52 + <Mail class="h-7 w-fit" /> 53 + </a> 54 + </div>
+40
src/components/popover/popover.tsx
··· 1 + import type React from "react"; 2 + import { useStore } from "@nanostores/react"; 3 + import { isPopoverOpen } from "./popoverStore"; 4 + 5 + interface TriggerProps { 6 + children: React.ReactNode; 7 + } 8 + 9 + interface ContentProps { 10 + className?: string; 11 + children: React.ReactNode; 12 + } 13 + 14 + export function Popover({ children }: TriggerProps) { 15 + return ( 16 + <div className="relative"> 17 + {children} 18 + </div> 19 + ) 20 + } 21 + 22 + export function PopoverTrigger({ children }: TriggerProps) { 23 + return ( 24 + <div className="inline" 25 + onMouseOver={() => { isPopoverOpen.set(true) }} 26 + onMouseLeave={() => isPopoverOpen.set(false)}> 27 + {children} 28 + </div> 29 + ) 30 + } 31 + 32 + export function PopoverContent({ children }: ContentProps) { 33 + const $isPopoverOpen = useStore(isPopoverOpen) 34 + 35 + return ( 36 + <dialog className="relative border-1 border-solid border-black bg-bg-5 rounded-lg p-3 z-10" open={true}> 37 + {children} 38 + </dialog> 39 + ) 40 + }
+3
src/components/popover/popoverStore.ts
··· 1 + import { atom } from "nanostores"; 2 + 3 + export const isPopoverOpen = atom(false);
+154
src/components/test.astro
··· 1 + --- 2 + // Component script (runs on server) 3 + --- 4 + 5 + <html lang="en"> 6 + <head> 7 + <meta charset="utf-8" /> 8 + <meta name="viewport" content="width=device-width, initial-scale=1" /> 9 + <title>Animated Image with Audio</title> 10 + </head> 11 + <body> 12 + <div class="container"> 13 + <button id="animateButton" class="trigger-btn"> 14 + Click to Animate 15 + </button> 16 + 17 + <img 18 + id="movingImage" 19 + src="https://via.placeholder.com/100x100/4F46E5/FFFFFF?text=🚀" 20 + alt="Moving image" 21 + class="moving-image" 22 + /> 23 + 24 + <audio id="audioPlayer" preload="auto"> 25 + <!-- Replace with your audio file URL --> 26 + <source src="https://www.soundjay.com/misc/sounds/bell-ringing-05.wav" type="audio/wav"> 27 + <!-- Fallback audio source --> 28 + <source src="https://www.zapsplat.com/wp-content/uploads/2015/sound-effects-one/cartoon_bubble_pop_or_drip_001.mp3" type="audio/mpeg"> 29 + </audio> 30 + </div> 31 + 32 + <style> 33 + body { 34 + margin: 0; 35 + padding: 20px; 36 + font-family: Arial, sans-serif; 37 + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); 38 + min-height: 100vh; 39 + overflow-x: hidden; 40 + } 41 + 42 + .container { 43 + position: relative; 44 + width: 100%; 45 + height: 100vh; 46 + } 47 + 48 + .trigger-btn { 49 + padding: 12px 24px; 50 + font-size: 16px; 51 + background: #4F46E5; 52 + color: white; 53 + border: none; 54 + border-radius: 8px; 55 + cursor: pointer; 56 + transition: background-color 0.3s ease; 57 + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); 58 + } 59 + 60 + .trigger-btn:hover { 61 + background: #3730A3; 62 + transform: translateY(-1px); 63 + box-shadow: 0 6px 8px rgba(0, 0, 0, 0.15); 64 + } 65 + 66 + .trigger-btn:active { 67 + transform: translateY(0); 68 + } 69 + 70 + .moving-image { 71 + position: fixed; 72 + width: 80px; 73 + height: 80px; 74 + bottom: 20px; 75 + right: -100px; /* Start off-screen */ 76 + border-radius: 50%; 77 + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); 78 + transition: all 4s cubic-bezier(0.25, 0.46, 0.45, 0.94); 79 + z-index: 1000; 80 + opacity: 0; 81 + } 82 + 83 + .moving-image.animate { 84 + right: calc(100vw - 100px); /* Move to left side */ 85 + opacity: 1; 86 + transform: rotate(360deg) scale(1.2); 87 + } 88 + 89 + .moving-image.reset { 90 + transition: none; 91 + right: -100px; 92 + opacity: 0; 93 + transform: rotate(0deg) scale(1); 94 + } 95 + 96 + /* Optional: Add a subtle pulse effect */ 97 + @keyframes pulse { 98 + 0%, 100% { transform: scale(1); } 99 + 50% { transform: scale(1.05); } 100 + } 101 + 102 + .moving-image.animate { 103 + animation: pulse 1s ease-in-out infinite; 104 + } 105 + </style> 106 + 107 + <script> 108 + // Client-side script 109 + const button = document.getElementById('animateButton'); 110 + const image = document.getElementById('movingImage'); 111 + const audio = document.getElementById('audioPlayer'); 112 + 113 + let isAnimating = false; 114 + 115 + button.addEventListener('click', () => { 116 + if (isAnimating) return; // Prevent multiple clicks during animation 117 + 118 + isAnimating = true; 119 + 120 + // Reset image position first 121 + image.classList.remove('animate'); 122 + image.classList.add('reset'); 123 + 124 + // Small delay to ensure reset is applied 125 + setTimeout(() => { 126 + image.classList.remove('reset'); 127 + image.classList.add('animate'); 128 + 129 + // Play audio 130 + audio.currentTime = 0; // Reset audio to beginning 131 + audio.play().catch(error => { 132 + console.log('Audio playback failed:', error); 133 + }); 134 + }, 50); 135 + 136 + // Reset animation state after animation completes 137 + setTimeout(() => { 138 + isAnimating = false; 139 + image.classList.remove('animate'); 140 + }, 4000); // Match the CSS transition duration 141 + }); 142 + 143 + // Optional: Reset image position when audio ends 144 + audio.addEventListener('ended', () => { 145 + console.log('Audio finished playing'); 146 + }); 147 + 148 + // Handle audio loading errors gracefully 149 + audio.addEventListener('error', (e) => { 150 + console.log('Audio failed to load, continuing with animation only'); 151 + }); 152 + </script> 153 + </body> 154 + </html>
+35 -8
src/components/whoami.astro
··· 1 1 <div class="border-1 border-solid rounded-lg p-4"> 2 - <h2 class="text-5xl font-normal">Yeah but like who <em>are</em> you?</h2> 3 - <p> 4 - I'm glad you asked! I am a full-stack software engineer from the 5 - beautiful state of Michigan, currently in the Metro Detroit area. 6 - <br /> 7 - I grew up in a small town in the Upper Peninsula, where I established a deep 8 - appreciation for the outdoors. I enjoy hiking, biking, tennis, swimming, and whitewater kayaking 9 - </p> 2 + <h2 class="text-5xl font-normal mb-4"> 3 + Okay but like who <em>are</em> you? 4 + </h2> 5 + 6 + <div> 7 + <p> 8 + I'm glad you asked! I am a full-stack software engineer from the 9 + beautiful state of Michigan, currently in the Metro Detroit area. 10 + <br class="mb-4" /> 11 + I grew up in a small town in the <button 12 + data-yooper 13 + class="text-blue hover:cursor-pointer" 14 + >Upper Peninsula</button 15 + >, where I established a deep appreciation for the outdoors. I enjoy hiking, 16 + biking, tennis, swimming, and hoping to get into some whitewater kayaking 17 + soon. During the long northern winters, you can find me inside playing 18 + video games or out on the slopes snowboarding. 19 + <br class="mb-4" /> 20 + Some of my other interests include (but are not limited to): 21 + <ul class="list-disc ml-6"> 22 + <!-- TODO: add links to things here. 23 + ex: a picture of my car, or posts about the things I've built --> 24 + <li>Working on my car</li> 25 + <li>Building things</li> 26 + <li>Photography</li> 27 + <li> 28 + Playing drums and <a 29 + href="https://en.wikipedia.org/wiki/Vibraphone" 30 + target="_blank" 31 + class="text-blue">vibraphone</a 32 + > 33 + </li> 34 + </ul> 35 + </p> 36 + </div> 10 37 </div>
+46 -4
src/pages/index.astro
··· 2 2 import Layout from "../layouts/Layout.astro"; 3 3 import Intro from "../components/intro.astro"; 4 4 import Whoami from "../components/whoami.astro"; 5 + import Test from "../components/test.astro"; 6 + import { Image } from "astro:assets"; 7 + import edmundFitzgerald from "../assets/edmund_fitzgerald.png"; 5 8 --- 6 9 10 + <script> 11 + const yooperButton = document.querySelector("[data-yooper]"); 12 + const eddyFitz = document.getElementById("eddyFitz"); 13 + const audio = document.getElementById("audioPlayer") as HTMLAudioElement; 14 + 15 + let isAnimating = false; 16 + 17 + yooperButton?.addEventListener("click", () => { 18 + if (isAnimating) return; 19 + 20 + isAnimating = true; 21 + 22 + eddyFitz?.classList.add('animate-') 23 + // Play audio 24 + audio.currentTime = 0; // Reset audio to beginning 25 + audio.play().catch((error) => { 26 + console.log("Audio playback failed:", error); 27 + }); 28 + }); 29 + </script> 30 + 7 31 <Layout title="dustycode"> 8 - <div class="flex-col gap-3 lg:flex"> 9 - <Intro /> 10 - <Whoami /> 32 + <div 33 + class="flex gap-4 md:mx-0 mx-4 justify-center flex-col md:flex-row xl:max-w-2/3" 34 + > 35 + <div class="flex-col gap-3 flex"> 36 + <Intro /> 37 + </div> 38 + <div class="flex-col flex"> 39 + <Whoami /> 40 + </div> 11 41 </div> 12 - </Layout> 42 + <Image 43 + id="eddyFitz" 44 + class="fixed bottom-5 xl:right-[-800px] right-[-300px] xl:h-72 h-32 w-auto" 45 + src={edmundFitzgerald} 46 + alt="The Edmund Fitzgerald, a ship that was lost to Lake Superior" 47 + /> 48 + <audio id="audioPlayer" preload="auto"> 49 + <source 50 + src="https://ia801608.us.archive.org/31/items/gl_20230503/02%20The%20Wreck%20of%20the%20Edmund%20Fitzgerald.mp3" 51 + type="audio/mp3" 52 + /> 53 + </audio> 54 + </Layout>
+12 -3
tsconfig.json
··· 1 1 { 2 2 "extends": "astro/tsconfigs/strict", 3 - "include": [".astro/types.d.ts", "**/*"], 4 - "exclude": ["dist"] 5 - } 3 + "include": [ 4 + ".astro/types.d.ts", 5 + "**/*" 6 + ], 7 + "exclude": [ 8 + "dist" 9 + ], 10 + "compilerOptions": { 11 + "jsx": "react-jsx", 12 + "jsxImportSource": "react" 13 + } 14 + }