Merge branch 'hackclub:main' into main

This commit is contained in:
Chee Yong 2025-08-05 19:25:01 +08:00 committed by GitHub
commit f8966d58fb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
46 changed files with 1590 additions and 205 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

@ -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=="],
@ -231,10 +234,6 @@
"@types/triple-beam": ["@types/triple-beam@1.3.5", "", {}, "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw=="],
"@types/unist": ["@types/unist@2.0.11", "", {}, "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="],
"@ungap/structured-clone": ["@ungap/structured-clone@1.3.0", "", {}, "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="],
"abort-controller": ["abort-controller@3.0.0", "", { "dependencies": { "event-target-shim": "^5.0.0" } }, "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg=="],
"abortcontroller-polyfill": ["abortcontroller-polyfill@1.7.8", "", {}, "sha512-9f1iZ2uWh92VcrU9Y8x+LdM4DLj75VE0MJB8zuF1iUnroEptStw+DQ8EQPMUdfe5k+PkB1uUfDQfWbhstH8LrQ=="],
@ -385,20 +384,6 @@
"magic-string": ["magic-string@0.30.17", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" } }, "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA=="],
"mdast-util-to-hast": ["mdast-util-to-hast@13.2.0", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "@ungap/structured-clone": "^1.0.0", "devlop": "^1.0.0", "micromark-util-sanitize-uri": "^2.0.0", "trim-lines": "^3.0.0", "unist-util-position": "^5.0.0", "unist-util-visit": "^5.0.0", "vfile": "^6.0.0" } }, "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA=="],
"mdsvex": ["mdsvex@0.12.6", "", { "dependencies": { "@types/mdast": "^4.0.4", "@types/unist": "^2.0.3", "prism-svelte": "^0.4.7", "prismjs": "^1.17.1", "unist-util-visit": "^2.0.1", "vfile-message": "^2.0.4" }, "peerDependencies": { "svelte": "^3.56.0 || ^4.0.0 || ^5.0.0-next.120" } }, "sha512-pupx2gzWh3hDtm/iDW4WuCpljmyHbHi34r7ktOqpPGvyiM4MyfNgdJ3qMizXdgCErmvYC9Nn/qyjePy+4ss9Wg=="],
"micromark-util-character": ["micromark-util-character@2.1.1", "", { "dependencies": { "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q=="],
"micromark-util-encode": ["micromark-util-encode@2.0.1", "", {}, "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw=="],
"micromark-util-sanitize-uri": ["micromark-util-sanitize-uri@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-encode": "^2.0.0", "micromark-util-symbol": "^2.0.0" } }, "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ=="],
"micromark-util-symbol": ["micromark-util-symbol@2.0.1", "", {}, "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q=="],
"micromark-util-types": ["micromark-util-types@2.0.2", "", {}, "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA=="],
"minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="],
"minizlib": ["minizlib@3.0.2", "", { "dependencies": { "minipass": "^7.1.2" } }, "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA=="],
@ -435,12 +420,6 @@
"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=="],
"prism-svelte": ["prism-svelte@0.4.7", "", {}, "sha512-yABh19CYbM24V7aS7TuPYRNMqthxwbvx6FF/Rw920YbyBWO3tnyPIqRMgHuSVsLmuHkkBS1Akyof463FVdkeDQ=="],
"prismjs": ["prismjs@1.30.0", "", {}, "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw=="],
"property-information": ["property-information@7.1.0", "", {}, "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ=="],
"readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="],
"readdirp": ["readdirp@4.1.2", "", {}, "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg=="],
@ -505,22 +484,8 @@
"typescript": ["typescript@5.8.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ=="],
"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=="],
"unist-util-stringify-position": ["unist-util-stringify-position@2.0.3", "", { "dependencies": { "@types/unist": "^2.0.2" } }, "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g=="],
"unist-util-visit": ["unist-util-visit@2.0.3", "", { "dependencies": { "@types/unist": "^2.0.0", "unist-util-is": "^4.0.0", "unist-util-visit-parents": "^3.0.0" } }, "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q=="],
"unist-util-visit-parents": ["unist-util-visit-parents@3.1.1", "", { "dependencies": { "@types/unist": "^2.0.0", "unist-util-is": "^4.0.0" } }, "sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg=="],
"util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="],
"vfile": ["vfile@6.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "vfile-message": "^4.0.0" } }, "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q=="],
"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=="],
"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=="],

10
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",

View file

@ -29,6 +29,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",

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;

View file

@ -0,0 +1,107 @@
<script lang="ts">
let submitted = false;
let fadeOut = false;
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 })
}).catch(error => {
console.warn('Failed to save email:', error);
});
submitted = true;
// Clear the input box while the green overlay is showing
emailInput.value = '';
setTimeout(() => {
fadeOut = true;
}, 1500);
// Reset to original position after fade out completes
setTimeout(() => {
submitted = false;
fadeOut = false;
}, 1500 + 500);
}
</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>

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

@ -581,11 +581,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">

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,49 @@
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 } = 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,
}
}
]);
}
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 });

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>

File diff suppressed because it is too large Load diff

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

@ -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 ([ukeboxprint.com](http://https://www.jukeboxprint.com/)) if your account has 10+ organizers/people who follows it.
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.

View file

@ -2,10 +2,6 @@
Your daydream needs its own website. This might be one of the only technical aspects you'll need when organizing your hackathon and day-of mentoring.
<div class="font-bold bg-red-500/20 p-4 rounded-md text-red-950">
Note: The following guide walks through how to set up the website template. The website template is still currently a work-in-progress. If you'd like to use the website template, please wait until later this week.
</div>
Now… on to how to make your site\!
First, fork the repository:

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/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

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