diff --git a/assets/aws_logo.svg b/assets/aws_logo.svg
new file mode 100644
index 00000000..42455e44
--- /dev/null
+++ b/assets/aws_logo.svg
@@ -0,0 +1,9 @@
+
diff --git a/assets/civo_logo.svg b/assets/civo_logo.svg
new file mode 100644
index 00000000..240778b3
--- /dev/null
+++ b/assets/civo_logo.svg
@@ -0,0 +1,9 @@
+
diff --git a/assets/digital_ocean_logo.svg b/assets/digital_ocean_logo.svg
new file mode 100644
index 00000000..d22aff82
--- /dev/null
+++ b/assets/digital_ocean_logo.svg
@@ -0,0 +1,9 @@
+
diff --git a/assets/k3d_logo.svg b/assets/k3d_logo.svg
new file mode 100644
index 00000000..097f6810
--- /dev/null
+++ b/assets/k3d_logo.svg
@@ -0,0 +1,16 @@
+
diff --git a/assets/vultr_logo.svg b/assets/vultr_logo.svg
new file mode 100644
index 00000000..37178640
--- /dev/null
+++ b/assets/vultr_logo.svg
@@ -0,0 +1,13 @@
+
diff --git a/components/card/Card.stories.tsx b/components/card/Card.stories.tsx
new file mode 100644
index 00000000..fc918a29
--- /dev/null
+++ b/components/card/Card.stories.tsx
@@ -0,0 +1,25 @@
+import React from 'react';
+import { Story } from '@storybook/react';
+
+import Card, { CardProps } from './Card';
+
+export default {
+ title: 'Components/Card',
+ component: Card,
+ argTypes: {
+ active: {
+ control: 'boolean',
+ defaultValue: false,
+ },
+ withHoverEffect: {
+ control: 'boolean',
+ defaultValue: false,
+ },
+ },
+};
+
+const DefaultTemplate: Story = (args) => (
+
+);
+
+export const Default = DefaultTemplate.bind({});
diff --git a/components/card/Card.styled.tsx b/components/card/Card.styled.tsx
new file mode 100644
index 00000000..f0026c43
--- /dev/null
+++ b/components/card/Card.styled.tsx
@@ -0,0 +1,24 @@
+import styled, { css } from 'styled-components';
+
+import { CardProps } from './Card';
+
+export const CardContainer = styled.div`
+ border: 2px solid #e2e8f0;
+ border-radius: 8px;
+ background-color: white;
+ cursor: pointer;
+
+ ${({ withHoverEffect }) =>
+ withHoverEffect &&
+ css`
+ &:hover {
+ border-color: ${({ theme }) => theme.colors.primary};
+ }
+ `}
+
+ ${({ active, theme }) =>
+ active &&
+ css`
+ border-color: ${theme.colors.primary};
+ `}
+`;
diff --git a/components/card/Card.tsx b/components/card/Card.tsx
new file mode 100644
index 00000000..cdfa9365
--- /dev/null
+++ b/components/card/Card.tsx
@@ -0,0 +1,15 @@
+import React, { ComponentPropsWithoutRef, FC } from 'react';
+import styled from 'styled-components';
+
+import { CardContainer } from './Card.styled';
+
+export interface CardProps extends ComponentPropsWithoutRef<'div'> {
+ active?: boolean;
+ withHoverEffect?: boolean;
+}
+
+const Card: FC = ({ children, ...rest }) => (
+ {children}
+);
+
+export default styled(Card)``;
diff --git a/components/cloudProviderCard/CloudProviderCard.stories.tsx b/components/cloudProviderCard/CloudProviderCard.stories.tsx
new file mode 100644
index 00000000..c55e244f
--- /dev/null
+++ b/components/cloudProviderCard/CloudProviderCard.stories.tsx
@@ -0,0 +1,30 @@
+import React from 'react';
+import { Story } from '@storybook/react';
+
+import { InstallationType } from '../../types';
+
+import CloudProviderCard, { CloudProviderCardProps } from './CloudProviderCard';
+
+export default {
+ title: 'Components/CloudProviderCard',
+ component: CloudProviderCard,
+ argTypes: {
+ option: {
+ control: 'select',
+ options: InstallationType,
+ defaultValue: InstallationType.LOCAL,
+ },
+ active: {
+ control: 'boolean',
+ defaultValue: false,
+ },
+ withHoverEffect: {
+ control: 'boolean',
+ defaultValue: true,
+ },
+ },
+};
+
+const DefaultTemplate: Story = (args) => ;
+
+export const Default = DefaultTemplate.bind({});
diff --git a/components/cloudProviderCard/CloudProviderCard.styled.tsx b/components/cloudProviderCard/CloudProviderCard.styled.tsx
new file mode 100644
index 00000000..021f7ad8
--- /dev/null
+++ b/components/cloudProviderCard/CloudProviderCard.styled.tsx
@@ -0,0 +1,32 @@
+import styled from 'styled-components';
+
+import Card from '../card/Card';
+
+export const LabelContainer = styled.div`
+ display: flex;
+ gap: 16px;
+`;
+
+export const DetailsContainer = styled.div`
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+ margin-left: 24px;
+
+ p {
+ margin-top: 4px;
+ color: ${({ theme }) => theme.colors.saltboxBlue};
+ }
+`;
+
+export const LinkContent = styled.a`
+ text-decoration: none;
+ color: ${({ theme }) => theme.colors.primary};
+`;
+
+export const CardContainer = styled(Card)`
+ display: flex;
+ align-items: center;
+ width: 540px;
+ padding: 24px;
+`;
diff --git a/components/cloudProviderCard/CloudProviderCard.tsx b/components/cloudProviderCard/CloudProviderCard.tsx
new file mode 100644
index 00000000..d0532846
--- /dev/null
+++ b/components/cloudProviderCard/CloudProviderCard.tsx
@@ -0,0 +1,113 @@
+import React, { FC } from 'react';
+import styled from 'styled-components';
+import Image from 'next/image';
+import Link from 'next/link';
+
+import { CardProps } from '../card/Card';
+import Typography from '../typography';
+import { InstallationType } from '../../types';
+import k3dLogo from '../../assets/k3d_logo.svg';
+import awsLogo from '../../assets/aws_logo.svg';
+import civoLogo from '../../assets/civo_logo.svg';
+import digitalOceanLogo from '../../assets/digital_ocean_logo.svg';
+import vultrLogo from '../../assets/vultr_logo.svg';
+import Tag from '../tag/Tag';
+
+import {
+ CardContainer,
+ DetailsContainer,
+ LinkContent,
+ LabelContainer,
+} from './CloudProviderCard.styled';
+
+const PROVIDER_OPTIONS: Record<
+ InstallationType,
+ {
+ logoSrc: any;
+ label: string;
+ description: string;
+ height: number;
+ width: number;
+ learnMoreLink?: string;
+ beta?: boolean;
+ }
+> = {
+ [InstallationType.LOCAL]: {
+ logoSrc: k3dLogo,
+ label: 'Run Locally',
+ description:
+ 'The fastest way to explore all you can do with Kubefirst. Run Kubefirst for free on a local K3D cluster in less than 5 minutes - without any cloud costs or domain prerequisites.',
+ height: 88,
+ width: 50,
+ },
+ [InstallationType.AWS]: {
+ logoSrc: awsLogo,
+ label: 'AWS',
+ description:
+ 'Our AWS cloud platform can accommodate all of the needs of your enterprise and leverages the free Github system at github.com.',
+ height: 30,
+ width: 50,
+ },
+ [InstallationType.CIVO]: {
+ logoSrc: civoLogo,
+ label: 'CIVO',
+ description:
+ 'A powerful open source cloud native tool set for identity and infrastructure management, application delivery, and secrets managament.',
+ height: 17,
+ width: 50,
+ },
+ [InstallationType.DIGITAL_OCEAN]: {
+ logoSrc: digitalOceanLogo,
+ label: 'Digital Ocean',
+ description:
+ 'A powerful open source cloud native tool set for identity and infrastructure management, application delivery, and secrets managament.',
+ height: 50,
+ width: 50,
+ beta: true,
+ },
+ [InstallationType.VULTR]: {
+ logoSrc: vultrLogo,
+ label: 'Vultr',
+ description:
+ 'A powerful open source cloud native tool set for identity and infrastructure management, application delivery, and secrets managament.',
+ learnMoreLink: '#',
+ height: 43,
+ width: 50,
+ beta: true,
+ },
+};
+
+export interface CloudProviderCardProps extends CardProps {
+ option: InstallationType;
+ active?: boolean;
+}
+
+const CloudProviderCard: FC = ({
+ option,
+ withHoverEffect = true,
+ ...rest
+}) => {
+ const { logoSrc, label, description, learnMoreLink, height, width, beta } =
+ PROVIDER_OPTIONS[option];
+ return (
+
+
+
+
+ {label}
+ {beta && }
+
+
+ {description}
+ {learnMoreLink && (
+
+ Learn More
+
+ )}
+
+
+
+ );
+};
+
+export default styled(CloudProviderCard)``;
diff --git a/components/gitProviderButton/GitProviderButton.stories.tsx b/components/gitProviderButton/GitProviderButton.stories.tsx
new file mode 100644
index 00000000..13d7d279
--- /dev/null
+++ b/components/gitProviderButton/GitProviderButton.stories.tsx
@@ -0,0 +1,26 @@
+import React from 'react';
+import { Story } from '@storybook/react';
+
+import { GitProvider } from '../../types';
+
+import GitProviderButton, { GitProviderButtonProps } from './GitProviderButton';
+
+export default {
+ title: 'Components/GitProviderButton',
+ component: GitProviderButton,
+ argTypes: {
+ option: {
+ control: 'select',
+ options: GitProvider,
+ defaultValue: GitProvider.GITHUB,
+ },
+ active: {
+ control: 'boolean',
+ defaultValue: false,
+ },
+ },
+};
+
+const DefaultTemplate: Story = (args) => ;
+
+export const Default = DefaultTemplate.bind({});
diff --git a/components/gitProviderButton/GitProviderButton.styled.tsx b/components/gitProviderButton/GitProviderButton.styled.tsx
new file mode 100644
index 00000000..e0f20ec1
--- /dev/null
+++ b/components/gitProviderButton/GitProviderButton.styled.tsx
@@ -0,0 +1,24 @@
+import styled, { css } from 'styled-components';
+
+export const Button = styled.button<{ active?: boolean }>`
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ width: 260px;
+ height: 88px;
+ border: 2px solid #e2e8f0;
+ border-radius: 8px;
+ background-color: white;
+ cursor: pointer;
+ gap: 24px;
+
+ &:hover {
+ border-color: ${({ theme }) => theme.colors.primary};
+ }
+
+ ${({ active, theme }) =>
+ active &&
+ css`
+ border-color: ${theme.colors.primary};
+ `}
+`;
diff --git a/components/gitProviderButton/GitProviderButton.tsx b/components/gitProviderButton/GitProviderButton.tsx
new file mode 100644
index 00000000..4f079bdf
--- /dev/null
+++ b/components/gitProviderButton/GitProviderButton.tsx
@@ -0,0 +1,35 @@
+import React, { ComponentPropsWithoutRef, FC } from 'react';
+import styled from 'styled-components';
+import Image from 'next/image';
+
+import { GitProvider } from '../../types';
+import gitlabLogo from '../../assets/gitlab.svg';
+import githubLogo from '../../assets/github.svg';
+import Typography from '../typography';
+
+import { Button } from './GitProviderButton.styled';
+
+const PROVIDER_OPTIONS: Record<
+ GitProvider,
+ { logoSrc: any; label: string; height: number; width: number }
+> = {
+ [GitProvider.GITHUB]: { logoSrc: githubLogo, label: 'Github', height: 40, width: 40 },
+ [GitProvider.GITLAB]: { logoSrc: gitlabLogo, label: 'GitLab', height: 40, width: 42 },
+};
+
+export interface GitProviderButtonProps extends ComponentPropsWithoutRef<'button'> {
+ option: GitProvider;
+ active?: boolean;
+}
+
+const GitProviderButton: FC = ({ option, type = 'button', ...rest }) => {
+ const { logoSrc, label, height, width } = PROVIDER_OPTIONS[option];
+ return (
+
+ );
+};
+
+export default styled(GitProviderButton)``;
diff --git a/components/tag/Tag.stories.tsx b/components/tag/Tag.stories.tsx
new file mode 100644
index 00000000..5a290ce7
--- /dev/null
+++ b/components/tag/Tag.stories.tsx
@@ -0,0 +1,22 @@
+import React from 'react';
+import { Story } from '@storybook/react';
+
+import Tag, { TAG_COLOR_OPTIONS, TagProps } from './Tag';
+
+export default {
+ title: 'Components/Tag',
+ component: Tag,
+ argTypes: {
+ bgColor: {
+ control: 'select',
+ options: TAG_COLOR_OPTIONS,
+ },
+ },
+};
+
+const DefaultTemplate: Story = (args) => ;
+
+export const Default = DefaultTemplate.bind({});
+Default.args = {
+ text: 'Tag',
+};
diff --git a/components/tag/Tag.styled.tsx b/components/tag/Tag.styled.tsx
new file mode 100644
index 00000000..c96e4953
--- /dev/null
+++ b/components/tag/Tag.styled.tsx
@@ -0,0 +1,61 @@
+import styled, { css } from 'styled-components';
+
+import Typography, { ITypographyProps } from '../typography';
+
+import { TagColor } from './Tag';
+
+export const TagContainer = styled(Typography)<{ bgColor?: TagColor } & ITypographyProps>`
+ border-radius: 4px;
+ padding: 4px;
+
+ ${({ bgColor }) =>
+ bgColor === 'neon-green'
+ ? css`
+ background-color: #ecfccb;
+ color: #4d7c0f;
+ `
+ : bgColor === 'light-orange'
+ ? css`
+ background-color: #fef3c7;
+ color: #d97706;
+ `
+ : bgColor === 'pink'
+ ? css`
+ background-color: #fce7f3;
+ color: #be185d;
+ `
+ : bgColor === 'light-blue'
+ ? css`
+ background-color: #ecfeff;
+ color: #0e7490;
+ `
+ : bgColor === 'sky-blue'
+ ? css`
+ background-color: #e0f2fe;
+ color: #0369a1;
+ `
+ : bgColor === 'dark-sky-blue'
+ ? css`
+ background-color: #dbeafe;
+ color: #1d4ed8;
+ `
+ : bgColor === 'purple'
+ ? css`
+ background-color: #ede9fe;
+ color: #6d28d9;
+ `
+ : bgColor === 'yellow'
+ ? css`
+ background-color: #fef9c3;
+ color: #a16207;
+ `
+ : bgColor === 'green'
+ ? css`
+ background-color: #d1fae5;
+ color: #059669;
+ `
+ : css`
+ background-color: none;
+ color: #71717a;
+ `}
+`;
diff --git a/components/tag/Tag.tsx b/components/tag/Tag.tsx
new file mode 100644
index 00000000..bf3a5f4b
--- /dev/null
+++ b/components/tag/Tag.tsx
@@ -0,0 +1,31 @@
+import React, { FC } from 'react';
+import styled from 'styled-components';
+
+import { TagContainer } from './Tag.styled';
+
+export const TAG_COLOR_OPTIONS = [
+ 'neon-green',
+ 'light-orange',
+ 'pink',
+ 'light-blue',
+ 'sky-blue',
+ 'dark-sky-blue',
+ 'purple',
+ 'yellow',
+ 'green',
+] as const;
+
+export type TagColor = (typeof TAG_COLOR_OPTIONS)[number];
+
+export interface TagProps {
+ text: string;
+ bgColor?: TagColor;
+}
+
+const Tag: FC = ({ text, ...rest }) => (
+
+ {text}
+
+);
+
+export default styled(Tag)``;