diff --git a/website/app/GlobalStyles.ts b/website/app/GlobalStyles.ts
new file mode 100644
index 0000000..fd8fb4e
--- /dev/null
+++ b/website/app/GlobalStyles.ts
@@ -0,0 +1,184 @@
+"use client";
+
+import { createGlobalStyle, css } from "styled-components";
+
+const styles = css`
+ :root {
+ color-scheme: only light;
+
+ --max-width: 1248px;
+ --border-radius: 4px;
+
+ /* --font-mono: ui-monospace, Menlo, Monaco, "Cascadia Mono", "Segoe UI Mono", */
+ /* "Roboto Mono", "Oxygen Mono", "Ubuntu Monospace", "Source Code Pro", */
+ /* "Fira Mono", "Droid Sans Mono", "Courier New", monospace; */
+
+ /* color vars */
+ --brand-primary: #ff602c;
+ --brand-primary-dark: rgba(168, 50, 5, 0.4);
+ --brand-secondary: #fca061;
+ --gradient-from-bg: linear-gradient(84deg, transparent 0%, white 100%);
+ --gradient-to-bg: linear-gradient(180deg, transparent 0%, white 100%);
+
+ --gradient-brand: linear-gradient(
+ to right,
+ var(--brand-primary),
+ var(--brand-secondary)
+ );
+ --gradient-brand-reverse: linear-gradient(
+ to right,
+ var(--brand-secondary),
+ var(--brand-primary)
+ );
+
+ --gradient-brand-dark: linear-gradient(
+ 90deg,
+ #fca061,
+ rgba(168, 50, 5, 0.4)
+ );
+ --white-10: rgba(255, 255, 255, 0.1);
+ --white-20: rgba(255, 255, 255, 0.2);
+ --white-40: rgba(255, 255, 255, 0.4);
+ --white-60: rgba(255, 255, 255, 0.6);
+ --white-70: rgba(255, 255, 255, 0.7);
+ --white-90: rgba(255, 255, 255, 0.9);
+ --white-100: #ffffff;
+
+ /* TODO: too many grays... consolidate */
+ --gray-100: #f3f4f6;
+ --gray-200: #e5e7eb;
+ --gray-400: #9ca3af;
+ --gray-600: #4b5563;
+ --gray-bg-light: #212121;
+ --gray-bg: #1f232a;
+ --gray-dark: #21262d;
+ --gray-diagramlines: #666a6f;
+ --gray-icon: #8b949e;
+ --gray-light: #aaa;
+ --gray-lighter: #f2f2f2;
+ --gray-lightest: #fafafa;
+ --gray: #525157;
+
+ --blue: #1f56a5;
+ --blue-light: #58a6ff;
+
+ --black: #000330;
+ --white: #ffffff;
+
+ /* semantic vars */
+ --foreground: var(--gray);
+ --foreground-dark: var(--black);
+ --foreground-light: var(--gray-light);
+
+ --foreground-inverted: var(--gray-light);
+ --foreground-dark-inverted: var(--gray-lighter);
+
+ --background: var(--white);
+ --background-light: var(--gray-bg-light, #212121);
+ --background-dark: var(--gray-bg-dark, #21262d);
+
+ --background-contrast: #fff9f2;
+ --background-inverted: var(--gray-bg);
+
+ --gray-border: #ddd;
+ }
+
+ * {
+ -moz-font-feature-settings: "liga" on;
+ -moz-osx-font-smoothing: grayscale;
+ -webkit-font-smoothing: antialiased;
+ box-sizing: border-box;
+ font-smooth: always;
+ margin: 0;
+ padding: 0;
+ text-rendering: optimizeLegibility;
+ }
+
+ html,
+ body {
+ background: var(--background);
+ overflow-x: hidden;
+ scroll-behavior: smooth;
+ }
+
+ body {
+ color: var(--foreground);
+ }
+
+ a {
+ color: inherit;
+ text-decoration: none;
+ }
+
+ em {
+ font-weight: 500;
+ background: var(--gradient-brand-reverse);
+ background-size: auto;
+ background-clip: border-box;
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+ font-style: normal;
+ }
+
+ s {
+ text-decoration: none;
+ position: relative;
+ display: inline-block;
+ }
+
+ s:after {
+ content: "";
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background-image: url("/scribble-animated.svg");
+ background-size: 100%;
+ background-repeat: no-repeat;
+ }
+
+ hr {
+ border: 0;
+ border-bottom: 1px solid var(--gray-border);
+ }
+
+ br[data-mobile="true"] {
+ display: none;
+ }
+
+ @media (max-width: 768px) {
+ br[data-desktop="true"] {
+ display: none;
+ }
+ br[data-mobile="true"] {
+ display: block;
+ }
+ }
+
+ html {
+ color-scheme: light;
+ }
+
+ pre {
+ background-color: var(--gray-bg) !important;
+ padding: 12px !important;
+ }
+
+ code {
+ line-height: 1.6;
+ font-size: 14px;
+ font-style: normal;
+ font-weight: 400;
+ }
+
+ @media (max-width: 768px) {
+ code {
+ font-size: 14px;
+ }
+ }
+`;
+
+const GlobalStyles = createGlobalStyle`${styles}`;
+
+export default GlobalStyles;
diff --git a/website/app/Providers.tsx b/website/app/Providers.tsx
new file mode 100644
index 0000000..1c784f1
--- /dev/null
+++ b/website/app/Providers.tsx
@@ -0,0 +1,25 @@
+import { ReactNode } from "react";
+
+import { CalculatorProvider } from "@/context/CalculatorContext";
+import { ModalProvider } from "@/context/ModalContext";
+import { VotingProvider } from "@/context/VotingContext";
+
+import StyledComponentsRegistry from "../lib/registry";
+
+interface Props {
+ children: ReactNode;
+}
+
+const Providers = ({ children }: Props) => {
+ return (
+
+
+
+ {children}
+
+
+
+ );
+};
+
+export default Providers;
diff --git a/website/app/globals.css b/website/app/globals.css
deleted file mode 100644
index 1ea4ebf..0000000
--- a/website/app/globals.css
+++ /dev/null
@@ -1,162 +0,0 @@
-:root {
- color-scheme: only light;
-
- --max-width: 1248px;
- --border-radius: 4px;
-
- /* --font-mono: ui-monospace, Menlo, Monaco, "Cascadia Mono", "Segoe UI Mono", */
- /* "Roboto Mono", "Oxygen Mono", "Ubuntu Monospace", "Source Code Pro", */
- /* "Fira Mono", "Droid Sans Mono", "Courier New", monospace; */
-
- /* color vars */
- --brand-primary: #ff602C;
- --brand-primary-dark: rgba(168, 50, 5, 0.4);
- --brand-secondary: #FCA061;
- --gradient-from-bg: linear-gradient(84deg, transparent 0%, white 100%);
- --gradient-to-bg: linear-gradient(180deg, transparent 0%, white 100%);
-
- --gradient-brand: linear-gradient(to right, var(--brand-primary), var(--brand-secondary));
- --gradient-brand-reverse: linear-gradient(to right, var(--brand-secondary), var(--brand-primary));
-
- --gradient-brand-dark: linear-gradient(90deg, #fCA061, rgba(168, 50, 5, 0.4));
- --white-10: rgba(255, 255, 255, 0.1);
- --white-20: rgba(255, 255, 255, 0.2);
- --white-40: rgba(255, 255, 255, 0.4);
- --white-60: rgba(255, 255, 255, 0.6);
- --white-70: rgba(255, 255, 255, 0.7);
- --white-90: rgba(255, 255, 255, 0.9);
- --white-100: #ffffff;
-
- /* TODO: too many grays... consolidate */
- --gray-100: #F3F4F6;
- --gray-200: #E5E7EB;
- --gray-400: #9CA3AF;
- --gray-600: #4b5563;
- --gray-bg-light: #212121;
- --gray-bg: #1f232a;
- --gray-dark: #21262d;
- --gray-diagramlines: #666a6f;
- --gray-icon: #8b949e;
- --gray-light: #aaa;
- --gray-lighter: #f2f2f2;
- --gray-lightest: #fafafa;
- --gray: #525157;
-
- --blue: #1F56A5;
- --blue-light: #58A6FF;
-
- --black: #000330;
- --white: #ffffff;
-
- /* semantic vars */
- --foreground: var(--gray);
- --foreground-dark: var(--black);
- --foreground-light: var(--gray-light);
-
- --foreground-inverted: var(--gray-light);
- --foreground-dark-inverted: var(--gray-lighter);
-
- --background: var(--white);
- --background-light: var(--gray-bg-light, #212121);
- --background-dark: var(--gray-bg-dark, #21262d);
-
- --background-contrast: #fff9f2;
- --background-inverted: var(--gray-bg);
-
- --gray-border: #ddd;
-}
-
-* {
- -moz-font-feature-settings: "liga" on;
- -moz-osx-font-smoothing: grayscale;
- -webkit-font-smoothing: antialiased;
- box-sizing: border-box;
- font-smooth: always;
- margin: 0;
- padding: 0;
- text-rendering: optimizeLegibility;
-}
-
-html,
-body {
- background: var(--background);
- overflow-x: hidden;
- scroll-behavior: smooth;
-}
-
-body {
- color: var(--foreground);
-}
-
-a {
- color: inherit;
- text-decoration: none;
-}
-
-em {
- font-weight: 500;
- background: var(--gradient-brand-reverse);
- background-size: auto;
- background-clip: border-box;
- -webkit-background-clip: text;
- -webkit-text-fill-color: transparent;
- font-style: normal;
-}
-
-s {
- text-decoration: none;
- position: relative;
- display: inline-block;
-}
-
-s:after {
- content: "";
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- background-image: url("/scribble-animated.svg");
- background-size: 100%;
- background-repeat: no-repeat;
-}
-
-hr {
- border: 0;
- border-bottom: 1px solid var(--gray-border);
-}
-
-br[data-mobile="true"] {
- display: none;
-}
-
-@media (max-width: 768px) {
- br[data-desktop="true"] {
- display: none;
- }
- br[data-mobile="true"] {
- display: block;
- }
-}
-
-html {
- color-scheme: light;
-}
-
-pre {
- background-color: var(--gray-bg) !important;
- padding: 12px !important;
-}
-
-code {
- line-height: 1.6;
- font-size: 14px;
- font-style: normal;
- font-weight: 400;
-}
-
-@media (max-width: 768px) {
- code {
- font-size: 14px;
- }
-}
diff --git a/website/app/layout.tsx b/website/app/layout.tsx
index 178655e..506fcc2 100644
--- a/website/app/layout.tsx
+++ b/website/app/layout.tsx
@@ -2,21 +2,15 @@ import { GoogleTagManager } from "@next/third-parties/google";
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import { ReactNode } from "react";
-import { Suspense } from "react";
import Footer from "@/components/Footer";
import Main from "@/components/Main";
import Modal from "@/components/Modal";
import Nav from "@/components/Nav";
import SegmentAnalytics from "@/components/SegmentAnalytics";
-import { CalculatorProvider } from "@/context/CalculatorContext";
-import { ModalProvider } from "@/context/ModalContext";
-import { VotingProvider } from "@/context/VotingContext";
-import StyledComponentsRegistry from "../lib/registry";
-
-import "react-responsive-carousel/lib/styles/carousel.min.css";
-import "./globals.css";
+import GlobalStyles from "./GlobalStyles";
+import Providers from "./Providers";
const inter = Inter({
subsets: ["latin"],
@@ -37,7 +31,7 @@ export default function RootLayout({
children: ReactNode;
}>) {
return (
-
+
-
-
-
-
-
-
- {children}
-
-
-
-
-
-
-
+
+
+
+ {children}
+
+
+
);
diff --git a/website/context/CalculatorContext.tsx b/website/context/CalculatorContext.tsx
index 6ce3971..bd97957 100644
--- a/website/context/CalculatorContext.tsx
+++ b/website/context/CalculatorContext.tsx
@@ -1,6 +1,5 @@
"use client";
-import { useSearchParams } from "next/navigation";
import {
createContext,
Dispatch,
@@ -43,7 +42,9 @@ const HOURLY_COST_PER_RESOURCE_REQUIREMENT: Record<
};
export const CalculatorProvider = ({ children }: PropsWithChildren) => {
- const searchParams = useSearchParams();
+ const searchParams = new URLSearchParams(
+ typeof window !== "undefined" ? window.location.search : "",
+ );
const initialEngineers: number =
searchParams.get("engineers") != null
diff --git a/website/next.config.mjs b/website/next.config.mjs
index d27228b..df1c20f 100644
--- a/website/next.config.mjs
+++ b/website/next.config.mjs
@@ -6,13 +6,13 @@ const config = {
distDir: "out",
pageExtensions: ["mdx", "ts", "tsx"],
compiler: {
- styledComponents: true,
+ styledComponents: {
+ ssr: true,
+ displayName: true,
+ },
},
- ...(process.env.NODE_ENV === "production"
- ? {
- output: "export", // static export for production build
- }
- : {}),
+ output: "export",
+
// If localhost proxy is required (e.g. for CORS), uncomment this
// async rewrites() {
// return [