diff --git a/package.json b/package.json
index aa496a7..eae7dd1 100644
--- a/package.json
+++ b/package.json
@@ -21,6 +21,7 @@
"@jest/types": "^29.6.3",
"@svgr/webpack": "^8.1.0",
"@testing-library/react": "^16.1.0",
+ "classnames": "^2.5.1",
"gsap": "^3.12.5",
"html-react-parser": "^5.2.1",
"next": "^15.1.2",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 1d4b0a4..4d9aa3d 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -20,6 +20,9 @@ importers:
'@testing-library/react':
specifier: ^16.1.0
version: 16.1.0(@testing-library/dom@10.3.1)(@types/react@19.0.2)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ classnames:
+ specifier: ^2.5.1
+ version: 2.5.1
gsap:
specifier: ^3.12.5
version: 3.12.5
@@ -1806,6 +1809,9 @@ packages:
cjs-module-lexer@1.2.3:
resolution: {integrity: sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==}
+ classnames@2.5.1:
+ resolution: {integrity: sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==}
+
client-only@0.0.1:
resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==}
@@ -5542,6 +5548,8 @@ snapshots:
cjs-module-lexer@1.2.3: {}
+ classnames@2.5.1: {}
+
client-only@0.0.1: {}
cliui@8.0.1:
diff --git a/public/favicon.webp b/public/favicon.webp
deleted file mode 100644
index 1289695..0000000
Binary files a/public/favicon.webp and /dev/null differ
diff --git a/public/robots.txt b/public/robots.txt
deleted file mode 100644
index d114006..0000000
--- a/public/robots.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-User-agent: *
-Allow: /
-Sitemap: https://wadehammes.com/sitemap.xml
\ No newline at end of file
diff --git a/src/app/favicon.ico b/src/app/favicon.ico
new file mode 100644
index 0000000..9057097
Binary files /dev/null and b/src/app/favicon.ico differ
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index 94cfdca..d3570a0 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -1,11 +1,19 @@
"use client";
import isValidProp from "@emotion/is-prop-valid";
+import { Space_Mono } from "next/font/google";
import StyledComponentsRegistry from "src/lib/registry";
import { CSSRootVariables } from "src/styles/cssVariables";
import { GlobalStyles } from "src/styles/global";
import { StyleSheetManager } from "styled-components";
+const spaceMono = Space_Mono({
+ subsets: ["latin"],
+ weight: ["400", "700"],
+ display: "swap",
+ variable: "--font-mono",
+});
+
export default function RootLayout({
// Layouts must accept a children prop.
// This will be populated with nested layouts or pages
@@ -14,21 +22,7 @@ export default function RootLayout({
children: React.ReactNode;
}) {
return (
-
-
- Wade Hammes
-
-
-
-
-
-
+
diff --git a/src/app/manifest.ts b/src/app/manifest.ts
new file mode 100644
index 0000000..c41d95f
--- /dev/null
+++ b/src/app/manifest.ts
@@ -0,0 +1,20 @@
+import type { MetadataRoute } from "next";
+
+export default function manifest(): MetadataRoute.Manifest {
+ return {
+ name: "Wade Hammes",
+ short_name: "Wade Hammes",
+ description: "Wade is a software engineer for Rhythm Energy, helping build the best customer experience in retail renewable energy, and a co-founder of Provisioner, a full-service creative agency helping to grow brands.",
+ start_url: "/",
+ display: "standalone",
+ background_color: "#171717",
+ theme_color: "#171717",
+ icons: [
+ {
+ src: "/favicon.ico",
+ sizes: "any",
+ type: "image/x-icon",
+ },
+ ],
+ };
+}
diff --git a/src/app/opengraph-image.alt.txt b/src/app/opengraph-image.alt.txt
new file mode 100644
index 0000000..6e95209
--- /dev/null
+++ b/src/app/opengraph-image.alt.txt
@@ -0,0 +1 @@
+Wade Hammes - Software Engineer
\ No newline at end of file
diff --git a/src/app/opengraph-image.png b/src/app/opengraph-image.png
new file mode 100644
index 0000000..2e5b957
Binary files /dev/null and b/src/app/opengraph-image.png differ
diff --git a/src/app/page.tsx b/src/app/page.tsx
index 6c56573..38c6650 100644
--- a/src/app/page.tsx
+++ b/src/app/page.tsx
@@ -1,42 +1,18 @@
-"use client";
+import type { Metadata } from "next";
+import { HomePage } from "src/components/HomePage/HomePage.component";
-import { type FC, type ReactElement, useEffect, useState } from "react";
-import { useInView } from "react-intersection-observer";
-import { Bio } from "src/components/Bio/Bio.component";
-import { Footer, FooterActions } from "src/components/Layout";
-import { PageContainer } from "src/components/PageContainer/Page.component";
-import { SpiralsActions } from "src/components/Spirals/SpiralsActions";
-import { SpiralsSVG } from "src/components/Spirals/SpiralsSVG.component";
-import { isBrowser } from "src/utils/helpers";
-const Home: FC = (): ReactElement => {
- const [key, updateKey] = useState(new Date());
- const [clientReady, setClientReady] = useState(false);
- const { inView, ref } = useInView({
- triggerOnce: true,
- initialInView: true,
- fallbackInView: true,
- });
+export function generateMetadata(): Metadata {
+ return {
+ metadataBase: new URL("https://wadehammes.com/"),
+ creator: "Wade Hammes",
+ publisher: "Wade Hammes",
+ description: "Wade Hammes is a software engineer for Rhythm Energy, helping build the best customer experience in retail renewable energy, and a co-founder of Provisioner, a full-service creative agency helping to grow brands.",
+ };
+}
- useEffect(() => {
- if (isBrowser() && inView) {
- setClientReady(true);
- }
- }, [inView]);
-
- return (
- <>
-
-
-
- {clientReady && }
- >
- );
+const Home = () => {
+ return ;
};
export default Home;
diff --git a/src/app/robots.ts b/src/app/robots.ts
new file mode 100644
index 0000000..7cc37cd
--- /dev/null
+++ b/src/app/robots.ts
@@ -0,0 +1,11 @@
+import type { MetadataRoute } from "next";
+
+export default function robots(): MetadataRoute.Robots {
+ return {
+ rules: {
+ userAgent: "*",
+ allow: "/",
+ },
+ sitemap: "https://www.wadehammes.com/sitemap-index.xml",
+ };
+}
diff --git a/src/components/Bio/Bio.component.tsx b/src/components/Bio/Bio.component.tsx
index a9e5052..cb00a5f 100644
--- a/src/components/Bio/Bio.component.tsx
+++ b/src/components/Bio/Bio.component.tsx
@@ -32,6 +32,14 @@ export const Bio = () => (
Instagram
+ ,{" "}
+
+ Bluesky
+
, and{" "}
all other links
diff --git a/src/components/HomePage/HomePage.component.tsx b/src/components/HomePage/HomePage.component.tsx
new file mode 100644
index 0000000..6094472
--- /dev/null
+++ b/src/components/HomePage/HomePage.component.tsx
@@ -0,0 +1,40 @@
+"use client";
+
+import { useEffect, useState } from "react";
+import { useInView } from "react-intersection-observer";
+import { Bio } from "src/components/Bio/Bio.component";
+import { Footer, FooterActions } from "src/components/Layout";
+import PageContainer from "src/components/PageContainer/Page.component";
+import SpiralsActions from "src/components/Spirals/SpiralsActions";
+import SpiralsSVG from "src/components/Spirals/SpiralsSVG.component";
+import { isBrowser } from "src/helpers/helpers";
+
+export const HomePage = () => {
+ const [key, updateKey] = useState(new Date());
+ const [clientReady, setClientReady] = useState(false);
+ const { inView, ref } = useInView({
+ triggerOnce: true,
+ initialInView: true,
+ fallbackInView: true,
+ });
+
+ useEffect(() => {
+ if (isBrowser() && inView) {
+ setClientReady(true);
+ }
+ }, [inView]);
+
+ return (
+ <>
+
+
+
+ {clientReady && }
+ >
+ );
+};
diff --git a/src/components/Typography.tsx b/src/components/Typography.tsx
index 955718e..79a018f 100644
--- a/src/components/Typography.tsx
+++ b/src/components/Typography.tsx
@@ -4,8 +4,7 @@ import styled from "styled-components";
export const H1 = styled.h1`
font-size: 2rem;
- font-family: "Suez One", serif;
- font-weight: ${FontWeight.Bold};
+ font-weight: 700;
padding-bottom: 1.5rem;
line-height: 1.1;
diff --git a/src/styles/cssVariables.ts b/src/styles/cssVariables.ts
index cfe05c6..3b70704 100644
--- a/src/styles/cssVariables.ts
+++ b/src/styles/cssVariables.ts
@@ -11,7 +11,7 @@ export const CSSRootVariables = createGlobalStyle`
--colors-green: hsla(145,55%,58%,1);
--colors-red: hsla(350,95%,58%,0.83);
--colors-purple: hsla(229,94%,76%,0.915);
- --colors-trueBlack: #000000;
+ --colors-trueBlack: #171717;
--colors-alphaBlack: rgba(0, 0, 0, 0.25);
--sizing-mobilePadding: 2em;
--sizing-desktopPadding: 5em;
diff --git a/src/styles/global.ts b/src/styles/global.ts
index d7e34d7..d575e96 100644
--- a/src/styles/global.ts
+++ b/src/styles/global.ts
@@ -32,7 +32,7 @@ export const GlobalStyles = createGlobalStyle`
body {
background: var(--color-bg);
color: var(--color-text);
- font-family: 'Space Mono', monospace;
+ font-family: var(--font-mono);
font-size: 14px;
transition: background 0.2s ease-in-out;
@@ -42,6 +42,7 @@ export const GlobalStyles = createGlobalStyle`
}
body {
line-height: 1;
+ font-family: var(--font-mono);
}
img {
max-width: 100%;