diff --git a/app/components/calculator.tsx b/app/components/calculator.tsx
new file mode 100644
index 0000000..dc094ed
--- /dev/null
+++ b/app/components/calculator.tsx
@@ -0,0 +1,217 @@
+import { ValidatedForm } from "remix-validated-form";
+import { withZod } from "@remix-validated-form/with-zod";
+import { z } from "zod";
+import { useIsSubmitting } from "remix-validated-form";
+import { useField } from "remix-validated-form";
+import { useState, useEffect } from "react";
+
+/*------------------------------------------
+    HELPER FUNCTIONS
+  ------------------------------------------ */
+// NOTE: I decided to try out remix-validated-form because of it's simplicity and ease for validation. I originally used 'useActionData();' to do server-side validation, but ran into some issues due to returning a JSON response instead of a redirect, which caused the app to stay on the action's route.
+
+const validator = withZod(
+    z.object({
+        name: z.string().min(1, { message: "First name is required" }),
+        email: z.string().min(1, { message: "Email is required" }).email("Must be a valid email"),
+        averageProgramsPerMonth: z.string().min(1, { message: "Average Number of Programs Per Month is required" }),
+        averageLengthOfProgramsInHours: z
+            .string()
+            .min(1, { message: "Average Length Of Programs In Hours is required" }),
+    })
+);
+
+/*------------------------------------------
+        JSX ELEMENTS
+  ------------------------------------------ */
+const SubmitButton = () => {
+    const isSubmitting = useIsSubmitting();
+    return (
+        <button type="submit" disabled={isSubmitting} className="rounded-full bg-logo-green text-white p-2 px-4">
+            {isSubmitting ? "CALCULATING..." : "CALCULATE"}
+        </button>
+    );
+};
+
+type TextInputProps = {
+    name: string;
+    label: string;
+    type: string;
+};
+
+// NOTE: remix-validated-form helped me to reduce my code quite a bit by being able to reuse a single component for both inputs and error handling. It was easy to customize the styles in one place as well.
+const TextInput = ({ name, label, type }: TextInputProps) => {
+    const { error, getInputProps } = useField(name);
+    const [borderColor, setBorderColor] = useState("medium-grey");
+
+    useEffect(() => {
+        error ? setBorderColor("red-500") : setBorderColor("medium-grey");
+    }, [error]);
+
+    return (
+        <div className="sm:flex sm:grow">
+            <label className="sm:mr-4 flex items-center sm:flex-nowrap" htmlFor={name}>
+                {label}
+            </label>
+            <input
+                className={`rounded-3xl border-4 border-${borderColor} py-px pl-1.5 text-center w-full max-w-sm`}
+                {...getInputProps({
+                    id: name,
+                    type: type,
+                })}
+            />
+            {error && <div className="text-red-500 text-sm pl-2">*{error}</div>}
+        </div>
+    );
+};
+
+export default function Calculator() {
+    // NOTE: I wasn't sure if you wanted the calculation to occur in the backend or frontend. I chose the frontend since it wasn't a complex function, and didn't slow down the the user's experience.
+    const [yearlyCaptionMins, setYearlyCaptionMins] = useState(0);
+
+    const calculateCaptions = (form) => {
+        const averageProgramsPerMonth = form.averageProgramsPerMonth;
+        const averageLengthOfProgramsInHours = form.averageLengthOfProgramsInHours;
+        setYearlyCaptionMins(averageProgramsPerMonth * averageLengthOfProgramsInHours * 60);
+    };
+
+    const CalculatorForm = () => {
+        return (
+            <ValidatedForm
+                validator={validator}
+                action="/api/leads"
+                method="POST"
+                className="text-2xl"
+                onSubmit={calculateCaptions}
+            >
+                <div className="flex justify-start items-center flex-wrap sm:flex-nowrap">
+                    <svg
+                        xmlns="http://www.w3.org/2000/svg"
+                        fill="none"
+                        viewBox="0 0 24 24"
+                        strokeWidth={1.5}
+                        stroke="#26A35C"
+                        className="w-10 h-10 mr-4 hidden sm:block"
+                    >
+                        <path
+                            strokeLinecap="round"
+                            strokeLinejoin="round"
+                            d="M17.982 18.725A7.488 7.488 0 0012 15.75a7.488 7.488 0 00-5.982 2.975m11.963 0a9 9 0 10-11.963 0m11.963 0A8.966 8.966 0 0112 21a8.966 8.966 0 01-5.982-2.275M15 9.75a3 3 0 11-6 0 3 3 0 016 0z"
+                        />
+                    </svg>
+                    <TextInput name="name" label="Name:" type="text" />
+                </div>
+                <div className="flex justify-start items-center flex-wrap sm:flex-nowrap my-6">
+                    <svg
+                        xmlns="http://www.w3.org/2000/svg"
+                        fill="none"
+                        viewBox="0 0 24 24"
+                        strokeWidth={1.5}
+                        stroke="#26A35C"
+                        className="w-10 h-10 mr-4 hidden sm:block"
+                    >
+                        <path
+                            strokeLinecap="round"
+                            d="M16.5 12a4.5 4.5 0 11-9 0 4.5 4.5 0 019 0zm0 0c0 1.657 1.007 3 2.25 3S21 13.657 21 12a9 9 0 10-2.636 6.364M16.5 12V8.25"
+                        />
+                    </svg>
+                    <TextInput name="email" label="Email:" type="text" />
+                </div>
+                <div className="flex justify-start items-center flex-wrap sm:flex-nowrap my-6">
+                    <svg
+                        xmlns="http://www.w3.org/2000/svg"
+                        fill="none"
+                        viewBox="0 0 24 24"
+                        strokeWidth={1.5}
+                        stroke="#26A35C"
+                        className="w-10 h-10 mr-4 hidden sm:block"
+                    >
+                        <path
+                            strokeLinecap="round"
+                            strokeLinejoin="round"
+                            d="M5.25 8.25h15m-16.5 7.5h15m-1.8-13.5l-3.9 19.5m-2.1-19.5l-3.9 19.5"
+                        />
+                    </svg>
+                    <TextInput
+                        name="averageProgramsPerMonth"
+                        label="Average Number of Programs Per Month:"
+                        type="number"
+                    />
+                </div>
+                <div className="flex justify-start items-center flex-wrap sm:flex-nowrap my-6">
+                    <svg
+                        xmlns="http://www.w3.org/2000/svg"
+                        fill="none"
+                        viewBox="0 0 24 24"
+                        strokeWidth={1.5}
+                        stroke="#26A35C"
+                        className="w-10 h-10 mr-4 hidden sm:block"
+                    >
+                        <path
+                            strokeLinecap="round"
+                            strokeLinejoin="round"
+                            d="M12 6v6h4.5m4.5 0a9 9 0 11-18 0 9 9 0 0118 0z"
+                        />
+                    </svg>
+                    <TextInput
+                        name="averageLengthOfProgramsInHours"
+                        label="Average Length Of Programs In Hours:"
+                        type="number"
+                    />
+                </div>
+                <div className="flex justify-start items-center flex-wrap sm:flex-nowrap my-6">
+                    <svg
+                        xmlns="http://www.w3.org/2000/svg"
+                        fill="none"
+                        viewBox="0 0 24 24"
+                        strokeWidth={1.5}
+                        stroke="#26A35C"
+                        className="w-10 h-10 mr-4 hidden sm:block"
+                    >
+                        <path
+                            strokeLinecap="round"
+                            strokeLinejoin="round"
+                            d="M12 21a9.004 9.004 0 008.716-6.747M12 21a9.004 9.004 0 01-8.716-6.747M12 21c2.485 0 4.5-4.03 4.5-9S14.485 3 12 3m0 18c-2.485 0-4.5-4.03-4.5-9S9.515 3 12 3m0 0a8.997 8.997 0 017.843 4.582M12 3a8.997 8.997 0 00-7.843 4.582m15.686 0A11.953 11.953 0 0112 10.5c-2.998 0-5.74-1.1-7.843-2.918m15.686 0A8.959 8.959 0 0121 12c0 .778-.099 1.533-.284 2.253m0 0A17.919 17.919 0 0112 16.5c-3.162 0-6.133-.815-8.716-2.247m0 0A9.015 9.015 0 013 12c0-1.605.42-3.113 1.157-4.418"
+                        />
+                    </svg>
+                    <span className="ml-3 mr-4  text-gray-900 dark:text-gray-300">Do You Need Translations?</span>
+                    <label className="relative inline-flex items-center cursor-pointer my-0 mx-auto sm:ml-0">
+                        <input
+                            type="checkbox"
+                            className="sr-only peer"
+                            id="needsTranslations"
+                            name="needsTranslations"
+                        />
+                        <div className="w-11 h-6 bg-gray-200 rounded-full peer peer-focus:ring-1 peer-focus:ring-logo-green dark:peer-focus:ring-logo-green dark:bg-gray-700 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-0.5 after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-logo-green"></div>
+                    </label>
+                </div>
+                <div className="text-center">
+                    <SubmitButton />
+                </div>
+            </ValidatedForm>
+        );
+    };
+    const CalculatorResults = () => {
+        return (
+            <>
+                <h1 className="text-2xl text-center">You will need approximately</h1>
+                <div className="text-center my-8">
+                    <input
+                        id="closedCaptioning"
+                        className="rounded-3xl border-4 border-medium-grey py-2 pl-1.5 text-center bg-white"
+                        value={yearlyCaptionMins}
+                        readOnly={true}
+                        disabled={true}
+                    />
+                </div>
+                <h2 className="text-2xl text-center">Of Closed Captioning Minutes for 1 year</h2>
+            </>
+        );
+    };
+
+    return (
+        <div className="bg-light-grey container mx-auto rounded-3xl lg:w-7/12 w-11/12 p-10 lg:pl-14 pl-4 mt-6 lg:mb-10">
+            {yearlyCaptionMins === 0 ? <CalculatorForm /> : <CalculatorResults />}
+        </div>
+    );
+}
diff --git a/app/components/navigation.tsx b/app/components/navigation.tsx
new file mode 100644
index 0000000..71744be
--- /dev/null
+++ b/app/components/navigation.tsx
@@ -0,0 +1,88 @@
+import logo from "../../public/cablecast-logo.png";
+import { useState } from "react";
+
+export default function Navigation() {
+    const [navbar, setNavbar] = useState(false);
+    return (
+        <nav className="flex items-center md:justify-between justify-center flex-wrap bg-dark-grey p-6 lg:px-64 text-xl border-b-8 border-logo-green">
+            <img src={logo} className="mx-10 sm:mx-0" />
+            <div className="md:hidden flex items-center">
+                <button className="outline-none" onClick={() => setNavbar(!navbar)}>
+                    <svg
+                        className="w-6 h-6 text-gray-500"
+                        x-show="! showMenu"
+                        fill="none"
+                        strokeLinecap="round"
+                        strokeLinejoin="round"
+                        strokeWidth="2"
+                        viewBox="0 00 24 24"
+                        stroke="white"
+                    >
+                        <path d="m4 6h16M4 12h16M4 18h16"></path>
+                    </svg>
+                </button>
+            </div>
+            <div>
+                <a
+                    href="/"
+                    className={`block mt-4 md:inline-block md:mt-0 text-white mr-4 ${navbar ? "block" : "hidden"}`}
+                >
+                    Products
+                </a>
+                <a
+                    href="/"
+                    className={`block mt-4 md:inline-block md:mt-0 text-white mr-4 ${navbar ? "block" : "hidden"}`}
+                >
+                    Services & Add Ons
+                </a>
+                <a
+                    href="/"
+                    className={`block mt-4 md:inline-block md:mt-0 text-white mr-4 ${navbar ? "block" : "hidden"}`}
+                >
+                    Support
+                </a>
+                <a
+                    href="/"
+                    className={`block mt-4 md:inline-block md:mt-0 text-white mr-4 ${navbar ? "block" : "hidden"}`}
+                >
+                    News & Resources
+                </a>
+                <a
+                    href="/"
+                    className={`block mt-4 md:inline-block md:mt-0 text-white mr-4 ${navbar ? "block" : "hidden"}`}
+                >
+                    About Us
+                </a>
+            </div>
+            <div className="md:flex hidden">
+                {/* Twitter */}
+                <a href="/">
+                    <svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5 mx-2" fill="white" viewBox="0 0 24 24">
+                        <path d="M24 4.557c-.883.392-1.832.656-2.828.775 1.017-.609 1.798-1.574 2.165-2.724-.951.564-2.005.974-3.127 1.195-.897-.957-2.178-1.555-3.594-1.555-3.179 0-5.515 2.966-4.797 6.045-4.091-.205-7.719-2.165-10.148-5.144-1.29 2.213-.669 5.108 1.523 6.574-.806-.026-1.566-.247-2.229-.616-.054 2.281 1.581 4.415 3.949 4.89-.693.188-1.452.232-2.224.084.626 1.956 2.444 3.379 4.6 3.419-2.07 1.623-4.678 2.348-7.29 2.04 2.179 1.397 4.768 2.212 7.548 2.212 9.142 0 14.307-7.721 13.995-14.646.962-.695 1.797-1.562 2.457-2.549z" />
+                    </svg>
+                </a>
+                {/* Facebook */}
+                <a href="/">
+                    <svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5 mx-2" fill="white" viewBox="0 0 24 24">
+                        <path d="M9 8h-3v4h3v12h5v-12h3.642l.358-4h-4v-1.667c0-.955.192-1.333 1.115-1.333h2.885v-5h-3.808c-3.596 0-5.192 1.583-5.192 4.615v3.385z" />
+                    </svg>
+                </a>
+                {/* Linkedin  */}
+                <a href="/">
+                    <svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5 mx-2" fill="white" viewBox="0 0 24 24">
+                        <path d="M4.98 3.5c0 1.381-1.11 2.5-2.48 2.5s-2.48-1.119-2.48-2.5c0-1.38 1.11-2.5 2.48-2.5s2.48 1.12 2.48 2.5zm.02 4.5h-5v16h5v-16zm7.982 0h-4.968v16h4.969v-8.399c0-4.67 6.029-5.052 6.029 0v8.399h4.988v-10.131c0-7.88-8.922-7.593-11.018-3.714v-2.155z" />
+                    </svg>
+                </a>
+            </div>
+            <div>
+                <a
+                    href="#"
+                    className="lg:block hidden
+                     text-base p-4 leading-none border border-cta-blue rounded text-white bg-cta-blue mt-4 md:mt-0 font-bold"
+                >
+                    GET IN TOUCH
+                </a>
+            </div>
+        </nav>
+    );
+}
diff --git a/app/root.tsx b/app/root.tsx
index 81181cc..58c58e8 100644
--- a/app/root.tsx
+++ b/app/root.tsx
@@ -1,35 +1,30 @@
 import type { LinksFunction } from "@remix-run/node";
-import {
-  Links,
-  LiveReload,
-  Meta,
-  Outlet,
-  Scripts,
-  ScrollRestoration,
-} from "@remix-run/react";
+import { Links, LiveReload, Meta, Outlet, Scripts, ScrollRestoration } from "@remix-run/react";
 
 import stylesheet from "~/tailwind.css";
 
-
 export const links: LinksFunction = () => [
-  { rel: "stylesheet", href: stylesheet },
+    { rel: "stylesheet", href: stylesheet },
+    { rel: "preconnect", href: "https://fonts.googleapis.com" },
+    { rel: "preconnect", href: "https://fonts.gstatic.com" },
+    { rel: "stylesheet", href: "https://fonts.googleapis.com/css2?family=Nunito+Sans:wght@300&display=swap" },
 ];
 
 export default function App() {
-  return (
-    <html lang="en">
-      <head>
-        <meta charSet="utf-8" />
-        <meta name="viewport" content="width=device-width,initial-scale=1" />
-        <Meta />
-        <Links />
-      </head>
-      <body>
-        <Outlet />
-        <ScrollRestoration />
-        <Scripts />
-        <LiveReload />
-      </body>
-    </html>
-  );
+    return (
+        <html lang="en">
+            <head>
+                <meta charSet="utf-8" />
+                <meta name="viewport" content="width=device-width,initial-scale=1" />
+                <Meta />
+                <Links />
+            </head>
+            <body>
+                <Outlet />
+                <ScrollRestoration />
+                <Scripts />
+                <LiveReload />
+            </body>
+        </html>
+    );
 }
diff --git a/app/routes/_index.tsx b/app/routes/_index.tsx
index 64163f8..b3f37da 100644
--- a/app/routes/_index.tsx
+++ b/app/routes/_index.tsx
@@ -1,23 +1,41 @@
 import type { V2_MetaFunction } from "@remix-run/node";
+import ccImage from "../../public/cc-img.png";
+import Navigation from "../components/navigation";
+import Calculator from "../components/calculator";
 
 export const meta: V2_MetaFunction = () => {
-  return [
-    { title: "New Remix App" },
-    { name: "description", content: "Welcome to Remix!" },
-  ];
+    return [
+        { title: "Captioning Calculator" },
+        {
+            name: "description",
+            content:
+                "A prototype of a closed caption calculator that can be used to capture leads for a Closed Captioning Project",
+        },
+    ];
 };
 
 export default function Index() {
-  return (
-    <div>
-      <h1 className="text-3xl font-bold underline">Hello world!</h1>
-      {/*  
-        // Use the form below if you wan to go remix style, or just use fetch in an event handler. 
-      */}
-      <form action="/api/leads" method="POST">
-        <label htmlFor="name">Name</label>
-        <input id="name" name="name" placeholder="Pat Smith" />
-      </form>
-    </div>
-  );
+    return (
+        <>
+            <Navigation />
+            <div>
+                <h1 className="lg:text-6xl text-3xl text-center lg:my-14 my-10">CAPTIONING CALCULATOR</h1>
+                <div className="grid lg:grid-cols-3 gap-4 lg:mx-80 mx-10">
+                    <div className="lg:col-span-2 lg:mx-24">
+                        <h2 className="lg:text-3xl text-xl font-bold my-8">
+                            How many captioning minutes will you need?
+                        </h2>
+                        <p className="text-xl">
+                            The Cablecast Captioning Calculator is a tool to understand how many cablecast Captioning
+                            Minutes you will need for a year of programming.
+                        </p>
+                    </div>
+                    <div>
+                        <img className="my-0 mx-auto lg:ml-0" src={ccImage} alt="closed captioning image" />
+                    </div>
+                </div>
+            </div>
+            <Calculator />
+        </>
+    );
 }
diff --git a/app/routes/api.leads.tsx b/app/routes/api.leads.tsx
index 4fa1b24..14ec039 100644
--- a/app/routes/api.leads.tsx
+++ b/app/routes/api.leads.tsx
@@ -9,16 +9,7 @@ interface Lead {
     needsTranslations: boolean;
 }
 
-export async function action( { request }: ActionArgs) {
-    
-    try {
-        const requestJson = request.clone();
-        const jsonData = await requestJson.json();
-        return await handleJsonBody(jsonData);
-    } catch {
-        // Nothing todo here. Just try form data next.
-    }
-
+export async function action({ request }: ActionArgs) {
     try {
         const requestFormData = request.clone();
         const formData = await requestFormData.formData();
@@ -27,40 +18,33 @@ export async function action( { request }: ActionArgs) {
         // Nothing todo here. We'll error before
     }
 
-    throw json({ message: "Unsupported content type. Supported values are application/json and application/x-www-form-urlencoded."}, {status: 401});
-}
-
-async function handleJsonBody(jsonData: any) {
-    const lead: Lead = {
-        name: jsonData.name,
-        email: jsonData.email,
-        averageProgramsPerMonth: jsonData.averageProgramsPerMonth,
-        averageLengthOfProgramsInHours: jsonData.averageLengthOfProgramsInHours,
-        needsTranslations: jsonData.needsTranslations
-    };
-    saveLead(lead);
-    return json({json: 'ok', lead})
+    throw json(
+        {
+            message:
+                "Unsupported content type. Supported values are application/json and application/x-www-form-urlencoded.",
+        },
+        { status: 401 }
+    );
 }
 
 async function handleFormData(formData: FormData) {
-    const name = formData.get('name') as string;
-    const email = formData.get('email') as string;
-    const averageProgramsPerMonth = Number(formData.get('averageProgramsPerMonth')) ?? 0;
-    const averageLengthOfProgramsInHours = Number(formData.get('averageLengthOfProgramsInHours')) ?? 0;
-    const needsTranslations = formData.get('needsTranslations') == "YES";
+    const name = formData.get("name") as string;
+    const email = formData.get("email") as string;
+    const averageProgramsPerMonth = Number(formData.get("averageProgramsPerMonth")) ?? 0;
+    const averageLengthOfProgramsInHours = Number(formData.get("averageLengthOfProgramsInHours")) ?? 0;
+    const needsTranslations = formData.get("needsTranslations") == "on";
     const lead: Lead = {
         name,
         email,
         averageProgramsPerMonth,
         averageLengthOfProgramsInHours,
-        needsTranslations
+        needsTranslations,
     };
-    await saveLead(lead);
-    return redirect('/');
 
+    await saveLead(lead);
+    return redirect("/");
 }
 
 async function saveLead(lead: Lead) {
     console.log(lead);
 }
-
diff --git a/app/tailwind.css b/app/tailwind.css
index bd6213e..2e8dba0 100644
--- a/app/tailwind.css
+++ b/app/tailwind.css
@@ -1,3 +1,9 @@
 @tailwind base;
 @tailwind components;
-@tailwind utilities;
\ No newline at end of file
+@tailwind utilities;
+
+@layer base {
+    html {
+        font-family: "Nunito Sans", sans-serif;
+    }
+}
diff --git a/package-lock.json b/package-lock.json
index ff8abab..dcd0258 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,5 +1,5 @@
 {
-  "name": "web-dev-hw",
+  "name": "captioning-calculator",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
@@ -9,9 +9,11 @@
         "@remix-run/node": "^1.17.1",
         "@remix-run/react": "^1.17.1",
         "@remix-run/serve": "^1.17.1",
+        "@remix-validated-form/with-zod": "^2.0.6",
         "isbot": "^3.6.8",
         "react": "^18.2.0",
-        "react-dom": "^18.2.0"
+        "react-dom": "^18.2.0",
+        "remix-validated-form": "^5.0.2"
       },
       "devDependencies": {
         "@remix-run/dev": "^1.17.1",
@@ -3012,6 +3014,15 @@
         "web-streams-polyfill": "^3.1.1"
       }
     },
+    "node_modules/@remix-validated-form/with-zod": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/@remix-validated-form/with-zod/-/with-zod-2.0.6.tgz",
+      "integrity": "sha512-i8H0PPFSSKIMGPVO/8cUMO1QoGa2bBQZb6RH3DoXGVE1heu52d1vwrFVsYYQB8Vc8lp5BGQk1kbxZuN9RzH1OA==",
+      "peerDependencies": {
+        "remix-validated-form": "^4.x || ^5.x",
+        "zod": "^3.11.x"
+      }
+    },
     "node_modules/@rollup/pluginutils": {
       "version": "4.2.1",
       "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz",
@@ -7488,6 +7499,15 @@
         "node": ">= 4"
       }
     },
+    "node_modules/immer": {
+      "version": "9.0.21",
+      "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz",
+      "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==",
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/immer"
+      }
+    },
     "node_modules/import-fresh": {
       "version": "3.3.0",
       "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
@@ -8369,6 +8389,11 @@
       "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==",
       "dev": true
     },
+    "node_modules/lodash.get": {
+      "version": "4.4.2",
+      "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
+      "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ=="
+    },
     "node_modules/lodash.merge": {
       "version": "4.6.2",
       "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
@@ -9589,7 +9614,6 @@
       "version": "3.3.6",
       "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
       "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
-      "dev": true,
       "funding": [
         {
           "type": "github",
@@ -10993,6 +11017,29 @@
         "url": "https://opencollective.com/unified"
       }
     },
+    "node_modules/remeda": {
+      "version": "1.23.0",
+      "resolved": "https://registry.npmjs.org/remeda/-/remeda-1.23.0.tgz",
+      "integrity": "sha512-1y0jygsAc3opoFQW5BtA/QYOboai0u5IwdvwtbRAd1eJ2D9NmvZpDfV819LdSmrIQ0LONbp/dE9Uo/rGxUshPw=="
+    },
+    "node_modules/remix-validated-form": {
+      "version": "5.0.2",
+      "resolved": "https://registry.npmjs.org/remix-validated-form/-/remix-validated-form-5.0.2.tgz",
+      "integrity": "sha512-jM3uuvCP6AO9G117MAEGgTb3x/aOy5qVrOM85XdDhWnpJFt7WC6u1gBQ/tSd1UBCTxDSFwU6TZPCJex73D9rjQ==",
+      "dependencies": {
+        "immer": "^9.0.12",
+        "lodash.get": "^4.4.2",
+        "nanoid": "3.3.6",
+        "remeda": "^1.2.0",
+        "tiny-invariant": "^1.2.0",
+        "zustand": "^4.3.0"
+      },
+      "peerDependencies": {
+        "@remix-run/react": ">= 1.15.0",
+        "@remix-run/server-runtime": "1.x",
+        "react": "^17.0.2 || ^18.0.0"
+      }
+    },
     "node_modules/require-like": {
       "version": "0.1.2",
       "resolved": "https://registry.npmjs.org/require-like/-/require-like-0.1.2.tgz",
@@ -12068,6 +12115,11 @@
         "safe-buffer": "~5.1.0"
       }
     },
+    "node_modules/tiny-invariant": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.1.tgz",
+      "integrity": "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw=="
+    },
     "node_modules/titleize": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/titleize/-/titleize-3.0.0.tgz",
@@ -12546,6 +12598,14 @@
         "punycode": "^2.1.0"
       }
     },
+    "node_modules/use-sync-external-store": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz",
+      "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==",
+      "peerDependencies": {
+        "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+      }
+    },
     "node_modules/util": {
       "version": "0.12.5",
       "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz",
@@ -12993,6 +13053,38 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/zod": {
+      "version": "3.21.4",
+      "resolved": "https://registry.npmjs.org/zod/-/zod-3.21.4.tgz",
+      "integrity": "sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw==",
+      "peer": true,
+      "funding": {
+        "url": "https://github.com/sponsors/colinhacks"
+      }
+    },
+    "node_modules/zustand": {
+      "version": "4.3.8",
+      "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.3.8.tgz",
+      "integrity": "sha512-4h28KCkHg5ii/wcFFJ5Fp+k1J3gJoasaIbppdgZFO4BPJnsNxL0mQXBSFgOgAdCdBj35aDTPvdAJReTMntFPGg==",
+      "dependencies": {
+        "use-sync-external-store": "1.2.0"
+      },
+      "engines": {
+        "node": ">=12.7.0"
+      },
+      "peerDependencies": {
+        "immer": ">=9.0",
+        "react": ">=16.8"
+      },
+      "peerDependenciesMeta": {
+        "immer": {
+          "optional": true
+        },
+        "react": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/zwitch": {
       "version": "2.0.4",
       "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz",
diff --git a/package.json b/package.json
index 376c099..4866b68 100644
--- a/package.json
+++ b/package.json
@@ -13,9 +13,11 @@
     "@remix-run/node": "^1.17.1",
     "@remix-run/react": "^1.17.1",
     "@remix-run/serve": "^1.17.1",
+    "@remix-validated-form/with-zod": "^2.0.6",
     "isbot": "^3.6.8",
     "react": "^18.2.0",
-    "react-dom": "^18.2.0"
+    "react-dom": "^18.2.0",
+    "remix-validated-form": "^5.0.2"
   },
   "devDependencies": {
     "@remix-run/dev": "^1.17.1",
diff --git a/public/cablecast-logo.png b/public/cablecast-logo.png
new file mode 100644
index 0000000..4c61601
Binary files /dev/null and b/public/cablecast-logo.png differ
diff --git a/public/cc-img.png b/public/cc-img.png
new file mode 100644
index 0000000..eee29fa
Binary files /dev/null and b/public/cc-img.png differ
diff --git a/public/favicon.ico b/public/favicon.ico
index 8830cf6..8a70edd 100644
Binary files a/public/favicon.ico and b/public/favicon.ico differ
diff --git a/tailwind.config.ts b/tailwind.config.ts
index 3a1b56f..734e4af 100644
--- a/tailwind.config.ts
+++ b/tailwind.config.ts
@@ -1,10 +1,17 @@
-import type { Config } from 'tailwindcss'
+import type { Config } from "tailwindcss";
 
 export default {
-  content: ['./app/**/*.{js,jsx,ts,tsx}'],
-  theme: {
-    extend: {},
-  },
-  plugins: [],
-} satisfies Config
-
+    content: ["./app/**/*.{js,jsx,ts,tsx}"],
+    theme: {
+        extend: {
+            colors: {
+                "dark-grey": "#535B6F",
+                "cta-blue": "#2F87CA",
+                "logo-green": "#26A35C",
+                "light-grey": "#EDEEF1",
+                "medium-grey": "#8E98A9",
+            },
+        },
+    },
+    plugins: [],
+} satisfies Config;
diff --git a/tsconfig.json b/tsconfig.json
index 20f8a38..ecae7d6 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,22 +1,23 @@
 {
-  "include": ["remix.env.d.ts", "**/*.ts", "**/*.tsx"],
-  "compilerOptions": {
-    "lib": ["DOM", "DOM.Iterable", "ES2019"],
-    "isolatedModules": true,
-    "esModuleInterop": true,
-    "jsx": "react-jsx",
-    "moduleResolution": "node",
-    "resolveJsonModule": true,
-    "target": "ES2019",
-    "strict": true,
-    "allowJs": true,
-    "forceConsistentCasingInFileNames": true,
-    "baseUrl": ".",
-    "paths": {
-      "~/*": ["./app/*"]
-    },
+    "include": ["remix.env.d.ts", "**/*.ts", "**/*.tsx"],
+    "compilerOptions": {
+        "lib": ["DOM", "DOM.Iterable", "ES2019"],
+        "noImplicitAny": false,
+        "isolatedModules": true,
+        "esModuleInterop": true,
+        "jsx": "react-jsx",
+        "moduleResolution": "node",
+        "resolveJsonModule": true,
+        "target": "ES2019",
+        "strict": true,
+        "allowJs": true,
+        "forceConsistentCasingInFileNames": true,
+        "baseUrl": ".",
+        "paths": {
+            "~/*": ["./app/*"]
+        },
 
-    // Remix takes care of building everything in `remix build`.
-    "noEmit": true
-  }
+        // Remix takes care of building everything in `remix build`.
+        "noEmit": true
+    }
 }