This commit is contained in:
praymantis2023 2025-08-13 16:30:43 +10:00
commit d8b2a2c8ce
66 changed files with 16102 additions and 352 deletions

View file

@ -1,4 +1,5 @@
AIRTABLE_API_KEY=your_airtable_api_key_here
AIRTABLE_BASE_ID=your_airtable_base_id_here
AIRTABLE_EMAILS_TABLE=your_airtable_emails_table_here
GEOCODER_API_KEY=your_geocoder_api_key_here
AIRTABLE_RSVPS_TABLE=your_airtable_rsvps_table_here
GEOCODER_API_KEY=your_geocoder_api_key_here

View file

@ -1,6 +1,9 @@
# Use Node.js LTS version
FROM node:20-alpine
# Install curl
RUN apk add --no-cache curl
# Set the working directory
WORKDIR /app

View file

@ -5,6 +5,7 @@
"name": "site",
"dependencies": {
"@fontsource/atkinson-hyperlegible": "^5.2.6",
"@fontsource/jersey-15": "^5.2.6",
"@sveltejs/adapter-node": "^5.2.13",
"@sveltejs/adapter-static": "^3.0.8",
"@tailwindcss/typography": "^0.5.16",
@ -93,6 +94,8 @@
"@fontsource/atkinson-hyperlegible": ["@fontsource/atkinson-hyperlegible@5.2.6", "", {}, "sha512-Kfh6/UlHhotKuv4Oi9PXQIsmzwbtJIR442sSJnEHsO7TDZaDczK8cY0AlTNOB0XMDZj1j35nAlgbi2HZCdNg/Q=="],
"@fontsource/jersey-15": ["@fontsource/jersey-15@5.2.6", "", {}, "sha512-3zkkEnu91esusWLqAK/AN1uc6jNtWT8idfO0UfYLqNlbMBKkbbiIVXtq6UbQsyegxnmRMppVV1J2t1zrJ36VgA=="],
"@isaacs/fs-minipass": ["@isaacs/fs-minipass@4.0.1", "", { "dependencies": { "minipass": "^7.0.4" } }, "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w=="],
"@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.12", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg=="],
@ -105,53 +108,53 @@
"@polka/url": ["@polka/url@1.0.0-next.29", "", {}, "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww=="],
"@rollup/plugin-commonjs": ["@rollup/plugin-commonjs@28.0.6", "", { "dependencies": { "@rollup/pluginutils": "^5.0.1", "commondir": "^1.0.1", "estree-walker": "^2.0.2", "fdir": "^6.2.0", "is-reference": "1.2.1", "magic-string": "^0.30.3", "picomatch": "^4.0.2" }, "peerDependencies": { "rollup": "^2.68.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-XSQB1K7FUU5QP+3lOQmVCE3I0FcbbNvmNT4VJSj93iUjayaARrTQeoRdiYQoftAJBLrR9t2agwAd3ekaTgHNlw=="],
"@rollup/plugin-commonjs": ["@rollup/plugin-commonjs@28.0.6", "", { "dependencies": { "@rollup/pluginutils": "^5.0.1", "commondir": "^1.0.1", "estree-walker": "^2.0.2", "fdir": "^6.2.0", "is-reference": "1.2.1", "magic-string": "^0.30.3", "picomatch": "^4.0.2" }, "peerDependencies": { "rollup": "^2.68.0||^3.0.0||^4.0.0" } }, "sha512-XSQB1K7FUU5QP+3lOQmVCE3I0FcbbNvmNT4VJSj93iUjayaARrTQeoRdiYQoftAJBLrR9t2agwAd3ekaTgHNlw=="],
"@rollup/plugin-json": ["@rollup/plugin-json@6.1.0", "", { "dependencies": { "@rollup/pluginutils": "^5.1.0" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA=="],
"@rollup/plugin-json": ["@rollup/plugin-json@6.1.0", "", { "dependencies": { "@rollup/pluginutils": "^5.1.0" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" } }, "sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA=="],
"@rollup/plugin-node-resolve": ["@rollup/plugin-node-resolve@16.0.1", "", { "dependencies": { "@rollup/pluginutils": "^5.0.1", "@types/resolve": "1.20.2", "deepmerge": "^4.2.2", "is-module": "^1.0.0", "resolve": "^1.22.1" }, "peerDependencies": { "rollup": "^2.78.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-tk5YCxJWIG81umIvNkSod2qK5KyQW19qcBF/B78n1bjtOON6gzKoVeSzAE8yHCZEDmqkHKkxplExA8KzdJLJpA=="],
"@rollup/plugin-node-resolve": ["@rollup/plugin-node-resolve@16.0.1", "", { "dependencies": { "@rollup/pluginutils": "^5.0.1", "@types/resolve": "1.20.2", "deepmerge": "^4.2.2", "is-module": "^1.0.0", "resolve": "^1.22.1" }, "peerDependencies": { "rollup": "^2.78.0||^3.0.0||^4.0.0" } }, "sha512-tk5YCxJWIG81umIvNkSod2qK5KyQW19qcBF/B78n1bjtOON6gzKoVeSzAE8yHCZEDmqkHKkxplExA8KzdJLJpA=="],
"@rollup/pluginutils": ["@rollup/pluginutils@5.2.0", "", { "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", "picomatch": "^4.0.2" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-qWJ2ZTbmumwiLFomfzTyt5Kng4hwPi9rwCYN4SHb6eaRU1KNO4ccxINHr/VhH4GgPlt1XfSTLX2LBTme8ne4Zw=="],
"@rollup/pluginutils": ["@rollup/pluginutils@5.2.0", "", { "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", "picomatch": "^4.0.2" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" } }, "sha512-qWJ2ZTbmumwiLFomfzTyt5Kng4hwPi9rwCYN4SHb6eaRU1KNO4ccxINHr/VhH4GgPlt1XfSTLX2LBTme8ne4Zw=="],
"@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.44.2", "", { "os": "android", "cpu": "arm" }, "sha512-g0dF8P1e2QYPOj1gu7s/3LVP6kze9A7m6x0BZ9iTdXK8N5c2V7cpBKHV3/9A4Zd8xxavdhK0t4PnqjkqVmUc9Q=="],
"@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.45.0", "", { "os": "android", "cpu": "arm" }, "sha512-2o/FgACbji4tW1dzXOqAV15Eu7DdgbKsF2QKcxfG4xbh5iwU7yr5RRP5/U+0asQliSYv5M4o7BevlGIoSL0LXg=="],
"@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.44.2", "", { "os": "android", "cpu": "arm64" }, "sha512-Yt5MKrOosSbSaAK5Y4J+vSiID57sOvpBNBR6K7xAaQvk3MkcNVV0f9fE20T+41WYN8hDn6SGFlFrKudtx4EoxA=="],
"@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.45.0", "", { "os": "android", "cpu": "arm64" }, "sha512-PSZ0SvMOjEAxwZeTx32eI/j5xSYtDCRxGu5k9zvzoY77xUNssZM+WV6HYBLROpY5CkXsbQjvz40fBb7WPwDqtQ=="],
"@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.44.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-EsnFot9ZieM35YNA26nhbLTJBHD0jTwWpPwmRVDzjylQT6gkar+zenfb8mHxWpRrbn+WytRRjE0WKsfaxBkVUA=="],
"@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.45.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-BA4yPIPssPB2aRAWzmqzQ3y2/KotkLyZukVB7j3psK/U3nVJdceo6qr9pLM2xN6iRP/wKfxEbOb1yrlZH6sYZg=="],
"@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.44.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-dv/t1t1RkCvJdWWxQ2lWOO+b7cMsVw5YFaS04oHpZRWehI1h0fV1gF4wgGCTyQHHjJDfbNpwOi6PXEafRBBezw=="],
"@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.45.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-Pr2o0lvTwsiG4HCr43Zy9xXrHspyMvsvEw4FwKYqhli4FuLE5FjcZzuQ4cfPe0iUFCvSQG6lACI0xj74FDZKRA=="],
"@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.44.2", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-W4tt4BLorKND4qeHElxDoim0+BsprFTwb+vriVQnFFtT/P6v/xO5I99xvYnVzKWrK6j7Hb0yp3x7V5LUbaeOMg=="],
"@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.45.0", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-lYE8LkE5h4a/+6VnnLiL14zWMPnx6wNbDG23GcYFpRW1V9hYWHAw9lBZ6ZUIrOaoK7NliF1sdwYGiVmziUF4vA=="],
"@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.44.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-tdT1PHopokkuBVyHjvYehnIe20fxibxFCEhQP/96MDSOcyjM/shlTkZZLOufV3qO6/FQOSiJTBebhVc12JyPTA=="],
"@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.45.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-PVQWZK9sbzpvqC9Q0GlehNNSVHR+4m7+wET+7FgSnKG3ci5nAMgGmr9mGBXzAuE5SvguCKJ6mHL6vq1JaJ/gvw=="],
"@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.44.2", "", { "os": "linux", "cpu": "arm" }, "sha512-+xmiDGGaSfIIOXMzkhJ++Oa0Gwvl9oXUeIiwarsdRXSe27HUIvjbSIpPxvnNsRebsNdUo7uAiQVgBD1hVriwSQ=="],
"@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.45.0", "", { "os": "linux", "cpu": "arm" }, "sha512-hLrmRl53prCcD+YXTfNvXd776HTxNh8wPAMllusQ+amcQmtgo3V5i/nkhPN6FakW+QVLoUUr2AsbtIRPFU3xIA=="],
"@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.44.2", "", { "os": "linux", "cpu": "arm" }, "sha512-bDHvhzOfORk3wt8yxIra8N4k/N0MnKInCW5OGZaeDYa/hMrdPaJzo7CSkjKZqX4JFUWjUGm88lI6QJLCM7lDrA=="],
"@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.45.0", "", { "os": "linux", "cpu": "arm" }, "sha512-XBKGSYcrkdiRRjl+8XvrUR3AosXU0NvF7VuqMsm7s5nRy+nt58ZMB19Jdp1RdqewLcaYnpk8zeVs/4MlLZEJxw=="],
"@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.44.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-NMsDEsDiYghTbeZWEGnNi4F0hSbGnsuOG+VnNvxkKg0IGDvFh7UVpM/14mnMwxRxUf9AdAVJgHPvKXf6FpMB7A=="],
"@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.45.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-fRvZZPUiBz7NztBE/2QnCS5AtqLVhXmUOPj9IHlfGEXkapgImf4W9+FSkL8cWqoAjozyUzqFmSc4zh2ooaeF6g=="],
"@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.44.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-lb5bxXnxXglVq+7imxykIp5xMq+idehfl+wOgiiix0191av84OqbjUED+PRC5OA8eFJYj5xAGcpAZ0pF2MnW+A=="],
"@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.45.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-Btv2WRZOcUGi8XU80XwIvzTg4U6+l6D0V6sZTrZx214nrwxw5nAi8hysaXj/mctyClWgesyuxbeLylCBNauimg=="],
"@rollup/rollup-linux-loongarch64-gnu": ["@rollup/rollup-linux-loongarch64-gnu@4.44.2", "", { "os": "linux", "cpu": "none" }, "sha512-Yl5Rdpf9pIc4GW1PmkUGHdMtbx0fBLE1//SxDmuf3X0dUC57+zMepow2LK0V21661cjXdTn8hO2tXDdAWAqE5g=="],
"@rollup/rollup-linux-loongarch64-gnu": ["@rollup/rollup-linux-loongarch64-gnu@4.45.0", "", { "os": "linux", "cpu": "none" }, "sha512-Li0emNnwtUZdLwHjQPBxn4VWztcrw/h7mgLyHiEI5Z0MhpeFGlzaiBHpSNVOMB/xucjXTTcO+dhv469Djr16KA=="],
"@rollup/rollup-linux-powerpc64le-gnu": ["@rollup/rollup-linux-powerpc64le-gnu@4.44.2", "", { "os": "linux", "cpu": "ppc64" }, "sha512-03vUDH+w55s680YYryyr78jsO1RWU9ocRMaeV2vMniJJW/6HhoTBwyyiiTPVHNWLnhsnwcQ0oH3S9JSBEKuyqw=="],
"@rollup/rollup-linux-powerpc64le-gnu": ["@rollup/rollup-linux-powerpc64le-gnu@4.45.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-sB8+pfkYx2kvpDCfd63d5ScYT0Fz1LO6jIb2zLZvmK9ob2D8DeVqrmBDE0iDK8KlBVmsTNzrjr3G1xV4eUZhSw=="],
"@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.44.2", "", { "os": "linux", "cpu": "none" }, "sha512-iYtAqBg5eEMG4dEfVlkqo05xMOk6y/JXIToRca2bAWuqjrJYJlx/I7+Z+4hSrsWU8GdJDFPL4ktV3dy4yBSrzg=="],
"@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.45.0", "", { "os": "linux", "cpu": "none" }, "sha512-5GQ6PFhh7E6jQm70p1aW05G2cap5zMOvO0se5JMecHeAdj5ZhWEHbJ4hiKpfi1nnnEdTauDXxPgXae/mqjow9w=="],
"@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.44.2", "", { "os": "linux", "cpu": "none" }, "sha512-e6vEbgaaqz2yEHqtkPXa28fFuBGmUJ0N2dOJK8YUfijejInt9gfCSA7YDdJ4nYlv67JfP3+PSWFX4IVw/xRIPg=="],
"@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.45.0", "", { "os": "linux", "cpu": "none" }, "sha512-N/euLsBd1rekWcuduakTo/dJw6U6sBP3eUq+RXM9RNfPuWTvG2w/WObDkIvJ2KChy6oxZmOSC08Ak2OJA0UiAA=="],
"@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.44.2", "", { "os": "linux", "cpu": "s390x" }, "sha512-evFOtkmVdY3udE+0QKrV5wBx7bKI0iHz5yEVx5WqDJkxp9YQefy4Mpx3RajIVcM6o7jxTvVd/qpC1IXUhGc1Mw=="],
"@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.45.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-2l9sA7d7QdikL0xQwNMO3xURBUNEWyHVHfAsHsUdq+E/pgLTUcCE+gih5PCdmyHmfTDeXUWVhqL0WZzg0nua3g=="],
"@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.44.2", "", { "os": "linux", "cpu": "x64" }, "sha512-/bXb0bEsWMyEkIsUL2Yt5nFB5naLAwyOWMEviQfQY1x3l5WsLKgvZf66TM7UTfED6erckUVUJQ/jJ1FSpm3pRQ=="],
"@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.45.0", "", { "os": "linux", "cpu": "x64" }, "sha512-XZdD3fEEQcwG2KrJDdEQu7NrHonPxxaV0/w2HpvINBdcqebz1aL+0vM2WFJq4DeiAVT6F5SUQas65HY5JDqoPw=="],
"@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.44.2", "", { "os": "linux", "cpu": "x64" }, "sha512-3D3OB1vSSBXmkGEZR27uiMRNiwN08/RVAcBKwhUYPaiZ8bcvdeEwWPvbnXvvXHY+A/7xluzcN+kaiOFNiOZwWg=="],
"@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.45.0", "", { "os": "linux", "cpu": "x64" }, "sha512-7ayfgvtmmWgKWBkCGg5+xTQ0r5V1owVm67zTrsEY1008L5ro7mCyGYORomARt/OquB9KY7LpxVBZes+oSniAAQ=="],
"@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.44.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-VfU0fsMK+rwdK8mwODqYeM2hDrF2WiHaSmCBrS7gColkQft95/8tphyzv2EupVxn3iE0FI78wzffoULH1G+dkw=="],
"@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.45.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-B+IJgcBnE2bm93jEW5kHisqvPITs4ddLOROAcOc/diBgrEiQJJ6Qcjby75rFSmH5eMGrqJryUgJDhrfj942apQ=="],
"@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.44.2", "", { "os": "win32", "cpu": "ia32" }, "sha512-+qMUrkbUurpE6DVRjiJCNGZBGo9xM4Y0FXU5cjgudWqIBWbcLkjE3XprJUsOFgC6xjBClwVa9k6O3A7K3vxb5Q=="],
"@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.45.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-+CXwwG66g0/FpWOnP/v1HnrGVSOygK/osUbu3wPRy8ECXjoYKjRAyfxYpDQOfghC5qPJYLPH0oN4MCOjwgdMug=="],
"@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.44.2", "", { "os": "win32", "cpu": "x64" }, "sha512-3+QZROYfJ25PDcxFF66UEk8jGWigHJeecZILvkPkyQN7oc5BvFo4YEXFkOs154j3FTMp9mn9Ky8RCOwastduEA=="],
"@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.45.0", "", { "os": "win32", "cpu": "x64" }, "sha512-SRf1cytG7wqcHVLrBc9VtPK4pU5wxiB/lNIkNmW2ApKXIg+RpqwHfsaEK+e7eH4A1BpI6BX/aBWXxZCIrJg3uA=="],
"@shikijs/core": ["@shikijs/core@3.8.1", "", { "dependencies": { "@shikijs/types": "3.8.1", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-uTSXzUBQ/IgFcUa6gmGShCHr4tMdR3pxUiiWKDm8pd42UKJdYhkAYsAmHX5mTwybQ5VyGDgTjW4qKSsRvGSang=="],
@ -203,7 +206,7 @@
"@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/oxide-linux-x64-musl@4.1.11", "", { "os": "linux", "cpu": "x64" }, "sha512-e3C/RRhGunWYNC3aSF7exsQkdXzQ/M+aYuZHKnw4U7KQwTJotnWsGOIVih0s2qQzmEzOFIJ3+xt7iq67K/p56Q=="],
"@tailwindcss/oxide-wasm32-wasi": ["@tailwindcss/oxide-wasm32-wasi@4.1.11", "", { "dependencies": { "@emnapi/core": "^1.4.3", "@emnapi/runtime": "^1.4.3", "@emnapi/wasi-threads": "^1.0.2", "@napi-rs/wasm-runtime": "^0.2.11", "@tybys/wasm-util": "^0.9.0", "tslib": "^2.8.0" }, "cpu": "none" }, "sha512-Xo1+/GU0JEN/C/dvcammKHzeM6NqKovG+6921MR6oadee5XPBaKOumrJCXvopJ/Qb5TH7LX/UAywbqrP4lax0g=="],
"@tailwindcss/oxide-wasm32-wasi": ["@tailwindcss/oxide-wasm32-wasi@4.1.11", "", { "cpu": "none" }, "sha512-Xo1+/GU0JEN/C/dvcammKHzeM6NqKovG+6921MR6oadee5XPBaKOumrJCXvopJ/Qb5TH7LX/UAywbqrP4lax0g=="],
"@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/oxide-win32-arm64-msvc@4.1.11", "", { "os": "win32", "cpu": "arm64" }, "sha512-UgKYx5PwEKrac3GPNPf6HVMNhUIGuUh4wlDFR2jYYdkX6pL/rn73zTq/4pzUm8fOjAn5L8zDeHp9iXmUGOXZ+w=="],
@ -225,7 +228,7 @@
"@types/mdast": ["@types/mdast@4.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA=="],
"@types/node": ["@types/node@14.18.63", "", {}, "sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ=="],
"@types/node": ["@types/node@24.0.13", "", { "dependencies": { "undici-types": "~7.8.0" } }, "sha512-Qm9OYVOFHFYg3wJoTSrz80hoec5Lia/dPp84do3X7dZvLikQvM1YpmvTBEdIr/e+U8HTkFjLHLnl78K/qjf+jQ=="],
"@types/resolve": ["@types/resolve@1.20.2", "", {}, "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q=="],
@ -239,7 +242,7 @@
"abortcontroller-polyfill": ["abortcontroller-polyfill@1.7.8", "", {}, "sha512-9f1iZ2uWh92VcrU9Y8x+LdM4DLj75VE0MJB8zuF1iUnroEptStw+DQ8EQPMUdfe5k+PkB1uUfDQfWbhstH8LrQ=="],
"acorn": ["acorn@8.15.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="],
"acorn": ["acorn@8.15.0", "", { "bin": "bin/acorn" }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="],
"airtable": ["airtable@0.12.2", "", { "dependencies": { "@types/node": ">=8.0.0 <15", "abort-controller": "^3.0.0", "abortcontroller-polyfill": "^1.4.0", "lodash": "^4.17.21", "node-fetch": "^2.6.7" } }, "sha512-HS3VytUBTKj8A0vPl7DDr5p/w3IOGv6RXL0fv7eczOWAtj9Xe8ri4TAiZRXoOyo+Z/COADCj+oARFenbxhmkIg=="],
@ -277,7 +280,7 @@
"cookie": ["cookie@0.6.0", "", {}, "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw=="],
"cssesc": ["cssesc@3.0.0", "", { "bin": { "cssesc": "bin/cssesc" } }, "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="],
"cssesc": ["cssesc@3.0.0", "", { "bin": "bin/cssesc" }, "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="],
"debug": ["debug@4.4.1", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ=="],
@ -295,7 +298,7 @@
"enhanced-resolve": ["enhanced-resolve@5.18.2", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" } }, "sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ=="],
"esbuild": ["esbuild@0.25.6", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.6", "@esbuild/android-arm": "0.25.6", "@esbuild/android-arm64": "0.25.6", "@esbuild/android-x64": "0.25.6", "@esbuild/darwin-arm64": "0.25.6", "@esbuild/darwin-x64": "0.25.6", "@esbuild/freebsd-arm64": "0.25.6", "@esbuild/freebsd-x64": "0.25.6", "@esbuild/linux-arm": "0.25.6", "@esbuild/linux-arm64": "0.25.6", "@esbuild/linux-ia32": "0.25.6", "@esbuild/linux-loong64": "0.25.6", "@esbuild/linux-mips64el": "0.25.6", "@esbuild/linux-ppc64": "0.25.6", "@esbuild/linux-riscv64": "0.25.6", "@esbuild/linux-s390x": "0.25.6", "@esbuild/linux-x64": "0.25.6", "@esbuild/netbsd-arm64": "0.25.6", "@esbuild/netbsd-x64": "0.25.6", "@esbuild/openbsd-arm64": "0.25.6", "@esbuild/openbsd-x64": "0.25.6", "@esbuild/openharmony-arm64": "0.25.6", "@esbuild/sunos-x64": "0.25.6", "@esbuild/win32-arm64": "0.25.6", "@esbuild/win32-ia32": "0.25.6", "@esbuild/win32-x64": "0.25.6" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-GVuzuUwtdsghE3ocJ9Bs8PNoF13HNQ5TXbEi2AhvVb8xU1Iwt9Fos9FEamfoee+u/TOsn7GUWc04lz46n2bbTg=="],
"esbuild": ["esbuild@0.25.6", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.6", "@esbuild/android-arm": "0.25.6", "@esbuild/android-arm64": "0.25.6", "@esbuild/android-x64": "0.25.6", "@esbuild/darwin-arm64": "0.25.6", "@esbuild/darwin-x64": "0.25.6", "@esbuild/freebsd-arm64": "0.25.6", "@esbuild/freebsd-x64": "0.25.6", "@esbuild/linux-arm": "0.25.6", "@esbuild/linux-arm64": "0.25.6", "@esbuild/linux-ia32": "0.25.6", "@esbuild/linux-loong64": "0.25.6", "@esbuild/linux-mips64el": "0.25.6", "@esbuild/linux-ppc64": "0.25.6", "@esbuild/linux-riscv64": "0.25.6", "@esbuild/linux-s390x": "0.25.6", "@esbuild/linux-x64": "0.25.6", "@esbuild/netbsd-arm64": "0.25.6", "@esbuild/netbsd-x64": "0.25.6", "@esbuild/openbsd-arm64": "0.25.6", "@esbuild/openbsd-x64": "0.25.6", "@esbuild/openharmony-arm64": "0.25.6", "@esbuild/sunos-x64": "0.25.6", "@esbuild/win32-arm64": "0.25.6", "@esbuild/win32-ia32": "0.25.6", "@esbuild/win32-x64": "0.25.6" }, "bin": "bin/esbuild" }, "sha512-GVuzuUwtdsghE3ocJ9Bs8PNoF13HNQ5TXbEi2AhvVb8xU1Iwt9Fos9FEamfoee+u/TOsn7GUWc04lz46n2bbTg=="],
"esm-env": ["esm-env@1.2.2", "", {}, "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA=="],
@ -305,7 +308,7 @@
"event-target-shim": ["event-target-shim@5.0.1", "", {}, "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ=="],
"fdir": ["fdir@6.4.6", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w=="],
"fdir": ["fdir@6.4.6", "", { "peerDependencies": { "picomatch": "^3 || ^4" } }, "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w=="],
"fecha": ["fecha@4.2.3", "", {}, "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw=="],
@ -339,7 +342,7 @@
"is-stream": ["is-stream@2.0.1", "", {}, "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg=="],
"jiti": ["jiti@2.4.2", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A=="],
"jiti": ["jiti@2.4.2", "", { "bin": "lib/jiti-cli.mjs" }, "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A=="],
"kleur": ["kleur@4.1.5", "", {}, "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ=="],
@ -403,7 +406,7 @@
"minizlib": ["minizlib@3.0.2", "", { "dependencies": { "minipass": "^7.1.2" } }, "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA=="],
"mkdirp": ["mkdirp@3.0.1", "", { "bin": { "mkdirp": "dist/cjs/src/bin.js" } }, "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg=="],
"mkdirp": ["mkdirp@3.0.1", "", { "bin": "dist/cjs/src/bin.js" }, "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg=="],
"mri": ["mri@1.2.0", "", {}, "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA=="],
@ -411,7 +414,7 @@
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
"nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
"nanoid": ["nanoid@3.3.11", "", { "bin": "bin/nanoid.cjs" }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
"node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="],
@ -431,7 +434,7 @@
"postcss-selector-parser": ["postcss-selector-parser@6.0.10", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w=="],
"prettier": ["prettier@3.6.2", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ=="],
"prettier": ["prettier@3.6.2", "", { "bin": "bin/prettier.cjs" }, "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ=="],
"prettier-plugin-svelte": ["prettier-plugin-svelte@3.4.0", "", { "peerDependencies": { "prettier": "^3.0.0", "svelte": "^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0" } }, "sha512-pn1ra/0mPObzqoIQn/vUTR3ZZI6UuZ0sHqMK5x2jMLGrs53h0sXhkVuDcrlssHwIMk7FYrMjHBPoUSyyEEDlBQ=="],
@ -451,9 +454,9 @@
"regex-utilities": ["regex-utilities@2.3.0", "", {}, "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng=="],
"resolve": ["resolve@1.22.10", "", { "dependencies": { "is-core-module": "^2.16.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w=="],
"resolve": ["resolve@1.22.10", "", { "dependencies": { "is-core-module": "^2.16.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": "bin/resolve" }, "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w=="],
"rollup": ["rollup@4.44.2", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.44.2", "@rollup/rollup-android-arm64": "4.44.2", "@rollup/rollup-darwin-arm64": "4.44.2", "@rollup/rollup-darwin-x64": "4.44.2", "@rollup/rollup-freebsd-arm64": "4.44.2", "@rollup/rollup-freebsd-x64": "4.44.2", "@rollup/rollup-linux-arm-gnueabihf": "4.44.2", "@rollup/rollup-linux-arm-musleabihf": "4.44.2", "@rollup/rollup-linux-arm64-gnu": "4.44.2", "@rollup/rollup-linux-arm64-musl": "4.44.2", "@rollup/rollup-linux-loongarch64-gnu": "4.44.2", "@rollup/rollup-linux-powerpc64le-gnu": "4.44.2", "@rollup/rollup-linux-riscv64-gnu": "4.44.2", "@rollup/rollup-linux-riscv64-musl": "4.44.2", "@rollup/rollup-linux-s390x-gnu": "4.44.2", "@rollup/rollup-linux-x64-gnu": "4.44.2", "@rollup/rollup-linux-x64-musl": "4.44.2", "@rollup/rollup-win32-arm64-msvc": "4.44.2", "@rollup/rollup-win32-ia32-msvc": "4.44.2", "@rollup/rollup-win32-x64-msvc": "4.44.2", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-PVoapzTwSEcelaWGth3uR66u7ZRo6qhPHc0f2uRO9fX6XDVNrIiGYS0Pj9+R8yIIYSD/mCx2b16Ws9itljKSPg=="],
"rollup": ["rollup@4.45.0", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.45.0", "@rollup/rollup-android-arm64": "4.45.0", "@rollup/rollup-darwin-arm64": "4.45.0", "@rollup/rollup-darwin-x64": "4.45.0", "@rollup/rollup-freebsd-arm64": "4.45.0", "@rollup/rollup-freebsd-x64": "4.45.0", "@rollup/rollup-linux-arm-gnueabihf": "4.45.0", "@rollup/rollup-linux-arm-musleabihf": "4.45.0", "@rollup/rollup-linux-arm64-gnu": "4.45.0", "@rollup/rollup-linux-arm64-musl": "4.45.0", "@rollup/rollup-linux-loongarch64-gnu": "4.45.0", "@rollup/rollup-linux-powerpc64le-gnu": "4.45.0", "@rollup/rollup-linux-riscv64-gnu": "4.45.0", "@rollup/rollup-linux-riscv64-musl": "4.45.0", "@rollup/rollup-linux-s390x-gnu": "4.45.0", "@rollup/rollup-linux-x64-gnu": "4.45.0", "@rollup/rollup-linux-x64-musl": "4.45.0", "@rollup/rollup-win32-arm64-msvc": "4.45.0", "@rollup/rollup-win32-ia32-msvc": "4.45.0", "@rollup/rollup-win32-x64-msvc": "4.45.0", "fsevents": "~2.3.2" }, "bin": "dist/bin/rollup" }, "sha512-WLjEcJRIo7i3WDDgOIJqVI2d+lAC3EwvOGy+Xfq6hs+GQuAA4Di/H72xmXkOhrIWFg2PFYSKZYfH0f4vfKXN4A=="],
"sade": ["sade@1.8.1", "", { "dependencies": { "mri": "^1.1.0" } }, "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A=="],
@ -481,9 +484,9 @@
"supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="],
"svelte": ["svelte@5.35.6", "", { "dependencies": { "@ampproject/remapping": "^2.3.0", "@jridgewell/sourcemap-codec": "^1.5.0", "@sveltejs/acorn-typescript": "^1.0.5", "@types/estree": "^1.0.5", "acorn": "^8.12.1", "aria-query": "^5.3.1", "axobject-query": "^4.1.0", "clsx": "^2.1.1", "esm-env": "^1.2.1", "esrap": "^2.1.0", "is-reference": "^3.0.3", "locate-character": "^3.0.0", "magic-string": "^0.30.11", "zimmerframe": "^1.1.2" } }, "sha512-p7PVLQYrvCxJuxzGfOv/l71hVuHC6EZk5UDjbt/bndMYaBcUV5sFjDsj+PSIYvz1vcfbG6inX83/xIUeik1xGA=="],
"svelte": ["svelte@5.35.7", "", { "dependencies": { "@ampproject/remapping": "^2.3.0", "@jridgewell/sourcemap-codec": "^1.5.0", "@sveltejs/acorn-typescript": "^1.0.5", "@types/estree": "^1.0.5", "acorn": "^8.12.1", "aria-query": "^5.3.1", "axobject-query": "^4.1.0", "clsx": "^2.1.1", "esm-env": "^1.2.1", "esrap": "^2.1.0", "is-reference": "^3.0.3", "locate-character": "^3.0.0", "magic-string": "^0.30.11", "zimmerframe": "^1.1.2" } }, "sha512-J3DeZKCWXyHodN6kpXHgIpXz1HkVAC2PbnlBGDfT7Y8kUMkklzI4n7mohjUR0x1AGPX8NEzAfdUaRHglegxQXw=="],
"svelte-check": ["svelte-check@4.2.2", "", { "dependencies": { "@jridgewell/trace-mapping": "^0.3.25", "chokidar": "^4.0.1", "fdir": "^6.2.0", "picocolors": "^1.0.0", "sade": "^1.7.4" }, "peerDependencies": { "svelte": "^4.0.0 || ^5.0.0-next.0", "typescript": ">=5.0.0" }, "bin": { "svelte-check": "bin/svelte-check" } }, "sha512-1+31EOYZ7NKN0YDMKusav2hhEoA51GD9Ws6o//0SphMT0ve9mBTsTUEX7OmDMadUP3KjNHsSKtJrqdSaD8CrGQ=="],
"svelte-check": ["svelte-check@4.2.2", "", { "dependencies": { "@jridgewell/trace-mapping": "^0.3.25", "chokidar": "^4.0.1", "fdir": "^6.2.0", "picocolors": "^1.0.0", "sade": "^1.7.4" }, "peerDependencies": { "svelte": "^4.0.0 || ^5.0.0-next.0", "typescript": ">=5.0.0" }, "bin": "bin/svelte-check" }, "sha512-1+31EOYZ7NKN0YDMKusav2hhEoA51GD9Ws6o//0SphMT0ve9mBTsTUEX7OmDMadUP3KjNHsSKtJrqdSaD8CrGQ=="],
"tailwindcss": ["tailwindcss@4.1.11", "", {}, "sha512-2E9TBm6MDD/xKYe+dvJZAmg3yxIEDNRc0jwlNyDg/4Fil2QcSLjFKGVff0lAf1jjeaArlG/M75Ey/EYr/OJtBA=="],
@ -505,6 +508,8 @@
"typescript": ["typescript@5.8.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ=="],
"undici-types": ["undici-types@7.8.0", "", {}, "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw=="],
"unist-util-is": ["unist-util-is@4.1.0", "", {}, "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg=="],
"unist-util-position": ["unist-util-position@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA=="],
@ -521,9 +526,9 @@
"vfile-message": ["vfile-message@2.0.4", "", { "dependencies": { "@types/unist": "^2.0.0", "unist-util-stringify-position": "^2.0.0" } }, "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ=="],
"vite": ["vite@7.0.4", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.6", "picomatch": "^4.0.2", "postcss": "^8.5.6", "rollup": "^4.40.0", "tinyglobby": "^0.2.14" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-SkaSguuS7nnmV7mfJ8l81JGBFV7Gvzp8IzgE8A8t23+AxuNX61Q5H1Tpz5efduSN7NHC8nQXD3sKQKZAu5mNEA=="],
"vite": ["vite@7.0.4", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.6", "picomatch": "^4.0.2", "postcss": "^8.5.6", "rollup": "^4.40.0", "tinyglobby": "^0.2.14" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["less", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": "bin/vite.js" }, "sha512-SkaSguuS7nnmV7mfJ8l81JGBFV7Gvzp8IzgE8A8t23+AxuNX61Q5H1Tpz5efduSN7NHC8nQXD3sKQKZAu5mNEA=="],
"vitefu": ["vitefu@1.1.1", "", { "peerDependencies": { "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0" }, "optionalPeers": ["vite"] }, "sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ=="],
"vitefu": ["vitefu@1.1.1", "", { "peerDependencies": { "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0" } }, "sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ=="],
"webidl-conversions": ["webidl-conversions@3.0.1", "", {}, "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="],
@ -541,17 +546,7 @@
"@rollup/plugin-commonjs/is-reference": ["is-reference@1.2.1", "", { "dependencies": { "@types/estree": "*" } }, "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ=="],
"@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.4.4", "", { "dependencies": { "@emnapi/wasi-threads": "1.0.3", "tslib": "^2.4.0" }, "bundled": true }, "sha512-A9CnAbC6ARNMKcIcrQwq6HeHCjpcBZ5wSx4U01WXCqEKlrzB9F9315WDNHkrs2xbx7YjjSxbUYxuN6EQzpcY2g=="],
"@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.4.4", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-hHyapA4A3gPaDCNfiqyZUStTMqIkKRshqPIuDOXv1hcBnD4U3l8cP0T1HMCfGRxQ6V64TGCcoswChANyOAwbQg=="],
"@tailwindcss/oxide-wasm32-wasi/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.0.3", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-8K5IFFsQqF9wQNJptGbS6FNKgUTsSRYnTqNCG1vPP8jFdjSv18n2mQfJpkt2Oibo9iBEzcDnDxNwKTzC7svlJw=="],
"@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@0.2.12", "", { "dependencies": { "@emnapi/core": "^1.4.3", "@emnapi/runtime": "^1.4.3", "@tybys/wasm-util": "^0.10.0" }, "bundled": true }, "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ=="],
"@tailwindcss/oxide-wasm32-wasi/@tybys/wasm-util": ["@tybys/wasm-util@0.9.0", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw=="],
"@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
"airtable/@types/node": ["@types/node@14.18.63", "", {}, "sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ=="],
"hast-util-to-html/@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="],
@ -563,8 +558,6 @@
"vfile/vfile-message": ["vfile-message@4.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw=="],
"@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime/@tybys/wasm-util": ["@tybys/wasm-util@0.10.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-VyyPYFlOMNylG45GoAe0xDoLwWuowvf92F9kySqzYh8vmYm7D2u4iUJKa1tOUpS70Ku13ASrOkS4ScXFsTaCNQ=="],
"mdast-util-to-hast/unist-util-visit/@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="],
"mdast-util-to-hast/unist-util-visit/unist-util-is": ["unist-util-is@6.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw=="],

BIN
bun.lockb

Binary file not shown.

BIN
daydreamkl.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

29
package-lock.json generated
View file

@ -9,6 +9,7 @@
"version": "0.0.1",
"dependencies": {
"@fontsource/atkinson-hyperlegible": "^5.2.6",
"@fontsource/jersey-15": "^5.2.6",
"@sveltejs/adapter-node": "^5.2.13",
"@sveltejs/adapter-static": "^3.0.8",
"@tailwindcss/typography": "^0.5.16",
@ -493,6 +494,15 @@
"url": "https://github.com/sponsors/ayuhito"
}
},
"node_modules/@fontsource/jersey-15": {
"version": "5.2.6",
"resolved": "https://registry.npmjs.org/@fontsource/jersey-15/-/jersey-15-5.2.6.tgz",
"integrity": "sha512-3zkkEnu91esusWLqAK/AN1uc6jNtWT8idfO0UfYLqNlbMBKkbbiIVXtq6UbQsyegxnmRMppVV1J2t1zrJ36VgA==",
"license": "OFL-1.1",
"funding": {
"url": "https://github.com/sponsors/ayuhito"
}
},
"node_modules/@isaacs/fs-minipass": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz",
@ -1415,17 +1425,6 @@
"@types/unist": "*"
}
},
"node_modules/@types/node": {
"version": "24.0.13",
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.0.13.tgz",
"integrity": "sha512-Qm9OYVOFHFYg3wJoTSrz80hoec5Lia/dPp84do3X7dZvLikQvM1YpmvTBEdIr/e+U8HTkFjLHLnl78K/qjf+jQ==",
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"undici-types": "~7.8.0"
}
},
"node_modules/@types/resolve": {
"version": "1.20.2",
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz",
@ -3194,14 +3193,6 @@
"node": ">=14.17"
}
},
"node_modules/undici-types": {
"version": "7.8.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz",
"integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==",
"license": "MIT",
"optional": true,
"peer": true
},
"node_modules/unist-util-is": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz",

View file

@ -18,7 +18,6 @@
"@sveltejs/kit": "^2.22.0",
"@sveltejs/vite-plugin-svelte": "^6.0.0",
"@tailwindcss/vite": "^4.0.0",
"mdsvex": "^0.12.6",
"prettier": "^3.4.2",
"prettier-plugin-svelte": "^3.3.3",
"svelte": "^5.0.0",
@ -29,6 +28,7 @@
},
"dependencies": {
"@fontsource/atkinson-hyperlegible": "^5.2.6",
"@fontsource/jersey-15": "^5.2.6",
"@sveltejs/adapter-node": "^5.2.13",
"@sveltejs/adapter-static": "^3.0.8",
"@tailwindcss/typography": "^0.5.16",
@ -37,6 +37,7 @@
"gsap": "^3.13.0",
"leaflet": "^1.9.4",
"lenis": "^1.3.4",
"mdsvex": "^0.12.6",
"shiki": "^3.8.1",
"winston": "^3.17.0"
}

View file

@ -1,9 +1,10 @@
@import 'tailwindcss';
@plugin '@tailwindcss/typography';
@import '@fontsource/atkinson-hyperlegible';
@import '@fontsource/jersey-15';
@font-face {
font-family: 'Expensify New Kansas';
font-family: 'Daydream New';
font-display: swap;
src: url('/fonts/serif.woff') format('woff');
font-weight: 400;
@ -11,7 +12,7 @@
}
@font-face {
font-family: 'Expensify New Kansas';
font-family: 'Daydream New';
font-display: swap;
src: url('/fonts/serif-italic.woff') format('woff');
font-weight: 400;
@ -20,7 +21,8 @@
@theme {
--font-sans: 'Atkinson Hyperlegible', ui-sans-serif, sans-serif;
--font-serif: 'Expensify New Kansas', ui-serif, serif;
--font-serif: 'Daydream New', ui-serif, serif;
--font-pixel: 'Jersey 15', monospace;
--color-gradient-daydream: linear-gradient(to bottom, #487DAB, #3F709A);
--color-daydream: #44DBC8;
--color-daydream-hover: #3CC2AF;

20
src/hooks.server.ts Normal file
View file

@ -0,0 +1,20 @@
import type { Handle } from '@sveltejs/kit';
export const handle: Handle = async ({ event, resolve }) => {
const response = await resolve(event);
// Add CORS headers for all requests
response.headers.set('Access-Control-Allow-Origin', '*');
response.headers.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
response.headers.set('Access-Control-Allow-Headers', 'Content-Type, Authorization');
// Specific headers for font files and static assets
if (event.url.pathname.includes('/fonts/') ||
event.url.pathname.includes('/static/') ||
event.url.pathname.match(/\.(woff|woff2|ttf|otf|eot|css|js|png|jpg|jpeg|gif|svg)$/)) {
response.headers.set('Access-Control-Allow-Origin', '*');
response.headers.set('Cache-Control', 'public, max-age=31536000');
}
return response;
};

View file

@ -10,7 +10,9 @@
<style>
.cloud-wrapper {
background: white;
display: inline-block;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
padding: 48px;
mask-image:

View file

@ -0,0 +1,50 @@
<div class="w-full bg-[#FFFFF8] relative min-h-80">
<div
class="absolute top-0 left-0 w-full h-full bg-[url('/noise.png')] bg-repeat opacity-10 pointer-events-none z-0"
></div>
<div
class="opacity-60 absolute w-full h-32 bg-[url('brushstroking.png')] bg-repeat-x z-10 bg-size-[100vw_100vh] mix-blend-overlay"
style="mask-image: url(/footer-clouds.png); mask-size: contain; mask-repeat: repeat-x; -webkit-mask-image: url(/footer-clouds.png); -webkit-mask-size: contain; -webkit-mask-repeat: repeat-x;"
></div>
<div
class="w-full h-32 bg-[#e99cce] z-5"
style="mask-image: url(/footer-clouds.png); mask-size: contain; mask-repeat: repeat-x; -webkit-mask-image: url(/footer-clouds.png); -webkit-mask-size: contain; -webkit-mask-repeat: repeat-x;"
></div>
<!-- Footer Text -->
<div
class="absolute bottom-20 left-32 text-center z-20 max-md:bottom-12 max-md:left-8 max-md:right-4 max-md:text-left"
>
<p class="text-gray-700 mb-2">Made with ♡ by teenagers, for teenagers at Hack Club</p>
<div class="flex space-x-4 max-md:flex-col max-md:space-x-0 max-md:space-y-2">
<a
href="https://hackclub.com"
class="underline text-gray-700 hover:text-gray-900 transition-colors">Hack Club</a
>
<span class="text-gray-700 max-md:hidden"></span>
<a
href="https://hackclub.com/slack"
class="underline text-gray-700 hover:text-gray-900 transition-colors">Slack</a
>
<span class="text-gray-700 max-md:hidden"></span>
<a
href="https://hackclub.com/clubs"
class="underline text-gray-700 hover:text-gray-900 transition-colors">Clubs</a
>
<span class="text-gray-700 max-md:hidden"></span>
<a
href="https://hackclub.com/hackathons"
class="underline text-gray-700 hover:text-gray-900 transition-colors">Hackathons</a
>
</div>
</div>
<div
class="max-sm:hidden absolute bottom-2 right-16 h-2/3 aspect-square bg-[url('brushstroking.png')] bg-repeat z-10 bg-size-[100vw_100vh] mix-blend-overlay"
style="mask-image: url(/thought-bubbles.png); mask-size: contain; mask-repeat: no-repeat; -webkit-mask-image: url(/thought-bubbles.png); -webkit-mask-size: contain; -webkit-mask-repeat: no-repeat;"
></div>
<div
class="max-sm:hidden absolute bottom-2 right-16 h-2/3 aspect-square bg-[#e99cce]"
style="mask-image: url(/thought-bubbles.png); mask-size: contain; mask-repeat: no-repeat; -webkit-mask-image: url(/thought-bubbles.png); -webkit-mask-size: contain; -webkit-mask-repeat: no-repeat;"
></div>
</div>

View file

@ -0,0 +1,113 @@
<script lang="ts">
import { page } from '$app/stores';
let submitted = false;
let fadeOut = false;
$: city = $page.url.pathname.split('/')[1] || '';
function handleFormSubmit(event: Event) {
event.preventDefault();
const form = event.target as HTMLFormElement;
const emailInput = form.querySelector('input[name="email"]') as HTMLInputElement;
const email = emailInput.value;
fetch('/api/rsvp', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ email, city })
}).catch(error => {
console.warn('Failed to save email:', error);
});
submitted = true;
emailInput.value = '';
setTimeout(() => {
fadeOut = true;
}, 1500);
setTimeout(() => {
submitted = false;
fadeOut = false;
}, 1500 + 500);
if (city === 'suceava') {
window.location.href = `https://forms.fillout.com/t/wABjdnkgLWus?email=${encodeURIComponent(email)}`;
}
}
</script>
<style>
@keyframes slide-in {
from {
transform: translateX(-100%);
}
to {
transform: translateX(0);
}
}
.animate-slide-in {
animation: slide-in 0.3s cubic-bezier(0, 0.55, 0.45, 1);
}
.animate-fade-out {
animation: fade-out 0.5s ease-out forwards;
}
@keyframes fade-out {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
</style>
<div class="mt-8 flex flex-col items-center gap-3 z-5 max-md:scale-90">
<div class="relative rounded-full overflow-hidden" style="padding: 2px 2px 5px 2px;">
<form on:submit={handleFormSubmit} class="rounded-full bg-white border-2 border-dark font-sans p-2 flex flex-row items-center gap-2 shadow-[0_3px_0_0_theme(colors.dark)] focus-within:border-pink focus-within:shadow-[0_3px_0_0_#E472AB] has-[button:active]:border-dark has-[button:active]:shadow-[0_3px_0_0_theme(colors.dark)] has-[button:focus]:border-dark has-[button:focus]:shadow-[0_3px_0_0_theme(colors.dark)]">
<input
type="email"
name="email"
placeholder="Enter email to RSVP"
class="w-80 px-3 py-1 text-dark focus:outline-none flex-1"
required
/>
<input type="hidden" name="mailingLists" value="cmd3c94kz0hvz0iwt7ps28cyd" />
<button type="submit" class="bg-light h-full px-5 py-[0.45rem] rounded-full border-b-2 border-[#B3866A] cursor-pointer hover:border-b-4 hover:transform active:border-b-0 active:transform active:translate-y-0.5 focus:outline-none transition-all duration-100 flex-shrink-0">
<img src="submit.svg" alt="Go">
</button>
</form>
<!-- Success overlay that slides in from left -->
{#if submitted}
<div class="absolute inset-0 -top-4 -bottom-4 bg-[#44DBC8] rounded-full flex items-center justify-center z-20 animate-slide-in {fadeOut ? 'animate-fade-out' : ''}">
<span class="text-white font-sans text-lg">RSVPed!</span>
</div>
{/if}
</div>
<a
href="https://forms.hackclub.com/daydream-stickers"
target="_blank"
class="w-max px-4 py-2 bg-pink border-b-2 border-b-pink-dark text-white rounded-full active:transform active:translate-y-0.5 transition-all duration-100 font-sans cursor-pointer mx-auto relative overflow-visible hover:shadow-[0_2px_0_0_theme(colors.pink.dark)] hover:-translate-y-[2px] active:border-transparent active:shadow-none active: mt-4 md:hidden"
>
Get free stickers
<img
src="button-clouds.svg"
alt=""
class="absolute bottom-0 left-1/2 -translate-x-1/2 w-auto object-contain pointer-events-none"
>
<img
src="rock-sticker.png"
alt=""
class="absolute bottom-2 right-3 translate-2/3 w-18 h-18 object-contain pointer-events-none"
style="transform: rotate(-15deg);"
>
</a>
</div>

View file

@ -0,0 +1,59 @@
<script lang="ts">
export let tickerText: string;
</script>
<!-- Animated text ticker along curvy line -->
<div
class="absolute top-0 left-1/2 -translate-x-1/2 w-full h-full pointer-events-none lg:-translate-y-35 -translate-y-20 overflow-hidden max-md:w-200 max-lg:w-[125%]"
>
<svg
width="1280"
height="464"
viewBox="0 0 1280 464"
class="w-full h-max pt-32 object-contain"
xmlns="http://www.w3.org/2000/svg"
>
<defs>
<path
id="curvy-path"
d="M-41 274.995C91.5 229.995 203.5 64.4946 483.5 39.9946C763.5 15.4946 892.5 151.495 1165 196.495C1383 232.495 1462.5 263.828 1475 274.995"
/>
<mask id="reveal-mask">
<rect x="0" y="0" width="0" height="464" fill="white">
<animate
attributeName="width"
values="0;1280"
dur="2s"
calcMode="spline"
keySplines="0.05,0.7,0.3,1"
keyTimes="0;1"
begin="0.75s"
fill="freeze"
/>
</rect>
</mask>
</defs>
<g mask="url(#reveal-mask)">
<!-- Background path stroke -->
<path
d="M-41 268.495C91.5 223.495 203.5 57.9946 483.5 33.4946C763.5 8.9946 892.5 144.995 1165 189.995C1383 225.995 1462.5 257.328 1475 268.495"
stroke="#9EE4F2"
stroke-width="28"
fill="none"
stroke-linecap="round"
/>
<text font-family="sans-serif" fill="#EDFCFF" font-weight="bold" font-size="18">
<textPath href="#curvy-path" startOffset="-100%">
{@html Array(2).fill(tickerText).join(' • ')}
<animate
id="ticker-animation"
attributeName="startOffset"
values="-100%;0%"
dur="30s"
repeatCount="indefinite"
/>
</textPath>
</text>
</g>
</svg>
</div>

34
src/routes/+error.svelte Normal file
View file

@ -0,0 +1,34 @@
<script lang="ts">
import { page } from '$app/stores';
import { dev } from '$app/environment';
$: status = $page.status;
</script>
<svelte:head>
<title>Error {status}</title>
</svelte:head>
<div class="min-h-screen w-full relative bg-gradient-to-b from-[#639DEB] to-[#8EC7F0] flex items-center justify-center">
<div class="absolute bottom-0 left-1/2 -translate-x-1/2 w-full h-[80vh] bg-[url(/cloudy-bg.png)] opacity-10 bg-cover bg-no-repeat bg-position-[0_10vh] pointer-events-none"></div>
<div class="absolute inset-0 bg-[url('/brushstroking.png')] bg-size-[100vw_100vh] bg-repeat mix-blend-overlay opacity-60 pointer-events-none"></div>
<div class="relative z-10 text-center text-white flex flex-col">
<h1 class="text-8xl font-serif text-white drop-shadow-lg">{status}</h1>
<p class="text-2xl font-sans text-white mt-1">Something went wrong.</p>
<a
href="/"
class="w-max px-4 py-2 bg-pink border-b-2 border-b-pink-dark text-white rounded-full active:translate-y-0.5 transition-all duration-100 font-sans cursor-pointer mx-auto relative overflow-visible hover:shadow-[0_2px_0_0_theme(colors.pink.dark)] hover:-translate-y-[2px] active:border-transparent active:shadow-none mt-12"
>
Take me somewhere safe
<img
src="/button-clouds.svg"
alt=""
class="absolute bottom-0 left-1/2 -translate-x-1/2 w-auto object-contain pointer-events-none"
>
</a>
</div>
</div>

View file

@ -2,6 +2,8 @@
import { onMount } from "svelte";
import { gsap } from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
import Ticker from "$lib/components/Ticker.svelte";
import Footer from "$lib/components/Footer.svelte";
/** @type {import('./$types').PageData} */
export let data;
@ -30,7 +32,7 @@ Dubai
San Francisco
Minneapolis
Seattle
Signapore
Singapore
Sydney
Mumbai`.split("\n")
@ -581,11 +583,41 @@ Mumbai`.split("\n")
}
</style>
<svelte:head>
<title>Daydream</title>
<title>Daydream - Teen Game Jam by Hack Club</title>
<meta name="description" content="Join Daydream, the worldwide teen-led game jam by Hack Club! 4,000+ hackers building games in 100+ cities. Sign up to organize or participate in your city." />
<meta name="keywords" content="game jam, hackathon, teen coding, Hack Club, game development, teen programming, high school coding" />
<!-- Open Graph / Facebook -->
<meta property="og:type" content="website" />
<meta property="og:url" content="https://daydream.hackclub.com" />
<meta property="og:title" content="Daydream - Teen Game Jam by Hack Club" />
<meta property="og:description" content="Join Daydream, the worldwide teen-led game jam by Hack Club! 4,000+ hackers building games in 100+ cities. Sign up to organize or participate in your city." />
<meta property="og:image" content="https://daydream.hackclub.com/og-image.png" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<meta property="og:site_name" content="Daydream" />
<!-- Twitter -->
<meta property="twitter:card" content="summary_large_image" />
<meta property="twitter:url" content="https://daydream.hackclub.com" />
<meta property="twitter:title" content="Daydream - Teen Game Jam by Hack Club" />
<meta property="twitter:description" content="Join Daydream, the worldwide teen-led game jam by Hack Club! 4,000+ hackers building games in 100+ cities. Sign up to organize or participate in your city." />
<meta property="twitter:image" content="https://daydream.hackclub.com/og-image.png" />
<meta property="twitter:creator" content="@hackclub" />
<meta property="twitter:site" content="@hackclub" />
<!-- Additional SEO -->
<meta name="robots" content="index, follow" />
<meta name="author" content="Hack Club" />
<link rel="canonical" href="https://daydream.hackclub.com" />
<!-- Analytics -->
<script defer data-domain="daydream.hackclub.com" src="https://plausible.io/js/script.js"></script>
</svelte:head>
<div class="absolute top-0 left-0 w-full h-full bg-[url('brushstroking.png')] bg-size-[100vw_100vh] bg-repeat mix-blend-overlay opacity-60 pointer-events-none"></div>
<div class="flex flex-col items-center justify-center h-screen text-center bg-gradient-to-b from-[#CCF4FD] to-[#B8D9F8] bg-blend-overlay relative">
@ -596,30 +628,7 @@ Mumbai`.split("\n")
<div class="buildings-back-parallax absolute top-0 left-0 w-full h-full bg-[url(/buildings-back.png)] bg-no-repeat bg-contain pointer-events-none lg:-translate-y-15"></div>
<!-- Animated text ticker along curvy line -->
<div class="absolute top-0 left-1/2 -translate-x-1/2 w-full h-full pointer-events-none lg:-translate-y-35 -translate-y-20 overflow-hidden max-md:w-200 max-lg:w-[125%]">
<svg width="1280" height="464" viewBox="0 0 1280 464" class="w-full h-max pt-32 object-contain" xmlns="http://www.w3.org/2000/svg">
<defs>
<path id="curvy-path" d="M-41 274.995C91.5 229.995 203.5 64.4946 483.5 39.9946C763.5 15.4946 892.5 151.495 1165 196.495C1383 232.495 1462.5 263.828 1475 274.995"/>
<mask id="reveal-mask">
<rect x="0" y="0" width="0" height="464" fill="white">
<animate attributeName="width" values="0;1280" dur="2s" calcMode="spline" keySplines="0.05,0.7,0.3,1" keyTimes="0;1" begin="0.75s" fill="freeze"/>
</rect>
</mask>
</defs>
<g mask="url(#reveal-mask)">
<!-- Background path stroke -->
<path d="M-41 268.495C91.5 223.495 203.5 57.9946 483.5 33.4946C763.5 8.9946 892.5 144.995 1165 189.995C1383 225.995 1462.5 257.328 1475 268.495"
stroke="#9EE4F2" stroke-width="28" fill="none" stroke-linecap="round"/>
<text font-family="sans-serif" fill="#EDFCFF" font-weight="bold" font-size="18">
<textPath href="#curvy-path" startOffset="-100%">
{@html Array(2).fill(tickerText).join(" • ")}
<animate id="ticker-animation" attributeName="startOffset" values="-100%;0%" dur="30s" repeatCount="indefinite"/>
</textPath>
</text>
</g>
</svg>
</div>
<Ticker {tickerText} />
<!-- brush texture clipped to back buildings -->
<div class="absolute top-0 left-0 w-full h-full bg-[url('brushstroking.png')] bg-size-[100vw_100vh] bg-repeat pointer-events-none opacity-100 lg:-translate-y-15 bg-center mix-blend-overlay" style="mask-image: url('/buildings-back.png'); mask-size: contain; mask-repeat: no-repeat; mask-position: center top; -webkit-mask-image: url('/buildings-back.png'); -webkit-mask-size: contain; -webkit-mask-repeat: no-repeat; -webkit-mask-position: center top;"></div>
@ -1100,28 +1109,7 @@ Mumbai`.split("\n")
<div class="absolute top-0 left-0 w-full h-full bg-[url('brushstroking.png')] bg-size-[100vw_100vh] bg-repeat mix-blend-overlay opacity-60 pointer-events-none"></div>
</div>
<div class="w-full bg-[#FFFFF8] relative min-h-80">
<div class="absolute top-0 left-0 w-full h-full bg-[url('/noise.png')] bg-repeat opacity-10 pointer-events-none z-0"></div>
<div class="opacity-60 absolute w-full h-32 bg-[url('brushstroking.png')] bg-repeat-x z-10 bg-size-[100vw_100vh] mix-blend-overlay" style="mask-image: url(/footer-clouds.png); mask-size: contain; mask-repeat: repeat-x; -webkit-mask-image: url(/footer-clouds.png); -webkit-mask-size: contain; -webkit-mask-repeat: repeat-x;"></div>
<div class="w-full h-32 bg-[#e99cce] z-5" style="mask-image: url(/footer-clouds.png); mask-size: contain; mask-repeat: repeat-x; -webkit-mask-image: url(/footer-clouds.png); -webkit-mask-size: contain; -webkit-mask-repeat: repeat-x;"></div>
<!-- Footer Text -->
<div class="absolute bottom-20 left-32 text-center z-20 max-md:bottom-12 max-md:left-8 max-md:right-4 max-md:text-left">
<p class="text-gray-700 mb-2">Made with ♡ by teenagers, for teenagers at Hack Club</p>
<div class="flex space-x-4 max-md:flex-col max-md:space-x-0 max-md:space-y-2">
<a href="https://hackclub.com" class="underline text-gray-700 hover:text-gray-900 transition-colors ">Hack Club</a>
<span class="text-gray-700 max-md:hidden"></span>
<a href="https://hackclub.com/slack" class="underline text-gray-700 hover:text-gray-900 transition-colors ">Slack</a>
<span class="text-gray-700 max-md:hidden"></span>
<a href="https://hackclub.com/clubs" class="underline text-gray-700 hover:text-gray-900 transition-colors ">Clubs</a>
<span class="text-gray-700 max-md:hidden"></span>
<a href="https://hackclub.com/hackathons" class="underline text-gray-700 hover:text-gray-900 transition-colors ">Hackathons</a>
</div>
</div>
<div class="max-sm:hidden absolute bottom-2 right-16 h-2/3 aspect-square bg-[url('brushstroking.png')] bg-repeat z-10 bg-size-[100vw_100vh] mix-blend-overlay" style="mask-image: url(/thought-bubbles.png); mask-size: contain; mask-repeat: no-repeat; -webkit-mask-image: url(/thought-bubbles.png); -webkit-mask-size: contain; -webkit-mask-repeat: no-repeat;"></div>
<div class="max-sm:hidden absolute bottom-2 right-16 h-2/3 aspect-square bg-[#e99cce]" style="mask-image: url(/thought-bubbles.png); mask-size: contain; mask-repeat: no-repeat; -webkit-mask-image: url(/thought-bubbles.png); -webkit-mask-size: contain; -webkit-mask-repeat: no-repeat;"></div>
</div>
<Footer />
<!-- Video Popup Modal -->
{#if showVideoPopup}

View file

@ -0,0 +1,99 @@
import { json } from '@sveltejs/kit';
export async function POST() {
try {
// Create a varied, creative prompt using multiple techniques
const randomElements = getRandomPromptElements();
const prompt = `Create a simple game idea for a beginner game jam.
GAME TYPE: ${randomElements.gameType}
THEME: ${randomElements.theme}
SETTING: ${randomElements.setting}
Turn these three elements into a single sentence game idea. Start with "A [game type] where you..." or "An [game type] where you..." and keep it simple and clear. Use normal words, no fancy language.`;
const response = await fetch('https://ai.hackclub.com/chat/completions', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
messages: [
{
role: 'system',
content: 'You are a practical game designer. Respond with ONLY a single sentence game idea. Use simple, plain language. One basic mechanic only. No fancy words, no poetry, no flowery descriptions.'
},
{ role: 'user', content: prompt }
]
})
});
if (!response.ok) {
throw new Error(`AI API request failed: ${response.status}`);
}
const data = await response.json();
let idea = data.choices[0]?.message?.content?.trim();
if (!idea) {
throw new Error('No idea generated from AI response');
}
// Clean up the response - remove any thinking tags or extra formatting
idea = idea.replace(/<think>[\s\S]*?<\/think>/g, '').trim();
idea = idea.replace(/^["']/g, '').replace(/["']$/g, '').trim();
return json({ idea });
} catch (error) {
console.error('Error generating game idea:', error);
return json({ error: 'Failed to generate game idea' }, { status: 500 });
}
}
function getRandomPromptElements() {
const gameTypes = [
"puzzle game", "arcade game", "platformer", "racing game", "rhythm game",
"physics game", "strategy game", "tower defense", "stealth game", "adventure game",
"simulation", "management game", "survival game", "exploration game", "maze game",
"matching game", "building game", "collecting game", "jumping game", "flying game",
"shooting game", "defense game", "escape game", "rescue game", "cooking game",
"drawing game", "music game", "word game", "memory game", "reaction game",
"sorting game", "stacking game", "rolling game", "sliding game", "rotating game",
"growing game", "shrinking game", "merging game", "splitting game", "timing game"
];
const themes = [
"animals", "space", "underwater", "robots", "magic", "pirates", "ninjas", "knights",
"zombies", "aliens", "dinosaurs", "dragons", "ghosts", "monsters", "superheroes", "wizards",
"cats", "dogs", "birds", "fish", "insects", "plants", "flowers", "trees",
"food", "candy", "pizza", "ice cream", "vegetables", "fruits", "cooking", "baking",
"music", "dancing", "art", "painting", "drawing", "colors", "shapes", "patterns",
"weather", "seasons", "rain", "snow", "sun", "clouds", "storms", "rainbows",
"vehicles", "cars", "trains", "planes", "boats", "rockets", "bicycles", "trucks",
"sports", "soccer", "basketball", "tennis", "golf", "baseball", "swimming", "running",
"school", "library", "playground", "home", "garden", "park", "beach", "mountain",
"friendship", "family", "helping", "sharing", "learning", "growing", "exploring", "discovering"
];
const settings = [
"forest", "castle", "spaceship", "underwater city", "desert", "mountain", "cave", "laboratory",
"school", "playground", "park", "beach", "farm", "circus", "carnival", "zoo",
"kitchen", "bakery", "restaurant", "garden", "greenhouse", "library", "museum", "theater",
"factory", "workshop", "garage", "basement", "attic", "treehouse", "island", "village",
"city", "town", "neighborhood", "street", "alley", "rooftop", "bridge", "tower",
"maze", "dungeon", "temple", "pyramid", "ruins", "volcano", "glacier", "jungle",
"swamp", "meadow", "valley", "hill", "cliff", "river", "lake", "pond",
"space station", "alien planet", "moon base", "asteroid", "comet", "black hole", "nebula", "galaxy",
"pirate ship", "treasure island", "haunted house", "magic realm", "fairy tale land", "dreamworld", "candy land", "toy store"
];
const randomChoice = (array: any[]) => array[Math.floor(Math.random() * array.length)];
return {
gameType: randomChoice(gameTypes),
theme: randomChoice(themes),
setting: randomChoice(settings)
};
}

View file

@ -0,0 +1,50 @@
import Airtable from 'airtable';
import { json } from '@sveltejs/kit';
import { AIRTABLE_API_KEY, AIRTABLE_BASE_ID, AIRTABLE_RSVPS_TABLE } from '$env/static/private';
if (!AIRTABLE_API_KEY || !AIRTABLE_BASE_ID) {
console.warn('Airtable environment variables not configured, email saving will be skipped');
}
const base = AIRTABLE_API_KEY && AIRTABLE_BASE_ID
? new Airtable({
apiKey: AIRTABLE_API_KEY
}).base(AIRTABLE_BASE_ID)
: null;
export async function POST({ request, getClientAddress }) {
try {
const { email, city } = await request.json();
if (!email) {
return json({ error: 'Email is required' }, { status: 400 });
}
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(email)) {
return json({ error: 'Invalid email format' }, { status: 400 });
}
// get IP address
const ip = request.headers.get('x-forwarded-for')?.split(',')[0] || getClientAddress();
if (base) {
await base(AIRTABLE_RSVPS_TABLE || 'participant_rsvps').create([
{
fields: {
email,
ip,
city,
}
}
]);
}
return new Response(null, { status: 200 });
} catch (error) {
console.error('Error saving email to Airtable:', error);
return new Response(null, { status: 418 });
}
}

View file

@ -26,11 +26,10 @@ export async function POST({ request, getClientAddress }) {
}
// get IP address
const ip = getClientAddress();
const ip = request.headers.get('x-forwarded-for')?.split(',')[0] || getClientAddress();
let recordId = null;
if (base) {
const record = await base(AIRTABLE_EMAILS_TABLE || 'email_addresses').create([
await base(AIRTABLE_EMAILS_TABLE || 'email_addresses').create([
{
fields: {
email,
@ -38,7 +37,6 @@ export async function POST({ request, getClientAddress }) {
}
}
]);
recordId = record[0].id;
}
return new Response(null, { status: 200 });

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

1609
src/routes/dc/+page.svelte Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,42 @@
import { GEOCODER_API_KEY } from '$env/static/private';
export const prerender = false;
/** @type {import('./$types').PageServerLoad} */
export async function load({ url }) {
const location = url.searchParams.get('location');
if (!GEOCODER_API_KEY || !location) {
return {
location: null,
geocoded: null
};
}
try {
// Geocode the provided location
const geocodeUrl = `https://geocoder.hackclub.com/v1/geocode?address=${encodeURIComponent(location)}&key=${GEOCODER_API_KEY}`;
const geocodeResponse = await fetch(geocodeUrl);
if (geocodeResponse.ok) {
const geocodeData = await geocodeResponse.json();
return {
location,
geocoded: {
lat: geocodeData.lat,
lng: geocodeData.lng,
address: location
}
};
} else {
console.error(`Failed to geocode ${location}: ${geocodeResponse.status}`);
}
} catch (error) {
console.error(`Failed to geocode ${location}:`, error);
}
return {
location,
geocoded: null
};
}

View file

@ -0,0 +1,396 @@
<script lang="ts">
import { onMount } from 'svelte';
import { browser } from '$app/environment';
/** @type {import('./$types').PageData} */
export let data;
let mapContainer: HTMLElement;
let map: any;
onMount(() => {
if (browser) {
// Mouse trail setup
let mouseTrailPoints: Array<{ x: number; y: number }> = [];
const maxTrailLength = 15;
let animationId: number;
// Rainbow trail configuration - adjust these to tune the effect
const colorChangeSpeed = 400; // Lower = faster color changes (was 800)
const trailColorSpan = 25; // Degrees of color variation across trail length (was 15)
const trailThicknessStart = 3; // Path thickness at tail (oldest points)
const trailThicknessEnd = 8; // Path thickness at mouse (newest points)
function getHueFromIndex(index: number): number {
return (index * 24) % 360; // Rainbow cycle through hues
}
function updateMouseTrail(e: MouseEvent) {
// Get fresh references to all SVG containers
const svgs = [
document.querySelector('#trail-svg-blur'),
// document.querySelector('#trail-svg-main')
];
if (svgs.find(svg => !svg)) return;
const x = e.clientX;
const y = e.clientY;
mouseTrailPoints.push({ x, y });
// Keep trail at max length
if (mouseTrailPoints.length > maxTrailLength) {
mouseTrailPoints.shift();
}
// Clear existing paths and gradients
if (mouseTrailPoints.length > 1) {
svgs.forEach((svg: any) => {
// Clear old elements
const oldPaths = svg.querySelectorAll('.trail-segment');
const oldGradients = svg.querySelectorAll('.segment-gradient');
oldPaths.forEach((path: any) => path.remove());
oldGradients.forEach((grad: any) => grad.remove());
// Ensure defs exists
let defs = svg.querySelector('defs');
if (!defs) {
defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');
svg.appendChild(defs);
}
});
// Create individual path segments with gradient colors
for (let i = 0; i < mouseTrailPoints.length - 1; i++) {
const progress = i / (mouseTrailPoints.length - 1);
const nextProgress = (i + 1) / (mouseTrailPoints.length - 1);
// Base color changes slowly over time, with subtle variations along trail
const baseHue = getHueFromIndex(Date.now() / colorChangeSpeed);
const hue1 = baseHue - (progress * trailColorSpan);
const hue2 = baseHue - (nextProgress * trailColorSpan);
// Create paths in all SVGs
svgs.forEach((svg: any, svgIndex: number) => {
if (!svg) return;
const defs = svg.querySelector('defs');
if (!defs) return;
// Create gradient for this segment (unique ID per SVG)
const gradient = document.createElementNS('http://www.w3.org/2000/svg', 'linearGradient');
gradient.classList.add('segment-gradient');
gradient.setAttribute('id', `segment-gradient-${svgIndex}-${i}`);
gradient.setAttribute('x1', '0%');
gradient.setAttribute('y1', '0%');
gradient.setAttribute('x2', '100%');
gradient.setAttribute('y2', '0%');
const stop1 = document.createElementNS('http://www.w3.org/2000/svg', 'stop');
stop1.setAttribute('offset', '0%');
stop1.setAttribute('stop-color', `hsl(${hue1}, 70%, 60%)`);
const stop2 = document.createElementNS('http://www.w3.org/2000/svg', 'stop');
stop2.setAttribute('offset', '100%');
stop2.setAttribute('stop-color', `hsl(${hue2}, 70%, 60%)`);
gradient.appendChild(stop1);
gradient.appendChild(stop2);
defs.appendChild(gradient);
// Create path with gradient stroke - bigger at mouse (newest), smaller at tail (oldest)
const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
path.classList.add('trail-segment');
path.setAttribute('d', `M${mouseTrailPoints[i].x},${mouseTrailPoints[i].y} L${mouseTrailPoints[i + 1].x},${mouseTrailPoints[i + 1].y}`);
path.setAttribute('stroke', `url(#segment-gradient-${svgIndex}-${i})`);
path.setAttribute('stroke-width', `${trailThicknessStart + (trailThicknessEnd - trailThicknessStart) * progress}`);
path.setAttribute('stroke-linecap', 'round');
path.setAttribute('stroke-linejoin', 'round');
path.setAttribute('fill', 'none');
svg.appendChild(path);
});
}
}
}
function clearMouseTrail() {
mouseTrailPoints = [];
const svgs = [
document.querySelector('#trail-svg-blur'),
// document.querySelector('#trail-svg-main')
];
svgs.forEach((svg: any) => {
if (svg) {
const oldPaths = svg.querySelectorAll('.trail-segment');
oldPaths.forEach((path: any) => path.remove());
}
});
}
// Trail fade animation - only remove points every few frames
let frameCount = 0;
function animateTrail() {
frameCount++;
// Only remove points every 3 frames to slow down the fade
if (frameCount % 3 === 0 && mouseTrailPoints.length > 0) {
mouseTrailPoints.shift();
// Redraw trail segments with updated colors
const svgs = [
document.querySelector('#trail-svg-blur'),
// document.querySelector('#trail-svg-main')
];
if (mouseTrailPoints.length > 1 && !svgs.find(svg => !svg)) {
svgs.forEach((svg: any) => {
// Clear old elements
const oldPaths = svg.querySelectorAll('.trail-segment');
const oldGradients = svg.querySelectorAll('.segment-gradient');
oldPaths.forEach((path: any) => path.remove());
oldGradients.forEach((grad: any) => grad.remove());
// Ensure defs exists
let defs = svg.querySelector('defs');
if (!defs) {
defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');
svg.appendChild(defs);
}
});
// Redraw segments with gradients
for (let i = 0; i < mouseTrailPoints.length - 1; i++) {
const progress = i / (mouseTrailPoints.length - 1);
const nextProgress = (i + 1) / (mouseTrailPoints.length - 1);
// Base color changes slowly over time, with subtle variations along trail
const baseHue = getHueFromIndex(Date.now() / colorChangeSpeed);
const hue1 = baseHue - (progress * trailColorSpan);
const hue2 = baseHue - (nextProgress * trailColorSpan);
// Create paths in all SVGs
svgs.forEach((svg: any, svgIndex: number) => {
if (!svg) return;
const defs = svg.querySelector('defs');
if (!defs) return;
// Create gradient
const gradient = document.createElementNS('http://www.w3.org/2000/svg', 'linearGradient');
gradient.classList.add('segment-gradient');
gradient.setAttribute('id', `segment-gradient-${svgIndex}-${i}`);
gradient.setAttribute('x1', '0%');
gradient.setAttribute('y1', '0%');
gradient.setAttribute('x2', '100%');
gradient.setAttribute('y2', '0%');
const stop1 = document.createElementNS('http://www.w3.org/2000/svg', 'stop');
stop1.setAttribute('offset', '0%');
stop1.setAttribute('stop-color', `hsl(${hue1}, 70%, 60%)`);
const stop2 = document.createElementNS('http://www.w3.org/2000/svg', 'stop');
stop2.setAttribute('offset', '100%');
stop2.setAttribute('stop-color', `hsl(${hue2}, 70%, 60%)`);
gradient.appendChild(stop1);
gradient.appendChild(stop2);
defs.appendChild(gradient);
// Create path - bigger at mouse (newest), smaller at tail (oldest)
const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
path.classList.add('trail-segment');
path.setAttribute('d', `M${mouseTrailPoints[i].x},${mouseTrailPoints[i].y} L${mouseTrailPoints[i + 1].x},${mouseTrailPoints[i + 1].y}`);
path.setAttribute('stroke', `url(#segment-gradient-${svgIndex}-${i})`);
path.setAttribute('stroke-width', `${trailThicknessStart + (trailThicknessEnd - trailThicknessStart) * progress}`);
path.setAttribute('stroke-linecap', 'round');
path.setAttribute('stroke-linejoin', 'round');
path.setAttribute('fill', 'none');
svg.appendChild(path);
});
}
}
}
animationId = requestAnimationFrame(animateTrail);
}
// Wait for DOM and get elements
setTimeout(() => {
const svgs = [
document.querySelector('#trail-svg-blur'),
// document.querySelector('#trail-svg-main')
];
if (!svgs.find(svg => !svg)) {
// Event listeners
document.addEventListener('mousemove', updateMouseTrail);
document.addEventListener('mouseleave', clearMouseTrail);
// Start animation loop
animateTrail();
}
}, 100);
// Initialize Leaflet
import('leaflet').then((L) => {
// Load CSS
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.css';
document.head.appendChild(link);
// Initialize map
map = L.map(mapContainer, {
minZoom: 2,
maxZoom: 18
}).setView([20, 0], 2);
// Add tile layer with custom styling
L.tileLayer('https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png', {
attribution: '© OpenStreetMap contributors © CARTO',
detectRetina: true
}).addTo(map);
// Create custom icon using map-flag.png
const flagIcon = L.icon({
iconUrl: '/map-flag.png',
iconSize: [32, 32],
iconAnchor: [16, 32],
popupAnchor: [0, -32]
});
// Add marker for the specified location if geocoded successfully
if (data.geocoded && data.geocoded.lat && data.geocoded.lng) {
// Set the map view to the geocoded location with higher zoom
map.setView([data.geocoded.lat, data.geocoded.lng], 13);
const marker = L.marker([data.geocoded.lat, data.geocoded.lng], { icon: flagIcon })
.addTo(map);
// Create popup that shows the address
const popup = L.popup({
closeButton: false,
className: 'custom-popup'
}).setContent(data.geocoded.address);
marker.bindPopup(popup);
// Show popup on hover, hide on mouseout
marker.on('mouseover', () => {
marker.openPopup();
});
marker.on('mouseout', () => {
marker.closePopup();
});
}
});
// Cleanup function
return () => {
document.removeEventListener('mousemove', updateMouseTrail);
document.removeEventListener('mouseleave', clearMouseTrail);
if (animationId) {
cancelAnimationFrame(animationId);
}
};
}
});
</script>
<svelte:head>
<title>Event Location Map</title>
</svelte:head>
<!-- Mouse trailer SVGs -->
<!-- Background blurred layer -->
<!-- svelte-ignore component_name_lowercase -->
<svg id="trail-svg-blur" class="fixed top-0 left-0 w-full h-full pointer-events-none z-[9998]" style="filter: blur(10px); opacity: 0.75">
<!-- Individual path segments will be added here dynamically -->
</svg>
<!-- Foreground sharp layer -->
<!-- svelte-ignore component_name_lowercase -->
<svg id="trail-svg-main" class="fixed top-0 left-0 w-full h-full pointer-events-none z-[9999]" style="filter: blur(3px) saturate(0) brightness(1000); opacity: 0.25">
<!-- Individual path segments will be added here dynamically -->
</svg>
<div bind:this={mapContainer} class="w-full h-screen"></div>
<style>
:global(body) {
margin: 0;
padding: 0;
}
/* Map container styling */
:global(.leaflet-container) {
background: linear-gradient(135deg, #CCF4FD 0%, #B8D9F8 100%) !important;
border-radius: 16px !important;
overflow: hidden !important;
}
/* Map controls styling */
:global(.leaflet-control-zoom a) {
background: #44DBC8 !important;
border: 2px solid #3CC2AF !important;
color: white !important;
border-radius: 8px !important;
box-shadow: 0 4px 12px rgba(68, 219, 200, 0.3) !important;
transition: all 0.2s ease-in-out !important;
}
:global(.leaflet-control-zoom a:hover) {
background: #3CC2AF !important;
transform: translateY(-1px) !important;
box-shadow: 0 6px 16px rgba(68, 219, 200, 0.4) !important;
}
:global(.leaflet-control-attribution) {
background: rgba(252, 247, 196, 0.9) !important;
border: 1px solid #D3B180 !important;
border-radius: 8px !important;
color: #78531D !important;
font-family: 'Atkinson Hyperlegible', system-ui, sans-serif !important;
backdrop-filter: blur(8px) !important;
display: none !important;
}
:global(.leaflet-control-attribution a) {
color: #4477A3 !important;
text-decoration: none !important;
}
:global(.leaflet-control-attribution a:hover) {
color: #44DBC8 !important;
}
/* Custom popup styling */
:global(.custom-popup .leaflet-popup-content-wrapper) {
background: #FFFBDF !important;
border: 1px solid #D3B180 !important;
border-radius: 8px !important;
box-shadow: 0 4px 8px rgba(211, 177, 128, 0.15) !important;
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif !important;
}
:global(.custom-popup .leaflet-popup-content) {
margin: 8px 12px !important;
color: #78531D !important;
font-size: 14px !important;
font-weight: 500 !important;
line-height: 1.2 !important;
}
:global(.custom-popup .leaflet-popup-tip) {
background: #FFFBDF !important;
border: 1px solid #D3B180 !important;
border-top: none !important;
border-right: none !important;
}
/* Tile layer filter for softer appearance */
:global(.leaflet-tile-pane) {
filter: hue-rotate(5deg) saturate(0.8) brightness(1.1) !important;
}
</style>

View file

@ -1212,7 +1212,7 @@ Mumbai`.split("\n")
<!-- Map container with cloudy edges -->
<div class="relative w-full h-156 overflow-hidden bg-transparent">
<iframe
src={eventAddress ? "/event-map?location={encodeURIComponent(eventAddress)}" : "/map"}
src={eventAddress ? "/event-map?location=" + encodeURIComponent(eventAddress) : "/map"}
class="w-full h-full border-0 bg-[#acd4e0]"
style="
mask-image:

View file

@ -80,9 +80,9 @@ The PoC will get a link to your Daydream event's HCB org, and an onboarding vide
### **4\) Get a custom email**
Want a [city@daydream.hackclub.com](mailto:city@daydream.hackclub.com) email? Fill out this form\! This is a shared account that the team can use to send out communications to attendees (especially for quest
Want a [city@daydream.hackclub.com](mailto:city@daydream.hackclub.com) email? This will be coming to event PoCs soonTM! This is a shared Google Workspace account that the team can use to send out mass, personalized communications to attendees, and should be the contact email listed on your website so people can ask you questions.
(also, it's kind of awesome)
(it's kind of awesome. Google Workspace ftw)
<CloudImage src="/guide/email.png" />
@ -211,4 +211,4 @@ And we're here to give it to you. Reserve a 10 minute call with Meghana, RenRan,
You're not just building a hackathon. You're building a space where someone might code their very first game. Meet their best friend. Find their love ♥️ (for tech).
That's our daydream. And we're so, so excited to see what you'll build.
That's our daydream. And we're so, so excited to see what you'll build.

View file

@ -18,7 +18,7 @@ Use the branding guide for:
HQ will be sending each Daydream event ✨amazing✨ t-shirts, postcards, and stickers.
But… Beyond that, merch is all on you. Find cheap places to get printed badges and lanyards (if you raise enough money, maybe you can make a simple PCB badge). [Order Hack Club posters](https://forms.hackclub.com/t/uzgyhTqvsFus) and put them up around your venue.
But… Beyond that, merch is all on you. Find cheap places to get printed badges and lanyards (if you raise enough money, maybe you can make a simple PCB badge). You can also use the $500 Jukebox perk available on your HCB account to buy [posters, stickers, and more merch](https://jukeboxprint.com).
**Note: ALWAYS prioritize participants' merch above organizers'. DO NOT blow $500 on cool organizers' merch when you could have gotten merch for participants.**
@ -60,6 +60,6 @@ More fancy ones:
* Hoodies
* Something custom\!
Note: HCB currently offers a $500 grant for jukebox ([jukebox.com](http://jukebox.com)) if your account has 10+ organizers/people who follows it.
Note: HCB currently offers a $500 grant for jukebox ([jukeboxprint.com](http://https://www.jukeboxprint.com/)) if your account has 10+ organizers/people who follows it.
Jukebox is a custom sticker/postcard/prints shop\!
Jukebox is a custom sticker/postcard/prints shop\!

File diff suppressed because one or more lines are too long

View file

@ -124,4 +124,4 @@ RenRan
## Extra: Tips & Advice
Make the highest tier more than half of your budget. **The lowest tier should also be a significant contribution.** For example: if your budget is $8k, make $5k your highest tier and $1.5k your lowest tier.
Make the highest tier more than half of your budget. **The lowest tier should also be a significant contribution.** For example: if your budget is $8k, make $5k your highest tier and $1.5k your lowest tier.

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -11,31 +11,37 @@ export async function load() {
}
try {
// Fetch approved events from Airtable
const airtableUrl = `https://api.airtable.com/v0/${AIRTABLE_BASE_ID}/events?filterByFormula={triage_status}="Approved"`;
const airtableResponse = await fetch(airtableUrl, {
headers: {
'Authorization': `Bearer ${AIRTABLE_API_KEY}`
// Fetch all approved events from Airtable with pagination
const events = [];
let offset = null;
do {
const airtableUrl = `https://api.airtable.com/v0/${AIRTABLE_BASE_ID}/events?filterByFormula={triage_status}="Approved"${offset ? `&offset=${offset}` : ''}`;
const airtableResponse = await fetch(airtableUrl, {
headers: {
'Authorization': `Bearer ${AIRTABLE_API_KEY}`
}
});
if (!airtableResponse.ok) {
throw new Error(`Airtable API error: ${airtableResponse.status}`);
}
});
if (!airtableResponse.ok) {
throw new Error(`Airtable API error: ${airtableResponse.status}`);
}
const airtableData = await airtableResponse.json();
const events = airtableData.records;
const airtableData = await airtableResponse.json();
events.push(...airtableData.records);
offset = airtableData.offset;
} while (offset);
// Geocode each event location
const locations = [];
for (const event of events) {
const { location, state, country, event_name } = event.fields;
const { location, state, country, event_name, address_override } = event.fields;
if (!location || !event_name) continue;
// Build address string
const addressParts = [location, state, country].filter(Boolean);
const address = addressParts.join(', ');
// Use address_override if set, otherwise build address string
const address = address_override || [location, state, country].filter(Boolean).join(', ');
console.log(`${event_name}: ${address}`)
try {
const geocodeUrl = `https://geocoder.hackclub.com/v1/geocode?address=${encodeURIComponent(address)}&key=${GEOCODER_API_KEY}`;

1605
src/routes/novi/+page.svelte Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

BIN
static/banner-city.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

BIN
static/billboard-bars.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 628 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 566 B

BIN
static/billboard-lights.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

BIN
static/billboard-pillar.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 934 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

After

Width:  |  Height:  |  Size: 62 KiB

BIN
static/daydreamkl.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

BIN
static/dice/dice-1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 B

BIN
static/dice/dice-2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 195 B

BIN
static/dice/dice-3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 B

BIN
static/dice/dice-4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 191 B

BIN
static/dice/dice-5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 B

BIN
static/dice/dice-6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 B

BIN
static/dream-pixel.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

BIN
static/example/logo1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

BIN
static/example/logo2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

BIN
static/example/logo3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
static/example/logo4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
static/example/logo5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

BIN
static/example/logo6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
static/example/logo7.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

View file

@ -5,7 +5,7 @@
/* Define the Daydream fonts */
@font-face {
font-family: 'Expensify New Kansas';
font-family: 'Daydream New';
font-display: swap;
src: url('https://daydream.hackclub.com/fonts/serif.woff') format('woff');
font-weight: 400;
@ -13,7 +13,7 @@
}
@font-face {
font-family: 'Expensify New Kansas';
font-family: 'Daydream New';
font-display: swap;
src: url('https://daydream.hackclub.com/fonts/serif-italic.woff') format('woff');
font-weight: 400;
@ -22,7 +22,7 @@
/* Apply serif font to all headers */
h1, h2, h3, h4, h5, h6 {
font-family: 'Expensify New Kansas', ui-serif, serif !important;
font-family: 'Daydream New', ui-serif, serif !important;
color: #833710;
font-style: italic;
}
@ -40,7 +40,7 @@ h1, h2, h3, h4, h5, h6 {
/* Button styling - matching the "get free stickers" button */
[data-cy="button-component"] {
display: inline-block;
display: inline-flex;
padding: 8px 16px;
background-color: #E472AB;
border: none;
@ -61,6 +61,7 @@ h1, h2, h3, h4, h5, h6 {
[data-cy="button-component"]:hover {
box-shadow: 0 2px 0 0 #A65A80;
transform: translateY(-2px);
background-color: #E472AB !important;
}
[data-cy="button-component"]:active {
@ -136,8 +137,27 @@ a {
color: #548abb;
}
/* the "- Or -" divider */
.text-sm > span.px-2 {
background-color: #FFFBDF !important;
}
/* make the 'Thank You' text use the header font */
.fillout-field-thank-you > div > div > div:not(.mt-\[3px\]) p {
font-family: 'Expensify New Kansas', ui-serif, serif !important;
font-family: 'Daydream New', ui-serif, serif !important;
font-style: italic;
}
/* make the checkbox text clickable */
div:has(> div > [role="checkbox"]) p {
cursor: pointer !important;
}
/* 'sign in with google' button */
[data-cy="button-component"] .text-blue-500 {
color: white !important;
}
.fillout-field-send-response > div {
background: #fffef2;
}

BIN
static/gamejam-1-alt.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
static/macintosh-frame.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 606 KiB

BIN
static/macintosh.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 737 KiB

BIN
static/og-image.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 632 KiB

116
static/penang/daydream.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 1.9 MiB