diff --git a/src/app/components/Footer.tsx b/src/app/components/Footer.tsx
new file mode 100644
index 00000000..47aaf959
--- /dev/null
+++ b/src/app/components/Footer.tsx
@@ -0,0 +1,23 @@
+import { Octicon } from '.'
+import { useLocale } from '../contexts'
+
+interface Props {
+ donate?: boolean,
+}
+export function Footer({ donate }: Props) {
+ const { locale } = useLocale()
+
+ return
+}
diff --git a/src/app/components/Octicon.tsx b/src/app/components/Octicon.tsx
index 9404a34c..5acff40c 100644
--- a/src/app/components/Octicon.tsx
+++ b/src/app/components/Octicon.tsx
@@ -20,6 +20,7 @@ export const Octicon = {
file_directory: ,
gear: ,
globe: ,
+ heart: ,
history: ,
info: ,
issue_opened: ,
diff --git a/src/app/components/index.ts b/src/app/components/index.ts
index d858264a..28e59053 100644
--- a/src/app/components/index.ts
+++ b/src/app/components/index.ts
@@ -3,6 +3,7 @@ export * from './Btn'
export * from './BtnInput'
export * from './BtnMenu'
export * from './ErrorPanel'
+export * from './Footer'
export * from './forms'
export * from './generator'
export * from './Giscus'
diff --git a/src/app/pages/Category.tsx b/src/app/pages/Category.tsx
index d9a1474e..555502e6 100644
--- a/src/app/pages/Category.tsx
+++ b/src/app/pages/Category.tsx
@@ -1,5 +1,5 @@
import config from '../../config.json'
-import { ToolCard } from '../components'
+import { Footer, ToolCard } from '../components'
import { useLocale, useTitle } from '../contexts'
import { cleanUrl } from '../Utils'
@@ -16,5 +16,6 @@ export function Category({ category }: Props) {
)}
+
}
diff --git a/src/app/pages/Changelog.tsx b/src/app/pages/Changelog.tsx
index 66d03582..a7638e41 100644
--- a/src/app/pages/Changelog.tsx
+++ b/src/app/pages/Changelog.tsx
@@ -1,4 +1,4 @@
-import { Ad, ChangelogList, ErrorPanel } from '../components'
+import { Ad, ChangelogList, ErrorPanel, Footer } from '../components'
import { useLocale, useTitle } from '../contexts'
import { useAsync } from '../hooks'
import { getChangelogs } from '../services'
@@ -18,5 +18,6 @@ export function Changelog({}: Props) {
+
}
diff --git a/src/app/pages/Generator.tsx b/src/app/pages/Generator.tsx
index 5a974884..018b6260 100644
--- a/src/app/pages/Generator.tsx
+++ b/src/app/pages/Generator.tsx
@@ -3,7 +3,7 @@ import { getCurrentUrl, route } from 'preact-router'
import { useEffect, useErrorBoundary, useMemo, useRef, useState } from 'preact/hooks'
import config from '../../config.json'
import { Analytics } from '../Analytics'
-import { Ad, Btn, BtnMenu, ErrorPanel, HasPreview, Octicon, PreviewPanel, SearchList, SourcePanel, TextInput, Tree } from '../components'
+import { Ad, Btn, BtnMenu, ErrorPanel, Footer, HasPreview, Octicon, PreviewPanel, SearchList, SourcePanel, TextInput, Tree } from '../components'
import { useLocale, useProject, useTitle, useVersion } from '../contexts'
import { AsyncCancel, useActiveTimeout, useAsync, useModel, useSearchParam } from '../hooks'
import { getOutput } from '../schema/transformOutput'
@@ -377,6 +377,7 @@ export function Generator({}: Props) {
{error && setError(null)} />}
+
+
}
diff --git a/src/app/pages/Home.tsx b/src/app/pages/Home.tsx
index 62598025..6d0a3062 100644
--- a/src/app/pages/Home.tsx
+++ b/src/app/pages/Home.tsx
@@ -1,5 +1,5 @@
import config from '../../config.json'
-import { Giscus, ToolCard } from '../components'
+import { Footer, Giscus, ToolCard } from '../components'
import { useLocale, useTitle } from '../contexts'
import { cleanUrl } from '../Utils'
@@ -37,6 +37,7 @@ export function Home({}: Props) {
+
}
diff --git a/src/app/pages/Partners.tsx b/src/app/pages/Partners.tsx
index 2338382d..cb18e2e6 100644
--- a/src/app/pages/Partners.tsx
+++ b/src/app/pages/Partners.tsx
@@ -1,5 +1,5 @@
import config from '../../config.json'
-import { ToolCard } from '../components'
+import { Footer, ToolCard } from '../components'
import { useLocale, useTitle } from '../contexts'
import { cleanUrl } from '../Utils'
@@ -23,5 +23,6 @@ export function Partners({}: Props) {
)}
)}
+
}
diff --git a/src/app/pages/Sounds.tsx b/src/app/pages/Sounds.tsx
index b8072640..051bbc96 100644
--- a/src/app/pages/Sounds.tsx
+++ b/src/app/pages/Sounds.tsx
@@ -1,7 +1,7 @@
import type { Howl, HowlOptions } from 'howler'
import { useEffect, useMemo, useRef, useState } from 'preact/hooks'
import config from '../../config.json'
-import { Btn, BtnMenu, ErrorPanel, SoundConfig, TextInput } from '../components'
+import { Btn, BtnMenu, ErrorPanel, Footer, SoundConfig, TextInput } from '../components'
import { useLocale, useTitle, useVersion } from '../contexts'
import { useAsync } from '../hooks'
import type { VersionId } from '../services'
@@ -87,5 +87,6 @@ export function Sounds({}: Props) {
{soundKeys.map(s => )}
>}
+
}
diff --git a/src/app/pages/Versions.tsx b/src/app/pages/Versions.tsx
index 7711efee..5104cf83 100644
--- a/src/app/pages/Versions.tsx
+++ b/src/app/pages/Versions.tsx
@@ -1,4 +1,4 @@
-import { Ad, ErrorPanel, Octicon, VersionDetail, VersionList } from '../components'
+import { Ad, ErrorPanel, Footer, Octicon, VersionDetail, VersionList } from '../components'
import { useLocale, useTitle } from '../contexts'
import { useAsync, useSearchParam } from '../hooks'
import type { VersionMeta } from '../services'
@@ -46,6 +46,7 @@ export function Versions({}: Props) {
> : `/versions/?id=${id}`} />}
+
}
diff --git a/src/locales/en.json b/src/locales/en.json
index f28df0a2..98e47b64 100644
--- a/src/locales/en.json
+++ b/src/locales/en.json
@@ -16,9 +16,11 @@
"copy_share": "Copy share link",
"copied": "Copied!",
"copy_context": "Copy context",
+ "developed_by": "Developed by",
"dimension_type": "Dimension Type",
"dimension": "Dimension",
"disabled": "Disabled",
+ "donate": "Donate",
"download": "Download",
"duplicate": "Duplicate",
"enabled": "Enabled",
@@ -135,6 +137,7 @@
"sounds.remove_sound": "Remove sound",
"sounds.unknown_sound": "Unknown sound",
"sounds.loading_sound": "Loading sound",
+ "source_code_on": "Source code on",
"source_placeholder": "Paste raw %0% content here",
"switch_generator": "Switch generator",
"switch_version": "Switch version",
diff --git a/src/styles/global.css b/src/styles/global.css
index f46fb1dc..c986d53d 100644
--- a/src/styles/global.css
+++ b/src/styles/global.css
@@ -12,6 +12,7 @@
--accent-success: #3eb84f;
--accent-warning: #b8893e;
--accent-danger: #cf4945;
+ --accent-donate: #db61a2;
--accent-sounds-1: #451475;
--accent-sounds-2: #39155e;
--accent-sounds-3: #6a08a3;
@@ -233,6 +234,44 @@ header .btn-menu > .btn:hover {
fill: var(--nav-hover);
}
+footer {
+ display: flex;
+ align-items: flex-end;
+ flex-wrap: wrap;
+ padding: 50px 30px;
+ color: var(--text-3);
+}
+
+footer > * {
+ margin-bottom: 10px;
+}
+
+footer > *:not(:last-child) {
+ margin-right: 30px;
+}
+
+footer p {
+ display: flex;
+ align-items: center;
+}
+
+footer a {
+ color: var(--text-3);
+}
+
+footer a:hover {
+ color: var(--text-1);
+}
+
+footer svg {
+ fill: var(--text-3);
+ margin-right: 8px;
+}
+
+footer .donate svg {
+ fill: var(--accent-donate);
+}
+
main {
padding-top: 68px;
color: var(--text-1);