Mostly completed hero section
This commit is contained in:
71
package-lock.json
generated
71
package-lock.json
generated
@@ -8,14 +8,17 @@
|
||||
"name": "sunrise",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"@formkit/auto-animate": "^1.0.0-beta.6",
|
||||
"@radix-ui/react-separator": "^1.0.2",
|
||||
"@t3-oss/env-nextjs": "^0.2.1",
|
||||
"class-variance-authority": "^0.6.0",
|
||||
"framer-motion": "^10.12.4",
|
||||
"next": "^13.2.4",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0",
|
||||
"react-hook-form": "^7.43.9",
|
||||
"react-hot-toast": "^2.4.1",
|
||||
"react-icons": "^4.9.0",
|
||||
"zod": "^3.21.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -130,6 +133,11 @@
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@formkit/auto-animate": {
|
||||
"version": "1.0.0-beta.6",
|
||||
"resolved": "https://registry.npmjs.org/@formkit/auto-animate/-/auto-animate-1.0.0-beta.6.tgz",
|
||||
"integrity": "sha512-PVDhLAlr+B4Xb7e+1wozBUWmXa6BFU8xUPR/W/E+TsQhPS1qkAdAsJ25keEnFrcePSnXHrOsh3tiFbEToOzV9w=="
|
||||
},
|
||||
"node_modules/@humanwhocodes/config-array": {
|
||||
"version": "0.11.8",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz",
|
||||
@@ -1210,11 +1218,38 @@
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/class-variance-authority": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.6.0.tgz",
|
||||
"integrity": "sha512-qdRDgfjx3GRb9fpwpSvn+YaidnT7IUJNe4wt5/SWwM+PmUwJUhQRk/8zAyNro0PmVfmen2635UboTjIBXXxy5A==",
|
||||
"dependencies": {
|
||||
"clsx": "1.2.1"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://joebell.co.uk"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": ">= 4.5.5 < 6"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"typescript": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/client-only": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
|
||||
"integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="
|
||||
},
|
||||
"node_modules/clsx": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz",
|
||||
"integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
@@ -3848,6 +3883,14 @@
|
||||
"react-dom": ">=16"
|
||||
}
|
||||
},
|
||||
"node_modules/react-icons": {
|
||||
"version": "4.9.0",
|
||||
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.9.0.tgz",
|
||||
"integrity": "sha512-ijUnFr//ycebOqujtqtV9PFS7JjhWg0QU6ykURVHuL4cbofvRCf3f6GMn9+fBktEFQOIVZnuAYLZdiyadRQRFg==",
|
||||
"peerDependencies": {
|
||||
"react": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/react-is": {
|
||||
"version": "16.13.1",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||
@@ -4463,7 +4506,7 @@
|
||||
"version": "5.0.4",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz",
|
||||
"integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==",
|
||||
"dev": true,
|
||||
"devOptional": true,
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
@@ -4717,6 +4760,11 @@
|
||||
"integrity": "sha512-kf9RB0Fg7NZfap83B3QOqOGg9QmD9yBudqQXzzOtn3i4y7ZUXe5ONeW34Gwi+TxhH4mvj72R1Zc300KUMa9Bng==",
|
||||
"dev": true
|
||||
},
|
||||
"@formkit/auto-animate": {
|
||||
"version": "1.0.0-beta.6",
|
||||
"resolved": "https://registry.npmjs.org/@formkit/auto-animate/-/auto-animate-1.0.0-beta.6.tgz",
|
||||
"integrity": "sha512-PVDhLAlr+B4Xb7e+1wozBUWmXa6BFU8xUPR/W/E+TsQhPS1qkAdAsJ25keEnFrcePSnXHrOsh3tiFbEToOzV9w=="
|
||||
},
|
||||
"@humanwhocodes/config-array": {
|
||||
"version": "0.11.8",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz",
|
||||
@@ -5434,11 +5482,24 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"class-variance-authority": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.6.0.tgz",
|
||||
"integrity": "sha512-qdRDgfjx3GRb9fpwpSvn+YaidnT7IUJNe4wt5/SWwM+PmUwJUhQRk/8zAyNro0PmVfmen2635UboTjIBXXxy5A==",
|
||||
"requires": {
|
||||
"clsx": "1.2.1"
|
||||
}
|
||||
},
|
||||
"client-only": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
|
||||
"integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="
|
||||
},
|
||||
"clsx": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz",
|
||||
"integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg=="
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
@@ -7256,6 +7317,12 @@
|
||||
"goober": "^2.1.10"
|
||||
}
|
||||
},
|
||||
"react-icons": {
|
||||
"version": "4.9.0",
|
||||
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.9.0.tgz",
|
||||
"integrity": "sha512-ijUnFr//ycebOqujtqtV9PFS7JjhWg0QU6ykURVHuL4cbofvRCf3f6GMn9+fBktEFQOIVZnuAYLZdiyadRQRFg==",
|
||||
"requires": {}
|
||||
},
|
||||
"react-is": {
|
||||
"version": "16.13.1",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||
@@ -7700,7 +7767,7 @@
|
||||
"version": "5.0.4",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz",
|
||||
"integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==",
|
||||
"dev": true
|
||||
"devOptional": true
|
||||
},
|
||||
"unbox-primitive": {
|
||||
"version": "1.0.2",
|
||||
|
||||
@@ -9,14 +9,17 @@
|
||||
"start": "next start"
|
||||
},
|
||||
"dependencies": {
|
||||
"@formkit/auto-animate": "^1.0.0-beta.6",
|
||||
"@radix-ui/react-separator": "^1.0.2",
|
||||
"@t3-oss/env-nextjs": "^0.2.1",
|
||||
"class-variance-authority": "^0.6.0",
|
||||
"framer-motion": "^10.12.4",
|
||||
"next": "^13.2.4",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0",
|
||||
"react-hook-form": "^7.43.9",
|
||||
"react-hot-toast": "^2.4.1",
|
||||
"react-icons": "^4.9.0",
|
||||
"zod": "^3.21.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<svg width="1920" height="236" viewBox="0 0 1920 236" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<svg width="100%" height="100%" preserveAspectRatio="none" viewBox="0 0 1920 236" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_57_333)">
|
||||
<path d="M0 160.48L40.0593 146.556C80.237 132.514 160.356 104.666 240.356 87.32C320.356 69.974 400.237 63.366 480.237 81.42C560.237 99.474 640.356 142.426 720.356 150.45C800.356 158.474 880.237 131.806 960.237 131.806C1040.24 131.806 1120.36 158.474 1200.36 171.454C1280.36 184.434 1360.24 183.726 1440.24 165.2C1520.24 146.674 1600.36 110.566 1680.36 102.896C1760.36 95.226 1840.24 115.994 1880.06 126.496L1920 136.88V237.18H1880.06C1840.24 237.18 1760.36 237.18 1680.36 237.18C1600.36 237.18 1520.24 237.18 1440.24 237.18C1360.24 237.18 1280.36 237.18 1200.36 237.18C1120.36 237.18 1040.24 237.18 960.237 237.18C880.237 237.18 800.356 237.18 720.356 237.18C640.356 237.18 560.237 237.18 480.237 237.18C400.237 237.18 320.356 237.18 240.356 237.18C160.356 237.18 80.237 237.18 40.0593 237.18H0V160.48Z" fill="#F0D4B2"/>
|
||||
</g>
|
||||
|
||||
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.1 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 64 KiB |
25
src/components/Button.tsx
Normal file
25
src/components/Button.tsx
Normal file
@@ -0,0 +1,25 @@
|
||||
import React from "react";
|
||||
import { cva } from "class-variance-authority";
|
||||
|
||||
const button = cva([
|
||||
"flex flex-row items-center gap-x-2 rounded-full px-6 py-4",
|
||||
"text-r-lg font-semibold text-black",
|
||||
"bg-sunrise shadow-md",
|
||||
"hover:bg-sunrise/80",
|
||||
]);
|
||||
|
||||
interface Props {
|
||||
children?: React.ReactNode;
|
||||
onClick?: () => void;
|
||||
href?: string;
|
||||
}
|
||||
|
||||
export const Button: React.FC<Props> = ({ children, onClick, href }) => {
|
||||
const Wrapper = href ? "a" : "button";
|
||||
|
||||
return (
|
||||
<Wrapper className={button()} href={href} onClick={onClick}>
|
||||
{children}
|
||||
</Wrapper>
|
||||
);
|
||||
};
|
||||
@@ -23,9 +23,7 @@ export const RootLayout: React.FC<PropsWithChildren> = ({ children }) => {
|
||||
return (
|
||||
<>
|
||||
<Header />
|
||||
<main
|
||||
className={`${jakarta.variable} ${roadster.variable} min-h-screen bg-white font-sans`}
|
||||
>
|
||||
<main className={`${jakarta.variable} ${roadster.variable} font-sans`}>
|
||||
{children}
|
||||
</main>
|
||||
<Footer />
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
import { cva, cx } from "class-variance-authority";
|
||||
import { type NextPage } from "next";
|
||||
import Head from "next/head";
|
||||
import Image from "next/image";
|
||||
import { useEffect, useState } from "react";
|
||||
import { Button } from "~/components/Button";
|
||||
import { Container } from "~/components/Container";
|
||||
import { Polaroid } from "~/components/Polaroid";
|
||||
import { ProjectDescription } from "~/components/ProjectDescription";
|
||||
import { projects } from "~/constants/projects";
|
||||
import { MdArrowCircleDown } from "react-icons/md";
|
||||
|
||||
const Home: NextPage = () => {
|
||||
return (
|
||||
@@ -27,36 +31,78 @@ const Home: NextPage = () => {
|
||||
|
||||
export default Home;
|
||||
|
||||
const ribbon = cva("relative w-full transition-all duration-500", {
|
||||
variants: {
|
||||
state: {
|
||||
ribbon: "h-40 top-[20vh]",
|
||||
sunrise: "h-[95vh] top-[5vh]",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const Hero = () => {
|
||||
// Transform ribbon into sunrise on scroll
|
||||
const [showSunrise, setShowSunrise] = useState(false);
|
||||
useEffect(() => {
|
||||
const onScroll = () => {
|
||||
const showSunriseThreshold_vh = 5;
|
||||
const showSunriseThreshold_px =
|
||||
(window.innerHeight * showSunriseThreshold_vh) / 100;
|
||||
|
||||
setShowSunrise(window.pageYOffset > showSunriseThreshold_px);
|
||||
};
|
||||
|
||||
window.addEventListener("scroll", onScroll);
|
||||
return () => window.removeEventListener("scroll", onScroll);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="absolute min-h-full w-full">
|
||||
<div className="absolute mt-[20vh] h-[17vh] w-full">
|
||||
<Image
|
||||
src="/images/ribbon.webp"
|
||||
alt="Sunrise background banner"
|
||||
className="scale-pixelated"
|
||||
fill
|
||||
/>
|
||||
{/* TODO: Create + replace with .svg */}
|
||||
<Image
|
||||
src="/images/sunrise-display.png"
|
||||
alt="Sunrise Software"
|
||||
className="object-contain py-2"
|
||||
fill
|
||||
/>
|
||||
</div>
|
||||
<Container component="section">
|
||||
<h1 className="py-3 font-roadster text-5xl text-black">Sunrise</h1>
|
||||
<p className="leading-relaxed text-black lg:text-xl">
|
||||
<div className="relative min-h-screen w-full">
|
||||
<div className="flex flex-col items-center">
|
||||
<div className="absolute inset-0 -z-10">
|
||||
<div
|
||||
className={ribbon({ state: showSunrise ? "sunrise" : "ribbon" })}
|
||||
>
|
||||
<Image
|
||||
src="/images/ribbon.webp"
|
||||
alt="Sunrise background banner"
|
||||
className={cx(
|
||||
"transition-all duration-500",
|
||||
showSunrise ? "" : "shadow-lg scale-pixelated"
|
||||
)}
|
||||
fill
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="relative mt-[20vh] h-40 w-full">
|
||||
{/* TODO: Create + replace with .svg */}
|
||||
<Image
|
||||
src="/images/sunrise-display.png"
|
||||
alt="Sunrise Software"
|
||||
className="object-contain px-4 py-2"
|
||||
fill
|
||||
/>
|
||||
</div>
|
||||
<p className="mb-8 mt-5 max-w-xl text-center leading-relaxed text-black text-r-lg sm:mb-20 sm:mt-8 md:max-w-2xl lg:mb-32 lg:mt-11 2xl:max-w-4xl">
|
||||
Creating software that looks and works great is our specialty at
|
||||
Sunrise. Our team of experts combines artistry and technical
|
||||
know-how to craft solutions that will make your business{" "}
|
||||
Sunrise.
|
||||
<br />
|
||||
Our team of experts combines artistry and technical know-how to
|
||||
craft solutions that will make your business{" "}
|
||||
<span className="font-semibold text-orange">shine</span>.
|
||||
</p>
|
||||
</Container>
|
||||
{/* TODO: Make functional + more interesting */}
|
||||
<Button>
|
||||
Check out our work <MdArrowCircleDown size="1.25em" />
|
||||
</Button>
|
||||
</div>
|
||||
<div className="absolute bottom-0 w-full">
|
||||
<div className="md: relative h-16 w-full sm:h-20 md:h-32 xl:h-56 2xl:h-72">
|
||||
<Image src="/images/sand-top-1.svg" alt="sand" fill />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="h-screen" />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
html {
|
||||
@apply bg-white;
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ export default {
|
||||
"3xl": ["3rem", { lineHeight: "2.25rem" }], // 48px 3rem
|
||||
},
|
||||
fontFamily: {
|
||||
sans: ["var(--font-jakarta)"],
|
||||
sans: ["var(--font-jakarta)", ...fontFamily.sans],
|
||||
roadster: ["var(--font-roadster)", ...fontFamily.sans],
|
||||
},
|
||||
colors: {
|
||||
|
||||
Reference in New Issue
Block a user