Merge pull request 'framework-version' (#1) from framework-version into main
Reviewed-on: #1
41
.gitignore
vendored
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||||
|
|
||||||
|
# dependencies
|
||||||
|
/node_modules
|
||||||
|
/.pnp
|
||||||
|
.pnp.*
|
||||||
|
.yarn/*
|
||||||
|
!.yarn/patches
|
||||||
|
!.yarn/plugins
|
||||||
|
!.yarn/releases
|
||||||
|
!.yarn/versions
|
||||||
|
|
||||||
|
# testing
|
||||||
|
/coverage
|
||||||
|
|
||||||
|
# next.js
|
||||||
|
/.next/
|
||||||
|
/out/
|
||||||
|
|
||||||
|
# production
|
||||||
|
/build
|
||||||
|
|
||||||
|
# misc
|
||||||
|
.DS_Store
|
||||||
|
*.pem
|
||||||
|
|
||||||
|
# debug
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
.pnpm-debug.log*
|
||||||
|
|
||||||
|
# env files (can opt-in for committing if needed)
|
||||||
|
.env*
|
||||||
|
|
||||||
|
# vercel
|
||||||
|
.vercel
|
||||||
|
|
||||||
|
# typescript
|
||||||
|
*.tsbuildinfo
|
||||||
|
next-env.d.ts
|
||||||
5
AGENTS.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<!-- BEGIN:nextjs-agent-rules -->
|
||||||
|
# This is NOT the Next.js you know
|
||||||
|
|
||||||
|
This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in `node_modules/next/dist/docs/` before writing any code. Heed deprecation notices.
|
||||||
|
<!-- END:nextjs-agent-rules -->
|
||||||
36
README.md
@ -0,0 +1,36 @@
|
|||||||
|
This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
First, run the development server:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run dev
|
||||||
|
# or
|
||||||
|
yarn dev
|
||||||
|
# or
|
||||||
|
pnpm dev
|
||||||
|
# or
|
||||||
|
bun dev
|
||||||
|
```
|
||||||
|
|
||||||
|
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
|
||||||
|
|
||||||
|
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
|
||||||
|
|
||||||
|
This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.
|
||||||
|
|
||||||
|
## Learn More
|
||||||
|
|
||||||
|
To learn more about Next.js, take a look at the following resources:
|
||||||
|
|
||||||
|
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
|
||||||
|
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
|
||||||
|
|
||||||
|
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
|
||||||
|
|
||||||
|
## Deploy on Vercel
|
||||||
|
|
||||||
|
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
|
||||||
|
|
||||||
|
Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
|
||||||
28
app/components/banner/banner.tsx
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import Image from "next/image";
|
||||||
|
import shrimp3D from "./shrimp.png";
|
||||||
|
|
||||||
|
export default function Banner() {
|
||||||
|
return (
|
||||||
|
<section className="w-full flex bg-tangerine-dream-shrimp items-center justify-center md:gap-[30px] gap-[0] text-3xl text-space-shrimp-blue py-3 lg:px-25 px-5">
|
||||||
|
<Image
|
||||||
|
loading="eager"
|
||||||
|
src={shrimp3D}
|
||||||
|
alt="3D modeled shrimp"
|
||||||
|
width={774}
|
||||||
|
height={605}
|
||||||
|
className="md:w-[150px] w-[75px] h-auto"
|
||||||
|
/>
|
||||||
|
<h1 className="w-fit text-nowrap md:text-5xl text-2xl">
|
||||||
|
SHRIMP SQUAD
|
||||||
|
</h1>
|
||||||
|
<Image
|
||||||
|
loading="eager"
|
||||||
|
className="transform-[scaleX(-1)] md:w-[150px] w-[75px] h-auto"
|
||||||
|
src={shrimp3D}
|
||||||
|
alt="3D modeled shrimp"
|
||||||
|
width={774}
|
||||||
|
height={605}
|
||||||
|
/>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Before Width: | Height: | Size: 355 KiB After Width: | Height: | Size: 355 KiB |
|
Before Width: | Height: | Size: 2.0 MiB After Width: | Height: | Size: 2.0 MiB |
17
app/components/hero-shrimp/hero-shrimp.tsx
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import Image from "next/image";
|
||||||
|
import heroShrimp from "./hero-shrimp.png";
|
||||||
|
|
||||||
|
export default function HeroShrimp() {
|
||||||
|
return (
|
||||||
|
<section className="w-full h-auto flex items-center justify-center w-full bg-apricot-shrimp">
|
||||||
|
<Image
|
||||||
|
loading="eager"
|
||||||
|
src={heroShrimp}
|
||||||
|
alt="photo of three gold shrimp on rocks underwater"
|
||||||
|
width={2400}
|
||||||
|
height={742}
|
||||||
|
className="w-full h-auto"
|
||||||
|
/>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
41
app/components/seafood-delights/seafood-button.tsx
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
import { useState } from "react";
|
||||||
|
import { createPortal } from "react-dom";
|
||||||
|
import { ShrimpRain } from "./shrimp-rain";
|
||||||
|
|
||||||
|
export default function SeafoodButton() {
|
||||||
|
const [showShrimpOverlay, setShowShrimpOverlay] = useState(false);
|
||||||
|
|
||||||
|
// set maxShrimp based on image size so not to overflow
|
||||||
|
const maxShrimp = 83;
|
||||||
|
const shrimpRainValues: number[] = [];
|
||||||
|
for (let i = 0; i < maxShrimp; i++) {
|
||||||
|
shrimpRainValues.push(Math.floor(Math.random() * 200));
|
||||||
|
}
|
||||||
|
|
||||||
|
function itsRainingShrimp() {
|
||||||
|
setShowShrimpOverlay(true);
|
||||||
|
// wait until after the animation plays to make the shrimp disappear 🪄
|
||||||
|
setTimeout(() => {
|
||||||
|
setShowShrimpOverlay(false);
|
||||||
|
}, 2900);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<button
|
||||||
|
className="cursor-[unset] bg-space-shrimp-blue text-tangerine-dream-shrimp p-[20px] mt-[10px] w-full rounded-xl border-transparent border-2 hover:border-ashy-shrimp shadow-lg/40"
|
||||||
|
type="button"
|
||||||
|
onClick={() => itsRainingShrimp()}
|
||||||
|
>
|
||||||
|
Dive into Seafood Delights
|
||||||
|
</button>
|
||||||
|
{showShrimpOverlay &&
|
||||||
|
createPortal(
|
||||||
|
<ShrimpRain randomValues={shrimpRainValues} />,
|
||||||
|
document.body
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//todo nice to have: cooler button hover state - dancing shrimps
|
||||||
16
app/components/seafood-delights/seafood-delights.tsx
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import SeafoodButton from "./seafood-button";
|
||||||
|
|
||||||
|
export default function SeafoodDelights() {
|
||||||
|
return (
|
||||||
|
<section className="shrimp-info w-full bg-cherry-shrimp py-[10px] lg:px-25 px-5">
|
||||||
|
<div className="text-space-shrimp-blue text-center">
|
||||||
|
<p className="font-bold">
|
||||||
|
We are Shrimp Squad and we make things.
|
||||||
|
</p>
|
||||||
|
There's no project we can't mantis punch. Shrimply take a look
|
||||||
|
at what we're known for.
|
||||||
|
</div>
|
||||||
|
<SeafoodButton />
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
32
app/components/seafood-delights/shrimp-rain.tsx
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import Image from "next/image";
|
||||||
|
import Shrimp from "./shrimp.png";
|
||||||
|
|
||||||
|
export function ShrimpRain({ randomValues }: { randomValues: number[] }) {
|
||||||
|
const maxWidthToShrimp = randomValues.length;
|
||||||
|
|
||||||
|
const shrimpImagesArray = Array.from(Array(maxWidthToShrimp).keys());
|
||||||
|
const shrimpImagesArrayElements = shrimpImagesArray.map((index) => {
|
||||||
|
const left = "left-[" + (index + 1) + "%]";
|
||||||
|
const bottom = "bottom-[" + randomValues[index] + "%]";
|
||||||
|
return (
|
||||||
|
<Image
|
||||||
|
key={index}
|
||||||
|
className="w-[15%] h-auto absolute animate-shrimply-rain"
|
||||||
|
src={Shrimp}
|
||||||
|
alt="3D modeled shrimp"
|
||||||
|
width={774}
|
||||||
|
height={605}
|
||||||
|
style={{
|
||||||
|
left: +index + 1 + "%",
|
||||||
|
bottom: randomValues[index] + "%",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="fixed w-full h-full overflow-hidden">
|
||||||
|
{shrimpImagesArrayElements}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
BIN
app/components/seafood-delights/shrimp.png
Normal file
|
After Width: | Height: | Size: 355 KiB |
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?><svg id="Discord-Logo" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 126.644 96"><defs><style>.cls-1{fill:#5865f2;}</style></defs><path id="Discord-Symbol-Blurple" class="cls-1" d="M81.15,0c-1.2376,2.1973-2.3489,4.4704-3.3591,6.794-9.5975-1.4396-19.3718-1.4396-28.9945,0-.985-2.3236-2.1216-4.5967-3.3591-6.794-9.0166,1.5407-17.8059,4.2431-26.1405,8.0568C2.779,32.5304-1.6914,56.3725.5312,79.8863c9.6732,7.1476,20.5083,12.603,32.0505,16.0884,2.6014-3.4854,4.8998-7.1981,6.8698-11.0623-3.738-1.3891-7.3497-3.1318-10.8098-5.1523.9092-.6567,1.7932-1.3386,2.6519-1.9953,20.281,9.547,43.7696,9.547,64.0758,0,.8587.7072,1.7427,1.3891,2.6519,1.9953-3.4601,2.0457-7.0718,3.7632-10.835,5.1776,1.97,3.8642,4.2683,7.5769,6.8698,11.0623,11.5419-3.4854,22.3769-8.9156,32.0509-16.0631,2.626-27.2771-4.496-50.9172-18.817-71.8548C98.9811,4.2684,90.1918,1.5659,81.1752.0505l-.0252-.0505ZM42.2802,65.4144c-6.2383,0-11.4159-5.6575-11.4159-12.6535s4.9755-12.6788,11.3907-12.6788,11.5169,5.708,11.4159,12.6788c-.101,6.9708-5.026,12.6535-11.3907,12.6535ZM84.3576,65.4144c-6.2637,0-11.3907-5.6575-11.3907-12.6535s4.9755-12.6788,11.3907-12.6788,11.4917,5.708,11.3906,12.6788c-.101,6.9708-5.026,12.6535-11.3906,12.6535Z"/></svg>
|
||||||
|
After Width: | Height: | Size: 1.2 KiB |
BIN
app/components/shrimp-feet/assets/LI-In-Bug.png
Normal file
|
After Width: | Height: | Size: 8.2 KiB |
|
Before Width: | Height: | Size: 14 MiB After Width: | Height: | Size: 14 MiB |
BIN
app/components/shrimp-feet/assets/mediawiki.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
app/components/shrimp-feet/assets/shrimp.png
Normal file
|
After Width: | Height: | Size: 355 KiB |
@ -0,0 +1,24 @@
|
|||||||
|
import Image from "next/image";
|
||||||
|
import danceShrimp from "../assets/dance-shrimp-dance.gif";
|
||||||
|
|
||||||
|
export default function DancingShrimps() {
|
||||||
|
const shrimpArray = Array.from(Array(20).keys());
|
||||||
|
const shrimpArrayElements = shrimpArray.map((index) => (
|
||||||
|
<Image
|
||||||
|
key={index}
|
||||||
|
className="w-[150px] h-auto"
|
||||||
|
src={danceShrimp}
|
||||||
|
alt="dancing 3D modeled shrimp"
|
||||||
|
width={910}
|
||||||
|
height={530}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex flex-wrap justify-between py-5 bg-apricot-shrimp">
|
||||||
|
{shrimpArrayElements}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//todo try out one line of shrimp only that change size
|
||||||
82
app/components/shrimp-feet/shrimp-feet.tsx
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
import Image from "next/image";
|
||||||
|
import shrimp3D from "./assets/shrimp.png";
|
||||||
|
import discordSymbol from "./assets/Discord-Symbol-Blurple.svg";
|
||||||
|
import linkedInSymbol from "./assets/LI-In-Bug.png";
|
||||||
|
import mediawikiSymbol from "./assets/mediawiki.png";
|
||||||
|
import DancingShrimps from "./dancing-shrimps/dancing-shrimps";
|
||||||
|
|
||||||
|
export default function ShrimpFeet() {
|
||||||
|
const currentYear = new Date().getFullYear();
|
||||||
|
return (
|
||||||
|
<section>
|
||||||
|
<div className="flex md:flex-row flex-col items-center lg:gap-10 gap-5 justify-center py-5 lg:px-25 px-4 bg-ashy-shrimp text-space-shrimp-blue">
|
||||||
|
<div className="flex items-center">
|
||||||
|
<Image
|
||||||
|
src={shrimp3D}
|
||||||
|
alt="3D modeled shrimp"
|
||||||
|
width={774}
|
||||||
|
height={605}
|
||||||
|
className="w-[150px] h-auto"
|
||||||
|
/>
|
||||||
|
<div>
|
||||||
|
<p className="font-bold text-cherry-shrimp text-xl">
|
||||||
|
Making games should be fun
|
||||||
|
</p>
|
||||||
|
<p>Shrimp Squad Inc.</p>
|
||||||
|
<a
|
||||||
|
href="mailto:contact@shrimpsquad.ca"
|
||||||
|
className="underline cursor-[unset] hover:font-bold"
|
||||||
|
>
|
||||||
|
contact@shrimpsquad.ca
|
||||||
|
</a>
|
||||||
|
<p>© {currentYear}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex gap-5 justify-center items-center">
|
||||||
|
<a
|
||||||
|
href="https://discord.gg/RVhc27mbAc"
|
||||||
|
target="_blank"
|
||||||
|
className="cursor-[unset]"
|
||||||
|
>
|
||||||
|
<Image
|
||||||
|
src={discordSymbol}
|
||||||
|
alt="discord symbol"
|
||||||
|
width={150}
|
||||||
|
height={150}
|
||||||
|
className="w-[48px] h-auto"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
href="https://dev.shrimpsquad.ca/"
|
||||||
|
target="_blank"
|
||||||
|
className="cursor-[unset]"
|
||||||
|
>
|
||||||
|
<Image
|
||||||
|
src={mediawikiSymbol}
|
||||||
|
alt="discord symbol"
|
||||||
|
width={135}
|
||||||
|
height={135}
|
||||||
|
className="w-[48px] h-auto"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
href="https://www.linkedin.com/company/shrimp-squad-inc/"
|
||||||
|
target="_blank"
|
||||||
|
className="cursor-[unset]"
|
||||||
|
>
|
||||||
|
<Image
|
||||||
|
src={linkedInSymbol}
|
||||||
|
alt="linkedIn symbol"
|
||||||
|
width={635}
|
||||||
|
height={540}
|
||||||
|
className="w-[48px] h-auto"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<DancingShrimps />
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//todo get centered shrimp image
|
||||||
6
app/components/shrimp-projects/project-content/index.tsx
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import ProjectContent from "./project-content";
|
||||||
|
import { ProjectImageProps, ProjectContentProps } from "../types";
|
||||||
|
|
||||||
|
export { ProjectContent };
|
||||||
|
|
||||||
|
export type { ProjectImageProps, ProjectContentProps };
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
import Image from "next/image";
|
||||||
|
import { ProjectContentProps } from "./";
|
||||||
|
|
||||||
|
export default function ProjectContent(projectContent: ProjectContentProps) {
|
||||||
|
return (
|
||||||
|
<section className="flex flex-col items-center w-full pt-[10px]">
|
||||||
|
<div className="flex flex-col xl:flex-row justify-between gap-[10px] *:basis-[32%] [&>div]:bg-tangerine-dream-shrimp">
|
||||||
|
<Image
|
||||||
|
src={projectContent.images.left.src}
|
||||||
|
alt=""
|
||||||
|
width={2000}
|
||||||
|
height={2000}
|
||||||
|
className="w-full xl:w-[30%] h-auto"
|
||||||
|
/>
|
||||||
|
<div className="p-[40px]">{projectContent.children}</div>
|
||||||
|
<Image
|
||||||
|
src={projectContent.images.right.src}
|
||||||
|
alt=""
|
||||||
|
width={2000}
|
||||||
|
height={2000}
|
||||||
|
className="w-full xl:w-[30%] h-auto"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<Image
|
||||||
|
src={projectContent.images.central.src}
|
||||||
|
alt=""
|
||||||
|
width={2000}
|
||||||
|
height={2000}
|
||||||
|
className="w-full h-auto xl:mt-[15px] mt-[10px]"
|
||||||
|
/>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
export default function BiotamaText() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<p className="mb-2">
|
||||||
|
<span className="font-bold">Biotama</span> is a game where
|
||||||
|
players attempt to convert wastelands into thriving ecosystems.
|
||||||
|
</p>
|
||||||
|
<p className="mb-2">
|
||||||
|
The player starts with a "Mother Tree" which acts as the core
|
||||||
|
component of the player's ecosystem. Trees grow roots that can
|
||||||
|
connect together, allowing them to communicate and send
|
||||||
|
resources between each other. Mycelial networks function
|
||||||
|
similarly for fungi.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Biotama aims to be educational as well as fun. It will feature
|
||||||
|
real-world species with tooltips showing fun facts about those
|
||||||
|
species. We are consulting with experts in biology where
|
||||||
|
necessary to ensure accuracy to the real world.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
29
app/components/shrimp-projects/project-descriptions/htp.tsx
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
export default function HackThePlanetText() {
|
||||||
|
return (
|
||||||
|
<div className="h-full grid grid-cols-1 grid-row-2">
|
||||||
|
<div>
|
||||||
|
<p className="mb-2">
|
||||||
|
A game by Shrimp Squad Studios made for the Epic MegaJam!
|
||||||
|
</p>
|
||||||
|
<p className="mb-2">
|
||||||
|
One week to make a game and this is what we made! A game
|
||||||
|
based on the movie Hackers.
|
||||||
|
</p>
|
||||||
|
<p className="mb-2">
|
||||||
|
Your goal is to hack the Gibson computer and collect the
|
||||||
|
garbage file. Which will then in turn let you
|
||||||
|
<span className="font-bold"> HACK THE PLANET!</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="mt-[16px] mb-[16px] bg-space-shrimp-blue p-[15px] size-fit rounded-md self-end">
|
||||||
|
<a
|
||||||
|
className="animate-blink border-solid border-r-[2px] border-ashy-shrimp text-[24px] text-ashy-shrimp cursor-[unset]"
|
||||||
|
href="https://megsum.itch.io/hack-the-planet"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
>> Try it out!
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
31
app/components/shrimp-projects/project-list/project-list.tsx
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import { ProjectListProps } from "../types";
|
||||||
|
|
||||||
|
export default function ProjectList({
|
||||||
|
projects,
|
||||||
|
handleProjectClick,
|
||||||
|
}: {
|
||||||
|
projects: ProjectListProps[];
|
||||||
|
handleProjectClick: any;
|
||||||
|
}) {
|
||||||
|
const projectList = projects.map((project) => (
|
||||||
|
<button
|
||||||
|
key={project.id}
|
||||||
|
className={
|
||||||
|
(project.selected
|
||||||
|
? "text-shadow-[4px_3px_0_var(--color-cherry-shrimp)]"
|
||||||
|
: "") +
|
||||||
|
" hover:[text-decoration-line:underline_overline] hover:decoration-ashy-shrimp cursor-[unset]"
|
||||||
|
}
|
||||||
|
onClick={() => handleProjectClick(project.id)}
|
||||||
|
>
|
||||||
|
{project.name}
|
||||||
|
</button>
|
||||||
|
));
|
||||||
|
return (
|
||||||
|
<section className="flex gap-[20px] justify-evenly py-[10px] text-tangerine-dream-shrimp text-2xl">
|
||||||
|
{projectList}
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//todo nice to have: border-image on hover would be cool
|
||||||
35
app/components/shrimp-projects/shrimp-projects.tsx
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import { useState } from "react";
|
||||||
|
import ProjectList from "./project-list/project-list";
|
||||||
|
import ProjectContent from "./project-content/project-content";
|
||||||
|
import {
|
||||||
|
getCurrentProjectContent,
|
||||||
|
getProjectList,
|
||||||
|
} from "../../lib/project-content/getShrimps";
|
||||||
|
|
||||||
|
export default function ShrimpProjects() {
|
||||||
|
const [project, setProject] = useState("biotama");
|
||||||
|
const [projectContent, setProjectContent] = useState(
|
||||||
|
getCurrentProjectContent(project)
|
||||||
|
);
|
||||||
|
const [projectList, setProjectlist] = useState(getProjectList(project));
|
||||||
|
|
||||||
|
const handleProjectClick = (newProject: string) => {
|
||||||
|
setProject(newProject);
|
||||||
|
setProjectlist(getProjectList(newProject));
|
||||||
|
setProjectContent(getCurrentProjectContent(newProject));
|
||||||
|
};
|
||||||
|
|
||||||
|
const projectListProps = {
|
||||||
|
projects: projectList,
|
||||||
|
handleProjectClick: handleProjectClick,
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<section className="bg-space-shrimp-blue pb-5 lg:px-25 px-5 wave-border">
|
||||||
|
<ProjectList {...projectListProps} />
|
||||||
|
<ProjectContent {...projectContent}>
|
||||||
|
{projectContent.content}
|
||||||
|
</ProjectContent>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
25
app/components/shrimp-projects/types.tsx
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { StaticImageData } from "next/image";
|
||||||
|
import { ReactNode } from "react";
|
||||||
|
|
||||||
|
export type ProjectImageProps = {
|
||||||
|
src: StaticImageData;
|
||||||
|
alt: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ProjectImages = {
|
||||||
|
left: ProjectImageProps;
|
||||||
|
right: ProjectImageProps;
|
||||||
|
central: ProjectImageProps;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ProjectContentProps = React.PropsWithChildren<{
|
||||||
|
name: string;
|
||||||
|
content: ReactNode;
|
||||||
|
images: ProjectImages;
|
||||||
|
}>;
|
||||||
|
|
||||||
|
export type ProjectListProps = {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
selected: boolean;
|
||||||
|
};
|
||||||
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
53
app/globals.css
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
@import "tailwindcss";
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--background: #ffffff;
|
||||||
|
--foreground: #171717;
|
||||||
|
}
|
||||||
|
|
||||||
|
@theme inline {
|
||||||
|
--color-background: var(--background);
|
||||||
|
--color-foreground: var(--foreground);
|
||||||
|
--font-sans: var(--font-geist-sans);
|
||||||
|
--font-mono: var(--font-geist-mono);
|
||||||
|
--color-space-shrimp-blue: #2c2c54;
|
||||||
|
--color-cherry-shrimp: #a40e4c;
|
||||||
|
--color-ashy-shrimp: #acc3a6;
|
||||||
|
--color-apricot-shrimp: #f5d6ba;
|
||||||
|
--color-tangerine-dream-shrimp: #f49d6e;
|
||||||
|
}
|
||||||
|
|
||||||
|
@utility wave-border {
|
||||||
|
border-image: url("lib/waves-border.png") 27 fill / 35px / 25px 0 0 0 round;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background: var(--background);
|
||||||
|
color: var(--foreground);
|
||||||
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
|
cursor: url("lib/cursors/shrimp_cursor.png"), auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
@theme {
|
||||||
|
--animate-blink: blink-border 0.75s step-end infinite;
|
||||||
|
@keyframes blink-border {
|
||||||
|
from,
|
||||||
|
to {
|
||||||
|
border-color: transparent;
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
border-color: var(--ashy-shrimp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
--animate-shrimply-rain: rain-down 3s linear 1;
|
||||||
|
@keyframes rain-down {
|
||||||
|
0% {
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: translateY(200vh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
33
app/layout.tsx
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import type { Metadata } from "next";
|
||||||
|
import { Geist, Geist_Mono } from "next/font/google";
|
||||||
|
import "./globals.css";
|
||||||
|
|
||||||
|
const geistSans = Geist({
|
||||||
|
variable: "--font-geist-sans",
|
||||||
|
subsets: ["latin"],
|
||||||
|
});
|
||||||
|
|
||||||
|
const geistMono = Geist_Mono({
|
||||||
|
variable: "--font-geist-mono",
|
||||||
|
subsets: ["latin"],
|
||||||
|
});
|
||||||
|
|
||||||
|
export const metadata: Metadata = {
|
||||||
|
title: "Dive into Seafood Delights",
|
||||||
|
description: "It's shrimp",
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function RootLayout({
|
||||||
|
children,
|
||||||
|
}: Readonly<{
|
||||||
|
children: React.ReactNode;
|
||||||
|
}>) {
|
||||||
|
return (
|
||||||
|
<html
|
||||||
|
lang="en"
|
||||||
|
className={`${geistSans.variable} ${geistMono.variable} h-full antialiased`}
|
||||||
|
>
|
||||||
|
<body className="min-h-full flex flex-col">{children}</body>
|
||||||
|
</html>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 4.7 MiB After Width: | Height: | Size: 4.7 MiB |
|
Before Width: | Height: | Size: 3.2 MiB After Width: | Height: | Size: 3.2 MiB |
|
Before Width: | Height: | Size: 2.4 MiB After Width: | Height: | Size: 2.4 MiB |
|
Before Width: | Height: | Size: 983 KiB After Width: | Height: | Size: 983 KiB |
|
Before Width: | Height: | Size: 950 KiB After Width: | Height: | Size: 950 KiB |
|
Before Width: | Height: | Size: 242 KiB After Width: | Height: | Size: 242 KiB |
17
app/lib/project-content/getShrimps.tsx
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import { projects } from "./shrimpjects";
|
||||||
|
|
||||||
|
export function getCurrentProjectContent(project: string) {
|
||||||
|
return {
|
||||||
|
name: projects[project].name,
|
||||||
|
content: projects[project].content,
|
||||||
|
images: projects[project].images,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getProjectList(currentProject: string) {
|
||||||
|
return Object.keys(projects).map((key) => ({
|
||||||
|
id: key.toString(),
|
||||||
|
name: projects[key].name,
|
||||||
|
selected: key === currentProject,
|
||||||
|
}));
|
||||||
|
}
|
||||||
74
app/lib/project-content/shrimpjects.tsx
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
import { StaticImageData } from "next/image";
|
||||||
|
import { ReactNode } from "react";
|
||||||
|
|
||||||
|
import biotamaCentral from "./assets/biotama1.png";
|
||||||
|
import biotamaLeft from "./assets/biotama2.png";
|
||||||
|
import biotamaRight from "./assets/biotama3.png";
|
||||||
|
import htpCentral from "./assets/htp3.png";
|
||||||
|
import htpLeft from "./assets/htp1.png";
|
||||||
|
import htpRight from "./assets/htp2.png";
|
||||||
|
import BiotamaText from "@/app/components/shrimp-projects/project-descriptions/biotama";
|
||||||
|
import HackThePlanetText from "@/app/components/shrimp-projects/project-descriptions/htp";
|
||||||
|
|
||||||
|
type ProjectImage = {
|
||||||
|
src: StaticImageData;
|
||||||
|
alt: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type ProjectImages = {
|
||||||
|
left: ProjectImage;
|
||||||
|
right: ProjectImage;
|
||||||
|
central: ProjectImage;
|
||||||
|
};
|
||||||
|
|
||||||
|
type ProjectContent = {
|
||||||
|
name: string;
|
||||||
|
content: ReactNode;
|
||||||
|
images: ProjectImages;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type Project = {
|
||||||
|
[key: string]: ProjectContent;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const projects: Project = {
|
||||||
|
biotama: {
|
||||||
|
name: "BIOTAMA",
|
||||||
|
content: <BiotamaText />,
|
||||||
|
images: {
|
||||||
|
left: {
|
||||||
|
src: biotamaLeft,
|
||||||
|
alt: "mother tree with a river and cliffs in the background",
|
||||||
|
},
|
||||||
|
right: {
|
||||||
|
src: biotamaRight,
|
||||||
|
alt: "inside of an old brick house looking out the door onto a path leading to a bridge",
|
||||||
|
},
|
||||||
|
central: {
|
||||||
|
src: biotamaCentral,
|
||||||
|
alt: "top down view of the mother tree and greenery",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
htp: {
|
||||||
|
name: "HACK THE PLANET",
|
||||||
|
content: <HackThePlanetText />,
|
||||||
|
images: {
|
||||||
|
left: {
|
||||||
|
src: htpLeft,
|
||||||
|
alt: "visual puzzle with different colours",
|
||||||
|
},
|
||||||
|
right: {
|
||||||
|
src: htpRight,
|
||||||
|
alt: "the player character standing surrounded by various text characters",
|
||||||
|
},
|
||||||
|
central: {
|
||||||
|
src: htpCentral,
|
||||||
|
alt: "top down camera view of a black screen with hex codes randomly placed",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
//todo add new images for biotama
|
||||||
|
//todo use image components instead of properties
|
||||||
|
Before Width: | Height: | Size: 888 B After Width: | Height: | Size: 888 B |
26
app/page.tsx
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
"use client";
|
||||||
|
import Banner from "./components/banner/banner";
|
||||||
|
import HeroShrimp from "./components/hero-shrimp/hero-shrimp";
|
||||||
|
import SeafoodDelights from "./components/seafood-delights/seafood-delights";
|
||||||
|
import ShrimpFeet from "./components/shrimp-feet/shrimp-feet";
|
||||||
|
import ShrimpProjects from "./components/shrimp-projects/shrimp-projects";
|
||||||
|
|
||||||
|
export default function Home() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Banner />
|
||||||
|
<SeafoodDelights />
|
||||||
|
<HeroShrimp />
|
||||||
|
<ShrimpProjects />
|
||||||
|
<ShrimpFeet />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* todo list
|
||||||
|
- more shrimpy font
|
||||||
|
- shrimp profiles (about us)
|
||||||
|
- menu i guess, hamburger, but the lines are waves
|
||||||
|
- animations
|
||||||
|
- shirmp cursor for hover - colour swap
|
||||||
|
*/
|
||||||
|
Before Width: | Height: | Size: 15 KiB |
18
eslint.config.mjs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { defineConfig, globalIgnores } from "eslint/config";
|
||||||
|
import nextVitals from "eslint-config-next/core-web-vitals";
|
||||||
|
import nextTs from "eslint-config-next/typescript";
|
||||||
|
|
||||||
|
const eslintConfig = defineConfig([
|
||||||
|
...nextVitals,
|
||||||
|
...nextTs,
|
||||||
|
// Override default ignores of eslint-config-next.
|
||||||
|
globalIgnores([
|
||||||
|
// Default ignores of eslint-config-next:
|
||||||
|
".next/**",
|
||||||
|
"out/**",
|
||||||
|
"build/**",
|
||||||
|
"next-env.d.ts",
|
||||||
|
]),
|
||||||
|
]);
|
||||||
|
|
||||||
|
export default eslintConfig;
|
||||||
59
index.html
@ -1,59 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en-CA">
|
|
||||||
<head>
|
|
||||||
<title>Dive into Seafood Delights</title>
|
|
||||||
<link rel="icon" type="image/x-icon" href="./shrimpmoji.ico">
|
|
||||||
<link rel="stylesheet" href="shrimpy-styles.css"/>
|
|
||||||
<script type="module">
|
|
||||||
import { getProjectData, itsRainingShrimp} from "./shrimply-the-best.js"
|
|
||||||
window.getProjectData = getProjectData;
|
|
||||||
window.itsRainingShrimp = itsRainingShrimp;
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="shrimply-the-rain"></div>
|
|
||||||
<section class="we-are-shrimp-squad">
|
|
||||||
<img src="assets/shrimp.png"/>
|
|
||||||
<h1>SHRIMP SQUAD</h1>
|
|
||||||
<img class="flip" src="assets/shrimp.png"/>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<div class="shrimp-info">
|
|
||||||
<div> We are Shrimp Squad and we make things. There's no project we can't mantis punch. Shrimply take a look at what we're known for.</div>
|
|
||||||
<button id="seafoodDelightsBtn" type="button">Dive into Seafood Delights</button>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<section class="shrimp-hero">
|
|
||||||
<img src="assets/hero-shrimp.png"/>
|
|
||||||
</section>
|
|
||||||
<section class="shrimp-projects">
|
|
||||||
<section class="shrimp-project-list">
|
|
||||||
<div id='biotama'>BIOTAMA</div>
|
|
||||||
<div id='htp'>HACK THE PLANET</div>
|
|
||||||
</section>
|
|
||||||
<section id="shrimp-project-content">
|
|
||||||
<div class="upper">
|
|
||||||
<img id="image-left" class="smol-image"/>
|
|
||||||
<div id="project-content"></div>
|
|
||||||
<img id="image-right" class="smol-image"/>
|
|
||||||
</div>
|
|
||||||
<img id="image-central"/>
|
|
||||||
</section>
|
|
||||||
</section>
|
|
||||||
<section class="footer">
|
|
||||||
<div id="shrimp-gif"></div>
|
|
||||||
</section>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
||||||
|
|
||||||
<!--
|
|
||||||
|
|
||||||
todo list
|
|
||||||
- more shrimpy font
|
|
||||||
- shrimp profiles (about us)
|
|
||||||
- menu i guess, hamburger, but the lines are waves
|
|
||||||
- animations
|
|
||||||
- shirmp cursor for hover
|
|
||||||
- clean up click handling
|
|
||||||
-->
|
|
||||||
7
next.config.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import type { NextConfig } from "next";
|
||||||
|
|
||||||
|
const nextConfig: NextConfig = {
|
||||||
|
/* config options here */
|
||||||
|
};
|
||||||
|
|
||||||
|
export default nextConfig;
|
||||||
6710
package-lock.json
generated
Normal file
27
package.json
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"name": "shrimp-squad-site",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"dev": "next dev",
|
||||||
|
"build": "next build",
|
||||||
|
"start": "next start",
|
||||||
|
"lint": "eslint"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"next": "16.2.4",
|
||||||
|
"react": "19.2.4",
|
||||||
|
"react-dom": "19.2.4"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@tailwindcss/postcss": "^4",
|
||||||
|
"@types/node": "^20",
|
||||||
|
"@types/react": "^19",
|
||||||
|
"@types/react-dom": "^19",
|
||||||
|
"eslint": "^9",
|
||||||
|
"eslint-config-next": "16.2.4",
|
||||||
|
"prettier": "3.8.3",
|
||||||
|
"tailwindcss": "^4",
|
||||||
|
"typescript": "^5"
|
||||||
|
}
|
||||||
|
}
|
||||||
7
postcss.config.mjs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
const config = {
|
||||||
|
plugins: {
|
||||||
|
"@tailwindcss/postcss": {},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default config;
|
||||||
10
prettier.config.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
// prettier.config.ts, .prettierrc.ts, prettier.config.mts, or .prettierrc.mts
|
||||||
|
|
||||||
|
import { type Config } from "prettier";
|
||||||
|
|
||||||
|
const config: Config = {
|
||||||
|
trailingComma: "es5",
|
||||||
|
tabWidth: 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default config;
|
||||||
1
public/file.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg fill="none" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M14.5 13.5V5.41a1 1 0 0 0-.3-.7L9.8.29A1 1 0 0 0 9.08 0H1.5v13.5A2.5 2.5 0 0 0 4 16h8a2.5 2.5 0 0 0 2.5-2.5m-1.5 0v-7H8v-5H3v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1M9.5 5V2.12L12.38 5zM5.13 5h-.62v1.25h2.12V5zm-.62 3h7.12v1.25H4.5zm.62 3h-.62v1.25h7.12V11z" clip-rule="evenodd" fill="#666" fill-rule="evenodd"/></svg>
|
||||||
|
After Width: | Height: | Size: 391 B |
1
public/globe.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><g clip-path="url(#a)"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.27 14.1a6.5 6.5 0 0 0 3.67-3.45q-1.24.21-2.7.34-.31 1.83-.97 3.1M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.48-1.52a7 7 0 0 1-.96 0H7.5a4 4 0 0 1-.84-1.32q-.38-.89-.63-2.08a40 40 0 0 0 3.92 0q-.25 1.2-.63 2.08a4 4 0 0 1-.84 1.31zm2.94-4.76q1.66-.15 2.95-.43a7 7 0 0 0 0-2.58q-1.3-.27-2.95-.43a18 18 0 0 1 0 3.44m-1.27-3.54a17 17 0 0 1 0 3.64 39 39 0 0 1-4.3 0 17 17 0 0 1 0-3.64 39 39 0 0 1 4.3 0m1.1-1.17q1.45.13 2.69.34a6.5 6.5 0 0 0-3.67-3.44q.65 1.26.98 3.1M8.48 1.5l.01.02q.41.37.84 1.31.38.89.63 2.08a40 40 0 0 0-3.92 0q.25-1.2.63-2.08a4 4 0 0 1 .85-1.32 7 7 0 0 1 .96 0m-2.75.4a6.5 6.5 0 0 0-3.67 3.44 29 29 0 0 1 2.7-.34q.31-1.83.97-3.1M4.58 6.28q-1.66.16-2.95.43a7 7 0 0 0 0 2.58q1.3.27 2.95.43a18 18 0 0 1 0-3.44m.17 4.71q-1.45-.12-2.69-.34a6.5 6.5 0 0 0 3.67 3.44q-.65-1.27-.98-3.1" fill="#666"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h16v16H0z"/></clipPath></defs></svg>
|
||||||
|
After Width: | Height: | Size: 1.0 KiB |
1
public/next.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg>
|
||||||
|
After Width: | Height: | Size: 1.3 KiB |
1
public/vercel.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1155 1000"><path d="m577.3 0 577.4 1000H0z" fill="#fff"/></svg>
|
||||||
|
After Width: | Height: | Size: 128 B |
1
public/window.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 2.5h13v10a1 1 0 0 1-1 1h-11a1 1 0 0 1-1-1zM0 1h16v11.5a2.5 2.5 0 0 1-2.5 2.5h-11A2.5 2.5 0 0 1 0 12.5zm3.75 4.5a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5M7 4.75a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0m1.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5" fill="#666"/></svg>
|
||||||
|
After Width: | Height: | Size: 385 B |
@ -1,32 +0,0 @@
|
|||||||
export const projects = {
|
|
||||||
"biotama":{
|
|
||||||
content:
|
|
||||||
`<p><span class="bold">Biotama</span> is a game where players attempt to convert wastelands into thriving ecosystems.</p>
|
|
||||||
<p>The player starts with a "Mother Tree"
|
|
||||||
which acts as the core component of the player's ecosystem.
|
|
||||||
Trees grow roots that can connect together,
|
|
||||||
allowing them to communicate and send resources between each other.
|
|
||||||
Mycelial networks function similarly for fungi. </p>
|
|
||||||
<p>Biotama aims to be educational as well as fun.
|
|
||||||
It will feature real-world species with tooltips showing fun facts about those species.
|
|
||||||
We are consulting with experts in biology where necessary to ensure accuracy to the real world.</p>
|
|
||||||
`,
|
|
||||||
images: {
|
|
||||||
left: {src:"biotama2.png",alt:"mother tree with a river and cliffs in the background"},
|
|
||||||
right: {src:"biotama3.png",alt:"inside of an old brick house looking out the door onto a path leading to a bridge"},
|
|
||||||
central: {src:"biotama1.png",alt:"top down view of the mother tree and greenery"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"htp":{
|
|
||||||
content: `<p>A game by Shrimp Squad Studios made for the Epic MegaJam!</p>
|
|
||||||
<p>One week to make a game and this is what we made! A game based on the movie Hackers.</p>
|
|
||||||
<p>Your goal is to hack the Gibson computer and collect the garbage file.
|
|
||||||
Which will then in turn let you <span class="bold">HACK THE PLANET!</span> </p>
|
|
||||||
<div class='cta-wrapper'><a class='cta' href='https://megsum.itch.io/hack-the-planet'> >> Try it out!</a></div>`,
|
|
||||||
images: {
|
|
||||||
left: {src:"htp1.png",alt:"visual puzzle with different colours"},
|
|
||||||
right: {src:"htp2.png",alt:"the player character standing surrounded by various text characters"},
|
|
||||||
central: {src:"htp3.png",alt:"top down camera view of a black screen with hex codes randomly placed"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
@ -1,60 +0,0 @@
|
|||||||
import { projects } from "./shrimpjects.js";
|
|
||||||
|
|
||||||
export function getProjectData(project){
|
|
||||||
const leftImage = document.getElementById("image-left");
|
|
||||||
const rightImage = document.getElementById("image-right");
|
|
||||||
const centralImage = document.getElementById("image-central");
|
|
||||||
const projectContent = document.getElementById("project-content");
|
|
||||||
const projectData = projects[project];
|
|
||||||
projectContent.innerHTML = projectData.content;
|
|
||||||
|
|
||||||
const assetPath = "assets/"
|
|
||||||
|
|
||||||
leftImage.src = assetPath + projectData.images.left.src;
|
|
||||||
leftImage.alt = "altleft";
|
|
||||||
rightImage.src = assetPath + projectData.images.right.src;
|
|
||||||
centralImage.src = assetPath + projectData.images.central.src;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function clearSelectedProjectClass() {
|
|
||||||
document.getElementById("biotama").classList.remove("selected-project");
|
|
||||||
document.getElementById("htp").classList.remove("selected-project");
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createShrimpFooter() {
|
|
||||||
const footer = document.getElementById("shrimp-gif");
|
|
||||||
footer.innerHTML = "<img src='./assets/dance-shrimp-dance.gif' alt='a shrimp dancing'>".repeat(10);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function itsRainingShrimp() {
|
|
||||||
const shrimpyRain = document.getElementById("shrimply-the-rain");
|
|
||||||
// push shrimp rain to the front. It's basically an overlay
|
|
||||||
shrimpyRain.style.zIndex = 2;
|
|
||||||
|
|
||||||
var increment = 0;
|
|
||||||
var drops = "";
|
|
||||||
|
|
||||||
// maxWidthToShrimp is set based on image size so not to overflow
|
|
||||||
const maxWidthToShrimp = 83;
|
|
||||||
while (increment < maxWidthToShrimp) {
|
|
||||||
// how much you want shrimp to cover
|
|
||||||
var randomTwoHundo = (Math.floor(Math.random() * 200));
|
|
||||||
|
|
||||||
drops += '<img src="assets/shrimp.png" style="'
|
|
||||||
+ 'left: ' + increment
|
|
||||||
+ '%; bottom: ' + (randomTwoHundo) + '%;" />'
|
|
||||||
|
|
||||||
increment++;
|
|
||||||
}
|
|
||||||
|
|
||||||
shrimpyRain.innerHTML = drops;
|
|
||||||
|
|
||||||
// wait until after the animation plays to make the shrimp disappear 🪄
|
|
||||||
setTimeout(() => {
|
|
||||||
shrimpyRain.style.zIndex = -1;
|
|
||||||
shrimpyRain.innerHTML = "";
|
|
||||||
}, 2950);
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,34 +0,0 @@
|
|||||||
import {
|
|
||||||
getProjectData,
|
|
||||||
clearSelectedProjectClass,
|
|
||||||
createShrimpFooter,
|
|
||||||
itsRainingShrimp
|
|
||||||
} from "./shrimple-functions.js";
|
|
||||||
|
|
||||||
const biotamaBtn = document.getElementById("biotama");
|
|
||||||
const htpBtn = document.getElementById("htp");
|
|
||||||
const seafoodBtn = document.getElementById("seafoodDelightsBtn");
|
|
||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", function(event) {
|
|
||||||
biotamaBtn.click();
|
|
||||||
createShrimpFooter();
|
|
||||||
});
|
|
||||||
|
|
||||||
biotamaBtn.addEventListener("click", function() {
|
|
||||||
clearSelectedProjectClass();
|
|
||||||
this.classList.add("selected-project");
|
|
||||||
getProjectData("biotama");
|
|
||||||
});
|
|
||||||
|
|
||||||
htpBtn.addEventListener("click", function() {
|
|
||||||
clearSelectedProjectClass();
|
|
||||||
this.classList.add("selected-project");
|
|
||||||
getProjectData("htp");
|
|
||||||
});
|
|
||||||
|
|
||||||
seafoodBtn.addEventListener("click", function() {
|
|
||||||
itsRainingShrimp();
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
export {getProjectData, itsRainingShrimp}
|
|
||||||
@ -1,201 +0,0 @@
|
|||||||
body {
|
|
||||||
cursor: url("assets/shrimp_cursor.png"), auto;
|
|
||||||
--space-shrimp-blue: #2C2C54;
|
|
||||||
--cherry-shrimp: #A40E4C;
|
|
||||||
--ashy-shrimp: #ACC3A6;
|
|
||||||
--apricot-shrimp: #F5D6BA;
|
|
||||||
--tangerine-dream-shrimp: #F49D6E;
|
|
||||||
color: var(--space-shrimp-blue);
|
|
||||||
background: repeat url(assets/shrimp-tile.png);
|
|
||||||
background-size: 50px;
|
|
||||||
margin: 0 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.we-are-shrimp-squad {
|
|
||||||
width:100%;
|
|
||||||
height: 50%;
|
|
||||||
background-color: var(--tangerine-dream-shrimp);
|
|
||||||
font-size:30px;
|
|
||||||
display:flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
gap: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.we-are-shrimp-squad img {
|
|
||||||
height:10%;
|
|
||||||
width: 10%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.flip {
|
|
||||||
transform: scaleX(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.shrimp-hero {
|
|
||||||
max-width:100%;
|
|
||||||
height:auto;
|
|
||||||
background-color: var(--apricot-shrimp);
|
|
||||||
display:flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
width:100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.shrimp-hero img {
|
|
||||||
max-width:100%;
|
|
||||||
height:auto;
|
|
||||||
vertical-align: top;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.shrimp-hero div.inside-container, .shrimp-info {
|
|
||||||
background-color: var(--cherry-shrimp);
|
|
||||||
padding:10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.shrimp-hero button, .shrimp-info button{
|
|
||||||
border-radius: 10px;
|
|
||||||
background-color: var(--space-shrimp-blue);
|
|
||||||
color: var(--tangerine-dream-shrimp);
|
|
||||||
padding:10px;
|
|
||||||
margin-top:10px;
|
|
||||||
width: 100%;
|
|
||||||
cursor: unset;
|
|
||||||
}
|
|
||||||
|
|
||||||
.shrimp-project-list {
|
|
||||||
padding: 10px 0;
|
|
||||||
display: flex;
|
|
||||||
gap: 20px;
|
|
||||||
justify-content: space-evenly;
|
|
||||||
border-image: url("./assets/waves-border.png") 27 fill / 35px / 25px 0 0 0 round;
|
|
||||||
position:relative;
|
|
||||||
color: var(--tangerine-dream-shrimp);
|
|
||||||
font-size: 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.shrimp-project-list div:hover {
|
|
||||||
text-decoration: underline overline var(--ashy-shrimp);
|
|
||||||
}
|
|
||||||
|
|
||||||
.selected-project{
|
|
||||||
text-shadow: 4px 3px 0 var(--cherry-shrimp);
|
|
||||||
}
|
|
||||||
|
|
||||||
#shrimp-project-content {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
width: 100%;
|
|
||||||
margin-top: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#shrimp-project-content .upper{
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
gap: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#shrimp-project-content .upper > * {
|
|
||||||
flex-basis: 32%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#shrimp-project-content .upper > div{
|
|
||||||
background-color:var(--tangerine-dream-shrimp);
|
|
||||||
padding: 0 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#shrimp-project-content .smol-image{
|
|
||||||
width: 30%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#shrimp-project-content #image-central {
|
|
||||||
width: inherit;
|
|
||||||
margin-top: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#shrimp-gif {
|
|
||||||
display: flex;
|
|
||||||
flex-flow: row wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
#shrimp-gif > * {
|
|
||||||
width:50%;
|
|
||||||
}
|
|
||||||
#project-content{
|
|
||||||
display:flex;
|
|
||||||
flex-flow:column;
|
|
||||||
margin-top: 0;
|
|
||||||
margin-bottom: 0;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (orientation: portrait) {
|
|
||||||
#shrimp-project-content .upper{
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#shrimp-project-content .smol-image{
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
h1{
|
|
||||||
font-size: 32px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.bold {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* buttons */
|
|
||||||
|
|
||||||
.cta-wrapper{
|
|
||||||
margin:16px 0;
|
|
||||||
background-color: var(--space-shrimp-blue);
|
|
||||||
border-radius: 5px;
|
|
||||||
padding:15px;
|
|
||||||
width:fit-content;
|
|
||||||
}
|
|
||||||
.cta-wrapper .cta {
|
|
||||||
text-decoration: none;
|
|
||||||
border-right: 2px solid var(--ashy-shrimp);
|
|
||||||
color: var(--ashy-shrimp);
|
|
||||||
font-size: 24px;
|
|
||||||
animation: blink-border .75s step-end infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes blink-border {
|
|
||||||
from, to { border-color: transparent }
|
|
||||||
50% { border-color: var(--ashy-shrimp); }
|
|
||||||
}
|
|
||||||
/* end buttons */
|
|
||||||
|
|
||||||
/* shrimp rain animation */
|
|
||||||
#shrimply-the-rain {
|
|
||||||
height:100%;
|
|
||||||
width:100%;
|
|
||||||
overflow: hidden;
|
|
||||||
position:fixed;
|
|
||||||
z-index: -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#shrimply-the-rain > img {
|
|
||||||
animation: RainDown 3s linear 1;
|
|
||||||
position:absolute;
|
|
||||||
width:15%;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes RainDown {
|
|
||||||
0% {
|
|
||||||
transform: translateY(0);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
transform: translateY(200vh);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* end shrimp rain animation */
|
|
||||||
34
tsconfig.json
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ES2017",
|
||||||
|
"lib": ["dom", "dom.iterable", "esnext"],
|
||||||
|
"allowJs": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"strict": true,
|
||||||
|
"noEmit": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"module": "esnext",
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"jsx": "react-jsx",
|
||||||
|
"incremental": true,
|
||||||
|
"plugins": [
|
||||||
|
{
|
||||||
|
"name": "next"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"@/*": ["./*"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"next-env.d.ts",
|
||||||
|
"**/*.ts",
|
||||||
|
"**/*.tsx",
|
||||||
|
".next/types/**/*.ts",
|
||||||
|
".next/dev/types/**/*.ts",
|
||||||
|
"**/*.mts"
|
||||||
|
],
|
||||||
|
"exclude": ["node_modules"]
|
||||||
|
}
|
||||||