diff --git a/Makefile b/Makefile
index 7d67d252..6d57ac40 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-export NODE_OPTIONS := "--max-old-space-size=4096"
+export NODE_OPTIONS := "--max-old-space-size=8192"
.PHONY: all
all: build
diff --git a/src/components/ActionCard/index.js b/src/components/ActionCard/index.js
new file mode 100644
index 00000000..dc528bfb
--- /dev/null
+++ b/src/components/ActionCard/index.js
@@ -0,0 +1,22 @@
+import clsx from "clsx";
+import React from "react";
+import style from "./styles.module.css";
+
+// skin?: "default" | "primary"
+export const ActionCard = ({ skin = "default", icon, title, description, svgBackgroundColor, children, className }) => {
+ const styles = { background: svgBackgroundColor};
+ return (
+
+
{icon}
+
{title}
+
{description}
+
{children}
+
+ )
+}
+
+export default ActionCard
diff --git a/src/components/ActionCard/styles.module.css b/src/components/ActionCard/styles.module.css
new file mode 100644
index 00000000..8bc5b3de
--- /dev/null
+++ b/src/components/ActionCard/styles.module.css
@@ -0,0 +1,53 @@
+.root {
+ padding: 2rem;
+ border-radius: 16px;
+ background: var(--theme-attention-card-bg-color);
+}
+
+.title {
+ margin-top: 1rem;
+ margin-bottom: 1rem;
+ font-size: var(--font-size-big-1);
+ font-weight: var(--ifm-font-weight-bold);
+}
+
+.description {
+ font-size: var(--font-size-large);
+}
+
+@media screen and (min-width: 880px) {
+ .root {
+ padding: 2rem;
+ }
+
+ .title {
+ font-size: 1.2rem;
+ }
+}
+
+.content {
+ display: flex;
+ flex: 1;
+}
+
+.skinPrimary {
+ background: var(--ifm-color-primary-lighter);
+}
+
+[data-theme='dark'] .skinPrimary {
+ background: var(--ifm-color-primary-darker);
+}
+
+.skinPrimary .title,
+.skinPrimary .description {
+ color: var(--theme-attention-card-text-color);
+}
+
+.icon {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ height: 76px;
+ width: 76px;
+ border-radius: 50%;
+}
diff --git a/src/components/ActionFooter/footer.module.css b/src/components/ActionFooter/footer.module.css
new file mode 100644
index 00000000..34472619
--- /dev/null
+++ b/src/components/ActionFooter/footer.module.css
@@ -0,0 +1,19 @@
+.cards {
+ display: grid;
+ gap: 1.5rem;
+}
+
+.card__link {
+ text-transform: uppercase;
+ font-size: var(--font-size-normal);
+}
+
+.card__link:not(:last-child) {
+ margin-right: 1.5rem;
+}
+
+@media screen and (min-width: 768px) {
+ .cards {
+ grid-template-columns: 1fr 1fr;
+ }
+}
diff --git a/src/components/ActionFooter/foss.svg b/src/components/ActionFooter/foss.svg
new file mode 100644
index 00000000..c1d6e82b
--- /dev/null
+++ b/src/components/ActionFooter/foss.svg
@@ -0,0 +1,4 @@
+
diff --git a/src/components/ActionFooter/index.js b/src/components/ActionFooter/index.js
new file mode 100644
index 00000000..a9b60614
--- /dev/null
+++ b/src/components/ActionFooter/index.js
@@ -0,0 +1,53 @@
+import footerCss from "./footer.module.css";
+import ActionCard from "../ActionCard";
+import FossIcon from "./foss.svg";
+import SubscribeIcon from "./subscribeIcon.svg";
+import Subscribe from "../Subscribe";
+import React from "react";
+import SvgImage from "../SvgImage";
+
+export const ActionFooter = () => (
+
+
}
+ title="An icon showing wave propagation"
+ />
+ }
+ svgBackgroundColor="#ffffff"
+ title="Join our community"
+ description="Gitea is open source. Star our GitHub repo, and join our community on Discord!"
+ >
+
+ Go to GitHub >
+
+
+ Join Discord >
+
+
+
+
}
+ title="An icon showing a paper plane"
+ />
+ }
+ skin="primary"
+ >
+
+
+
+)
diff --git a/src/components/ActionFooter/styles.module.css b/src/components/ActionFooter/styles.module.css
new file mode 100644
index 00000000..37364172
--- /dev/null
+++ b/src/components/ActionFooter/styles.module.css
@@ -0,0 +1,27 @@
+.loader {
+ position: absolute;
+ width: 20px;
+ height: 20px;
+}
+
+.loader:after {
+ content: " ";
+ display: block;
+ width: 14px;
+ height: 14px;
+ margin: 0;
+ border-radius: 50%;
+ border: 3px solid transparent;
+ border-color: var(--ifm-color-white) transparent var(--ifm-color-white)
+ transparent;
+ animation: loader 1.2s linear infinite;
+}
+
+@keyframes loader {
+ 0% {
+ transform: rotate(0deg);
+ }
+ 100% {
+ transform: rotate(360deg);
+ }
+}
diff --git a/src/components/ActionFooter/subscribeIcon.svg b/src/components/ActionFooter/subscribeIcon.svg
new file mode 100644
index 00000000..4024e56b
--- /dev/null
+++ b/src/components/ActionFooter/subscribeIcon.svg
@@ -0,0 +1,5 @@
+
diff --git a/src/components/Button/index.js b/src/components/Button/index.js
new file mode 100644
index 00000000..94bdc4c1
--- /dev/null
+++ b/src/components/Button/index.js
@@ -0,0 +1,66 @@
+import clsx from "clsx";
+import React from "react";
+
+import styles from "./styles.module.css";
+
+const Button = (props) => {
+ const { icon, variant, size, uppercase, className, to, href, children } = props;
+ const classes = clsx(className, styles.button, {
+ [styles["button--icon"]]: icon != null,
+ [styles["button--primary"]]: variant === "primary",
+ [styles["button--secondary"]]: variant === "secondary",
+ [styles["button--small"]]: size === "small",
+ [styles["button--tertiary"]]: variant === "tertiary",
+ [styles["button--plain"]]: variant === "plain",
+ [styles["button--uppercase"]]: uppercase === "true",
+ [styles["button--xsmall"]]: size === "xsmall",
+ [styles["button--xxsmall"]]: size === "xxsmall",
+ })
+ if (href != null) {
+ const { disabled, onClick, newtab} = props;
+ return (
+
+ {icon}
+ {children}
+
+ )
+ }
+
+ if (to != null) {
+ return (
+
+ {icon}
+ {children}
+
+ )
+ }
+
+ return (
+
+ )
+}
+
+Button.defaultProps = {
+ newtab: "true",
+ size: "normal",
+ uppercase: "true",
+ variant: "primary",
+}
+
+export default Button
diff --git a/src/components/Button/styles.module.css b/src/components/Button/styles.module.css
new file mode 100644
index 00000000..c197b202
--- /dev/null
+++ b/src/components/Button/styles.module.css
@@ -0,0 +1,95 @@
+.button {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ height: 55px;
+ padding: 0 2rem;
+ border: none;
+ border-radius: calc(var(--ifm-global-border-radius) / 2);
+ font-weight: var(--ifm-font-weight-bold);
+ font-size: var(--font-size-normal);
+ transition: background-color 100ms cubic-bezier(0.17, 0.67, 0.83, 0.67);
+}
+
+.button:hover {
+ text-decoration: none;
+ cursor: pointer;
+}
+
+.button--plain {
+ height: auto;
+ padding: 0;
+ font-weight: unset;
+ font-size: unset;
+}
+
+.button--primary {
+ background-color: var(--theme-button-primary-background-color);
+ color: var(--theme-button-primary-text-color); }
+
+.button--primary:hover {
+ background-color: var(--theme-button-primary-hover-background-color);
+ color: var(--theme-button-primary-text-color);
+}
+
+.button--icon img, .button--icon svg {
+ margin-right: 0.5rem;
+}
+
+.button--secondary {
+ background-color: var(--theme-button-secondary-background-color);
+ color: var(--theme-button-secondary-text-color);
+}
+
+.button--secondary:hover {
+ background-color: var(--theme-button-secondary-hover-background-color);
+ color: var(--theme-button-secondary-text-color);
+}
+
+.button--tertiary {
+ background-color: var(--theme-button-tertiary-background-color);
+ color: var(--theme-button-tertiary-text-color);
+}
+
+.button--tertiary:hover {
+ color: var(--theme-button-tertiary-text-color);
+ background-color: var(--theme-button-tertiary-hover-background-color);
+}
+
+.button--small {
+ height: 3.5rem;
+}
+
+.button--xsmall {
+ height: 2.6rem;
+ padding: 0 1rem;
+}
+
+.button--xxsmall {
+ height: 2rem;
+ font-weight: normal;
+ font-size: 0.9rem;
+}
+
+.button--uppercase {
+ text-transform: uppercase;
+}
+
+@media (max-width: 996px) {
+ .button {
+ padding: 0 1.75rem;
+ }
+
+ .button--xsmall {
+ padding: 0 1rem;
+ }
+
+ .button--xxsmall {
+ padding: 0 0.9rem;
+ }
+
+
+ .button--plain {
+ padding: 0;
+ }
+}
diff --git a/src/components/Input/index.js b/src/components/Input/index.js
new file mode 100644
index 00000000..804c7aeb
--- /dev/null
+++ b/src/components/Input/index.js
@@ -0,0 +1,21 @@
+import clsx from "clsx";
+import React from "react";
+
+import styles from "./styles.module.css";
+
+const Input = (props) => {
+ const classes = clsx(props.className, styles.input)
+
+ return (
+
+ )
+}
+
+Input.defaultProps = {
+ type: "text",
+}
+
+export default Input
diff --git a/src/components/Input/styles.module.css b/src/components/Input/styles.module.css
new file mode 100644
index 00000000..f2546def
--- /dev/null
+++ b/src/components/Input/styles.module.css
@@ -0,0 +1,23 @@
+.input {
+ display: flex;
+ height: 55px;
+ padding: 0 2rem;
+ align-items: center;
+ border-radius: calc(var(--ifm-global-border-radius) / 2);
+ border: none;
+ background: var(--palette-rock);
+ font-size: var(--font-size-normal);
+ color: var(--ifm-color-white);
+ border: 2px solid transparent;
+}
+
+.input:focus {
+ outline: none;
+ border-color: var(--ifm-color-white);
+}
+
+.input:placeholder {
+ color: var(--palette-pale-blue);
+ font-size: var(--font-size-normal);
+ font-weight: var(--ifm-font-weight-bold);
+}
diff --git a/src/components/Section/index.js b/src/components/Section/index.js
new file mode 100644
index 00000000..9f5162e7
--- /dev/null
+++ b/src/components/Section/index.js
@@ -0,0 +1,31 @@
+import React from "react";
+import style from "./styles.module.css";
+import clsx from "clsx";
+
+export const Section = ({
+ fullWidth,
+ children,
+ odd,
+ accent,
+ row,
+ noGap,
+ center,
+ className = "",
+}) => (
+
+ {children}
+
+)
diff --git a/src/components/Section/styles.module.css b/src/components/Section/styles.module.css
new file mode 100644
index 00000000..63aedde3
--- /dev/null
+++ b/src/components/Section/styles.module.css
@@ -0,0 +1,41 @@
+.root {
+ display: flex;
+ flex-direction: column;
+ max-width: var(--ifm-container-width);
+ width: 100%;
+ padding: 2rem 1rem;
+ margin: 0 auto;
+}
+
+@media screen and (min-width: 900px) {
+ .root {
+ padding: 4.5rem 2rem;
+ }
+}
+
+.row {
+ flex-direction: row;
+}
+
+.odd {
+ background-color: var(--theme-section-odd-bg-color);
+}
+
+.accent {
+ --ifm-link-hover-color: var(--palette-pink);
+ --ifm-link-color: var(--palette-pink);
+ padding-top: 7rem;
+ padding-bottom: 7.5rem;
+}
+
+.fullWidth {
+ max-width: 100%;
+}
+
+.noGap {
+ padding: 0;
+}
+
+.center {
+ align-items: center;
+}
diff --git a/src/components/Subscribe/index.js b/src/components/Subscribe/index.js
new file mode 100644
index 00000000..c27023b7
--- /dev/null
+++ b/src/components/Subscribe/index.js
@@ -0,0 +1,39 @@
+import React, { useState } from "react"
+import Input from "../Input"
+import Button from "../Button"
+import style from "./style.module.css"
+import clsx from "clsx"
+
+const Spinner = () =>
+
+const Subscribe = ({placeholder, submitButtonText, className, classNameInputs}) => {
+ const [loading, setLoading] = useState(false)
+
+ return (
+
+ )
+}
+
+export default Subscribe
diff --git a/src/components/Subscribe/style.module.css b/src/components/Subscribe/style.module.css
new file mode 100644
index 00000000..ee512904
--- /dev/null
+++ b/src/components/Subscribe/style.module.css
@@ -0,0 +1,75 @@
+.root {
+ width: 100%;
+}
+
+.inputs {
+ display: grid;
+ gap: 1rem;
+}
+
+:global(html[data-theme="light"]) .subscribeSubmit {
+ background: #dde0e9;
+}
+
+:global(html[data-theme="light"]) .subscribeSubmit:hover {
+ opacity: 0.8;
+}
+
+@media screen and (min-width: 600px) {
+ .inputs {
+ grid-template-columns: 4fr 2fr;
+ }
+}
+
+.input {
+ color: var(--theme-input-text-color);
+ padding: 1rem;
+ font-size: var(--font-size-small);
+ width: 100%;
+ background-color: var(--theme-input-bg-color);
+}
+
+.checkbox {
+ display: none !important;
+}
+
+.input::placeholder {
+ color: var(--theme-input-text-color);
+}
+
+.submit {
+ white-space: nowrap;
+}
+
+.loader {
+ position: absolute;
+ width: 20px;
+ height: 20px;
+}
+
+.loader:after {
+ content: " ";
+ display: block;
+ width: 14px;
+ height: 14px;
+ margin: 0;
+ border-radius: 50%;
+ border: 3px solid transparent;
+ border-color: var(--ifm-color-white) transparent var(--ifm-color-white)
+ transparent;
+ animation: loader 1.2s linear infinite;
+}
+
+.success {
+ font-size: var(--font-size-large);
+ font-weight: var(--ifm-font-weight-bold);
+}
+
+@keyframes loader {
+ 0% {
+ transform: rotate(0deg);
+ }
+ 100% {
+ transform: rotate(360deg);
+ }
+}
diff --git a/src/components/SvgImage/index.js b/src/components/SvgImage/index.js
new file mode 100644
index 00000000..81045898
--- /dev/null
+++ b/src/components/SvgImage/index.js
@@ -0,0 +1,9 @@
+import { cloneElement } from "react";
+
+const SvgImage = ({ image, title = "" }) =>
+ cloneElement(image, {
+ ...image.props,
+ title,
+ })
+
+export default SvgImage
diff --git a/src/css/custom.css b/src/css/custom.css
index 039d7e3e..8c3b9694 100644
--- a/src/css/custom.css
+++ b/src/css/custom.css
@@ -6,6 +6,25 @@
/* You can override the default Infima variables here. */
:root {
+ --font-size-small: 15px;
+ --font-size-normal: 16px;
+ --font-size-large: 17px;
+ --font-size-big-1: 22px;
+ --font-size-big-2: 24px;
+ --font-size-big-3: 32px;
+ --font-size-big-4: 46px;
+ --font-size-big-5: 64px;
+ --palette-dark-10: rgba(0, 0, 0, 0.1);
+ --palette-dark-20: rgba(0, 0, 0, 0.2);
+ --palette-dark-30: rgba(0, 0, 0, 0.3);
+ --palette-dark-40: rgba(0, 0, 0, 0.4);
+ --palette-dark-60: rgba(0, 0, 0, 0.6);
+ --palette-dark-80: rgba(0, 0, 0, 0.8);
+ --palette-white-10: rgba(255, 255, 255, 0.1);
+ --palette-white-20: rgba(255, 255, 255, 0.2);
+ --palette-charade: #21222c;
+ --palette-rock: #262833;
+ --palette-pale-blue: #b1b5d3;
--ifm-color-primary: #2e8555;
--ifm-color-primary-dark: #29784c;
--ifm-color-primary-darker: #277148;
@@ -14,11 +33,29 @@
--ifm-color-primary-lighter: #359962;
--ifm-color-primary-lightest: #3cad6e;
--ifm-code-font-size: 95%;
- --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1);
+ --ifm-global-border-radius: 8px;
+ --docusaurus-highlighted-code-line-bg: var(--palette-dark-10);
+ --theme-card-text-color: var(--palette-charade);
+ --theme-card-title-color: var(--palette-charade);
+ --theme-attention-card-bg-color: #f0f1f5;
+ --theme-attention-card-text-color: var(--ifm-color-white);
+ --theme-input-text-color: #555b88;
+ --theme-card-secondary-bg-color: #dde0e9;
+ --theme-button-primary-background-color: var(--ifm-color-primary);
+ --theme-button-primary-text-color: var(--ifm-color-white);
+ --theme-button-primary-hover-background-color: var(--ifm-color-primary-darker);
+ --theme-button-secondary-background-color: var(--palette-dark-10);
+ --theme-button-secondary-text-color: var(--palette-charade);
+ --theme-button-secondary-hover-background-color: var(--palette-dark-30);
+ --theme-button-tertiary-background-color: var(--palette-dark-30);
+ --theme-button-tertiary-text-color: var(--palette-dark-80);
+ --theme-button-tertiary-hover-background-color: var(--palette-dark-40);
+ --theme-input-bg-color: #f0f1f5;
}
/* For readability concerns, you should choose a lighter palette in dark mode. */
[data-theme='dark'] {
+ --palette-gray: #4b4e5d;
--ifm-color-primary: #25c2a0;
--ifm-color-primary-dark: #21af90;
--ifm-color-primary-darker: #1fa588;
@@ -26,7 +63,20 @@
--ifm-color-primary-light: #29d5b0;
--ifm-color-primary-lighter: #32d8b4;
--ifm-color-primary-lightest: #4fddbf;
- --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3);
+ --docusaurus-highlighted-code-line-bg: var(--palette-dark-30);
+ --theme-attention-card-bg-color: var(--palette-gray);
+ --theme-input-bg-color: #44475a;
+ --theme-input-text-color: #b1b5d3;
+ --theme-card-secondary-bg-color: var(--palette-charade);
+ --theme-button-primary-background-color: var(--ifm-color-primary);
+ --theme-button-primary-text-color: var(--ifm-color-white);
+ --theme-button-primary-hover-background-color: var(--ifm-color-primary-darker);
+ --theme-button-secondary-background-color: var(--ifm-color-white);
+ --theme-button-secondary-text-color: var(--palette-charade);
+ --theme-button-secondary-hover-background-color: #d9d9d9;
+ --theme-button-tertiary-background-color: var(--palette-white-10);
+ --theme-button-tertiary-text-color: var(--ifm-color-white);
+ --theme-button-tertiary-hover-background-color: var(--palette-white-20);
}
[data-theme='dark'] [class*='announcementBar'] {
diff --git a/src/theme/ApiDoc/ApiDoc.jsx b/src/theme/ApiDoc/ApiDoc.jsx
new file mode 100644
index 00000000..3b0121a4
--- /dev/null
+++ b/src/theme/ApiDoc/ApiDoc.jsx
@@ -0,0 +1,16 @@
+import React from 'react';
+import Layout from '@theme/Layout';
+import Redoc from '@theme/Redoc';
+import { ActionFooter } from "@site/src/components/ActionFooter";
+import { Section } from "@site/src/components/Section";
+function ApiDoc({ layoutProps, specProps }) {
+ const defaultTitle = specProps.spec?.info?.title || 'API Docs';
+ const defaultDescription = specProps.spec?.info?.description || 'Open API Reference Docs for the API';
+ return (
+
+
+ );
+}
+export default ApiDoc;
diff --git a/src/theme/ApiDoc/index.js b/src/theme/ApiDoc/index.js
new file mode 100644
index 00000000..b9d038b0
--- /dev/null
+++ b/src/theme/ApiDoc/index.js
@@ -0,0 +1,2 @@
+import ApiDoc from './ApiDoc';
+export default ApiDoc;
diff --git a/src/theme/DocPage/Layout/index.js b/src/theme/DocPage/Layout/index.js
new file mode 100644
index 00000000..8a02a1c5
--- /dev/null
+++ b/src/theme/DocPage/Layout/index.js
@@ -0,0 +1,36 @@
+// Ejected unsafe, need to check if this changes and maintain this component
+// https://github.com/facebook/docusaurus/blob/docusaurus-v2/packages/docusaurus-theme-classic/src/theme/DocPage/Layout/index.tsx
+import React, {useState} from 'react';
+import {useDocsSidebar} from '@docusaurus/theme-common/internal';
+import Layout from '@theme/Layout';
+import BackToTopButton from '@theme/BackToTopButton';
+import DocPageLayoutSidebar from '@theme/DocPage/Layout/Sidebar';
+import DocPageLayoutMain from '@theme/DocPage/Layout/Main';
+import styles from './styles.module.css';
+import { ActionFooter } from "@site/src/components/ActionFooter";
+import { Section } from "@site/src/components/Section";
+
+export default function DocPageLayout({children}) {
+ const sidebar = useDocsSidebar();
+ const [hiddenSidebarContainer, setHiddenSidebarContainer] = useState(false);
+ return (
+
+
+
+ {sidebar && (
+
+ )}
+
+ {children}
+
+
+
+
+ );
+}
diff --git a/src/theme/DocPage/Layout/styles.module.css b/src/theme/DocPage/Layout/styles.module.css
new file mode 100644
index 00000000..74795779
--- /dev/null
+++ b/src/theme/DocPage/Layout/styles.module.css
@@ -0,0 +1,9 @@
+.docPage {
+ display: flex;
+ width: 100%;
+}
+
+.docsWrapper {
+ display: flex;
+ flex: 1 0 auto;
+}