diff --git a/.gitignore b/.gitignore
index 5ef6a52..bd4bbf2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,6 +23,7 @@
# misc
.DS_Store
*.pem
+*.code-workspace
# debug
npm-debug.log*
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..e8a999a
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2025 Wacky Wizards
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..25d1cd6
--- /dev/null
+++ b/README.md
@@ -0,0 +1,2 @@
+# Wacky Wizards Official Website
+Source code for the Wacky Wizards website
diff --git a/next.config.ts b/next.config.ts
index 6b0a4ea..67bbbb6 100644
--- a/next.config.ts
+++ b/next.config.ts
@@ -4,7 +4,10 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
- output: 'export'
+ //output: 'export',
+ //images: {
+ // unoptimized: true,
+ //},
};
export default nextConfig;
diff --git a/package-lock.json b/package-lock.json
index 340b50d..cdd662b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -6,8 +6,9 @@
"packages": {
"": {
"name": "org-site",
- "version": "0.1.0",
+ "version": "1.0.0",
"dependencies": {
+ "framer-motion": "^12.23.24",
"gray-matter": "^4.0.3",
"next": "15.2.4",
"react": "^19.0.0",
@@ -1260,6 +1261,7 @@
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.0.12.tgz",
"integrity": "sha512-V6Ar115dBDrjbtXSrS+/Oruobc+qVbbUxDFC1RSbRqLt5SYvxxyIDrSC85RWml54g+jfNeEMZhEj7wW07ONQhA==",
"dev": true,
+ "peer": true,
"dependencies": {
"csstype": "^3.0.2"
}
@@ -1313,6 +1315,7 @@
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.28.0.tgz",
"integrity": "sha512-LPcw1yHD3ToaDEoljFEfQ9j2xShY367h7FZ1sq5NJT9I3yj4LHer1Xd1yRSOdYy9BpsrxU7R+eoDokChYM53lQ==",
"dev": true,
+ "peer": true,
"dependencies": {
"@typescript-eslint/scope-manager": "8.28.0",
"@typescript-eslint/types": "8.28.0",
@@ -1712,6 +1715,7 @@
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz",
"integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==",
"dev": true,
+ "peer": true,
"bin": {
"acorn": "bin/acorn"
},
@@ -2068,6 +2072,7 @@
}
],
"license": "MIT",
+ "peer": true,
"dependencies": {
"caniuse-lite": "^1.0.30001726",
"electron-to-chromium": "^1.5.173",
@@ -2733,6 +2738,7 @@
"resolved": "https://registry.npmjs.org/eslint/-/eslint-9.23.0.tgz",
"integrity": "sha512-jV7AbNoFPAY1EkFYpLq5bslU9NLNO8xnEeQXwErNibVryjk67wHVmddTBilc5srIttJDBrB0eMHKZBFbSIABCw==",
"dev": true,
+ "peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.12.1",
@@ -2900,6 +2906,7 @@
"resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz",
"integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==",
"dev": true,
+ "peer": true,
"dependencies": {
"@rtsao/scc": "^1.1.0",
"array-includes": "^3.1.8",
@@ -3306,6 +3313,33 @@
"url": "https://github.com/sponsors/rawify"
}
},
+ "node_modules/framer-motion": {
+ "version": "12.23.24",
+ "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.23.24.tgz",
+ "integrity": "sha512-HMi5HRoRCTou+3fb3h9oTLyJGBxHfW+HnNE25tAXOvVx/IvwMHK0cx7IR4a2ZU6sh3IX1Z+4ts32PcYBOqka8w==",
+ "license": "MIT",
+ "dependencies": {
+ "motion-dom": "^12.23.23",
+ "motion-utils": "^12.23.6",
+ "tslib": "^2.4.0"
+ },
+ "peerDependencies": {
+ "@emotion/is-prop-valid": "*",
+ "react": "^18.0.0 || ^19.0.0",
+ "react-dom": "^18.0.0 || ^19.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@emotion/is-prop-valid": {
+ "optional": true
+ },
+ "react": {
+ "optional": true
+ },
+ "react-dom": {
+ "optional": true
+ }
+ }
+ },
"node_modules/function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
@@ -5181,6 +5215,21 @@
"url": "https://github.com/sponsors/isaacs"
}
},
+ "node_modules/motion-dom": {
+ "version": "12.23.23",
+ "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.23.23.tgz",
+ "integrity": "sha512-n5yolOs0TQQBRUFImrRfs/+6X4p3Q4n1dUEqt/H58Vx7OW6RF+foWEgmTVDhIWJIMXOuNNL0apKH2S16en9eiA==",
+ "license": "MIT",
+ "dependencies": {
+ "motion-utils": "^12.23.6"
+ }
+ },
+ "node_modules/motion-utils": {
+ "version": "12.23.6",
+ "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.23.6.tgz",
+ "integrity": "sha512-eAWoPgr4eFEOFfg2WjIsMoqJTW6Z8MTUCgn/GZ3VRpClWBdnbjryiA3ZSNLyxCTmCQx4RmYX6jX1iWHbenUPNQ==",
+ "license": "MIT"
+ },
"node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
@@ -5567,6 +5616,7 @@
}
],
"license": "MIT",
+ "peer": true,
"dependencies": {
"nanoid": "^3.3.11",
"picocolors": "^1.1.1",
@@ -5660,6 +5710,7 @@
"version": "19.1.0",
"resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz",
"integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==",
+ "peer": true,
"engines": {
"node": ">=0.10.0"
}
@@ -5668,6 +5719,7 @@
"version": "19.1.0",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz",
"integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==",
+ "peer": true,
"dependencies": {
"scheduler": "^0.26.0"
},
@@ -6390,7 +6442,8 @@
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.12.tgz",
"integrity": "sha512-DzFtxOi+7NsFf7DBtI3BJsynR+0Yp6etH+nRPTbpWnS2pZBaSksv/JGctNwSWzbFjp0vxSqknaUylseZqMDGrA==",
"dev": true,
- "license": "MIT"
+ "license": "MIT",
+ "peer": true
},
"node_modules/tapable": {
"version": "2.2.2",
@@ -6455,6 +6508,7 @@
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
"integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
"dev": true,
+ "peer": true,
"engines": {
"node": ">=12"
},
@@ -6614,6 +6668,7 @@
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz",
"integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==",
"dev": true,
+ "peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
diff --git a/package.json b/package.json
index 3ab3347..35fc6f4 100644
--- a/package.json
+++ b/package.json
@@ -12,6 +12,7 @@
"lint": "next lint"
},
"dependencies": {
+ "framer-motion": "^12.23.24",
"gray-matter": "^4.0.3",
"next": "15.2.4",
"react": "^19.0.0",
diff --git a/public/observation-1.png b/public/games/observation/observation-1.png
similarity index 100%
rename from public/observation-1.png
rename to public/games/observation/observation-1.png
diff --git a/public/observation-2.jpg b/public/games/observation/observation-2.jpg
similarity index 100%
rename from public/observation-2.jpg
rename to public/games/observation/observation-2.jpg
diff --git a/public/games/observation/observation-3.jpg b/public/games/observation/observation-3.jpg
new file mode 100644
index 0000000..e7af150
Binary files /dev/null and b/public/games/observation/observation-3.jpg differ
diff --git a/public/games/observation/observation-4.jpg b/public/games/observation/observation-4.jpg
new file mode 100644
index 0000000..c7a5c1e
Binary files /dev/null and b/public/games/observation/observation-4.jpg differ
diff --git a/public/games/observation/observation-5.jpg b/public/games/observation/observation-5.jpg
new file mode 100644
index 0000000..ad8a3dc
Binary files /dev/null and b/public/games/observation/observation-5.jpg differ
diff --git a/public/games/untitledcardgame/untitledcardgame1.jpg b/public/games/untitledcardgame/untitledcardgame1.jpg
new file mode 100644
index 0000000..a74fe1a
Binary files /dev/null and b/public/games/untitledcardgame/untitledcardgame1.jpg differ
diff --git a/public/games/untitledcardgame/untitledcardgame2.jpg b/public/games/untitledcardgame/untitledcardgame2.jpg
new file mode 100644
index 0000000..89fc44c
Binary files /dev/null and b/public/games/untitledcardgame/untitledcardgame2.jpg differ
diff --git a/public/kEllieDev.jpg b/public/kellie.jpg
similarity index 100%
rename from public/kEllieDev.jpg
rename to public/kellie.jpg
diff --git a/public/ptsd.jpg b/public/ptsd.jpg
new file mode 100644
index 0000000..21c47d6
Binary files /dev/null and b/public/ptsd.jpg differ
diff --git a/src/app/apply/page.tsx b/src/app/apply/page.tsx
index b3e9d67..0f45c46 100644
--- a/src/app/apply/page.tsx
+++ b/src/app/apply/page.tsx
@@ -1,9 +1,10 @@
import React from 'react';
import type { Metadata } from 'next';
+import { organization } from '@/constants';
export const metadata: Metadata = {
title: 'Apply',
- description: 'Join our team!',
+ description: `Join the ${organization.name} team!`,
};
export default function Apply() {
diff --git a/src/app/code-of-conduct/page.tsx b/src/app/code-of-conduct/page.tsx
deleted file mode 100644
index 8a08b93..0000000
--- a/src/app/code-of-conduct/page.tsx
+++ /dev/null
@@ -1,104 +0,0 @@
-import React from 'react';
-import type { Metadata } from 'next';
-
-export const metadata: Metadata = {
- title: 'Code Of Conduct',
- description: 'Read our community code of conduct!',
-};
-
-export default function CodeOfConduct() {
- return (
-
-
-
-
Code Of Conduct
-
Last Updated: July 4th, 2025
-
-
-
-
- Our goal is to foster an inclusive, welcoming, and safe community for people of all
- backgrounds. We value diversity and are committed to ensuring everyone can participate
- free from harassment or discrimination.
-
-
- This Code of Conduct outlines expectations for behavior, outlines unacceptable conduct,
- and explains our enforcement policies. We encourage all participants to help us make
- this a positive and respectful environment.
-
-
-
1. Expected Behavior
-
-
Participate authentically and actively to support the community.
-
Be considerate and respectful in speech and actions.
-
Collaborate before engaging in conflict.
-
Avoid demeaning, discriminatory, or harassing language or behavior.
-
Be aware of your surroundings and report any concerns or violations.
-
Respect that our spaces may be shared with the public; act accordingly.
- Discriminatory jokes, language, or behavior targeting protected characteristics.
-
-
Posting sexually explicit or violent material.
-
Doxxing: sharing someone’s personal information without consent.
-
Personal insults, especially those related to identity or background.
-
Unwelcome sexual attention or advances.
-
Deliberate intimidation, stalking, or following others.
-
Disrupting events or community activities.
-
Encouraging or promoting any of the above behavior.
-
Continuing unwanted interactions after being asked to stop.
-
-
-
- 3. Consequences Of Unacceptable Behavior
-
-
- Unacceptable behavior from any community member, including sponsors and those with
- decision-making authority, will not be tolerated. Anyone asked to stop unacceptable
- behavior is expected to comply immediately. If a community member engages in
- unacceptable behavior, the staff team may take any action they deem appropriate, up to
- and including a temporary ban or permanent expulsion from the community without warning
- (and without refund in the case of a paid event or service). If you are subject to or
- witness unacceptable behavior, or have any other concerns, please notify a staff member
- as soon as possible. Additionally, staff members are available to help community members
- engage with local law enforcement or to otherwise help those experiencing unacceptable
- behavior feel safe.
-
-
-
4. Scope
-
- We expect all community participants (contributors, paid or otherwise; sponsors; and
- other guests) to abide by this Code of Conduct in all community venues--online and
- in-person--as well as in all one-on-one communications pertaining to community business.
- This code of conduct and its related procedures also applies to unacceptable behavior
- occurring outside the scope of community activities when such behavior has the potential
- to adversely affect the safety and well-being of community members.
-
-
-
- 5. License and Attribution
-
-
- The Citizen Code of Conduct is distributed by Stumptown Syndicate under a Creative
- Commons Attribution-ShareAlike license. Portions of text derived from the Django Code of
- Conduct and the Geek Feminism Anti-Harassment Policy.
-
+
+ Launch Now
+
+
+
+ );
+}
diff --git a/src/app/play/observation/page.tsx b/src/app/components/gamelauncher.tsx
similarity index 85%
rename from src/app/play/observation/page.tsx
rename to src/app/components/gamelauncher.tsx
index 8f29915..7ab5a30 100644
--- a/src/app/play/observation/page.tsx
+++ b/src/app/components/gamelauncher.tsx
@@ -1,21 +1,16 @@
'use client';
import { useState, useEffect, useRef } from 'react';
-import { usePathname } from 'next/navigation';
-import { games, Game } from '@/games';
+import { Game } from '@/games';
-export default function GameLauncher() {
- const pathname = usePathname();
+type GameLauncherProps = {
+ game: Game | undefined;
+};
+
+export default function GameLauncher({ game }: GameLauncherProps) {
const [status, setStatus] = useState<'idle' | 'launching' | 'success' | 'error'>('idle');
const fallbackTimeoutRef = useRef(null);
- // Automatically find the game based on the current route
- const game: Game | undefined = games.find(g => {
- // Extract game name from pathname (e.g., /play/observation -> observation)
- const gameNameFromPath = pathname.split('/').pop()?.toLowerCase();
- return g.title.toLowerCase() === gameNameFromPath;
- });
-
// Cleanup timeout on unmount
useEffect(() => {
return () => {
@@ -32,10 +27,11 @@ export default function GameLauncher() {
Game Not Found
- Could not find a game matching the current route: {pathname}
+ The requested game could not be found. It may have been removed or the link is
+ incorrect.