diff --git a/client/src/assets/fonts/0xProtoNerdFont-Bold.ttf b/client/src/assets/fonts/0xProtoNerdFont-Bold.ttf
new file mode 100644
index 0000000..725d2d2
Binary files /dev/null and b/client/src/assets/fonts/0xProtoNerdFont-Bold.ttf differ
diff --git a/client/src/assets/fonts/0xProtoNerdFont-Regular.ttf b/client/src/assets/fonts/0xProtoNerdFont-Regular.ttf
new file mode 100644
index 0000000..489a6da
Binary files /dev/null and b/client/src/assets/fonts/0xProtoNerdFont-Regular.ttf differ
diff --git a/client/src/components/Code/index.tsx b/client/src/components/Code/index.tsx
index f850089..54a7e81 100644
--- a/client/src/components/Code/index.tsx
+++ b/client/src/components/Code/index.tsx
@@ -7,6 +7,7 @@ import { KEYS_TO_DISABLE } from 'constants/default';
import { renderCharacter } from './utils';
import './index.css';
+import Spinner from 'components/Spinner';
type CodeProps = {
code: string;
@@ -72,6 +73,12 @@ function Code({ code, loaded }: CodeProps) {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [timer, characters]);
+ if (!code) return (
+
{code.split('').map((char, index) => renderCharacter(code, characters, loaded, char, index))}
diff --git a/client/src/components/Spinner/index.css b/client/src/components/Spinner/index.css
new file mode 100644
index 0000000..599f64c
--- /dev/null
+++ b/client/src/components/Spinner/index.css
@@ -0,0 +1,24 @@
+.spinner-container {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ height: 200px;
+}
+
+.spinner {
+ width: 50px;
+ height: 50px;
+ border: 5px solid var(--white);
+ border-top: 5px solid var(--crimson);
+ border-radius: 50%;
+ animation: spin 1s linear infinite;
+}
+
+@keyframes spin {
+ 0% {
+ transform: rotate(0deg);
+ }
+ 100% {
+ transform: rotate(360deg);
+ }
+}
diff --git a/client/src/components/Spinner/index.tsx b/client/src/components/Spinner/index.tsx
new file mode 100644
index 0000000..739ff4d
--- /dev/null
+++ b/client/src/components/Spinner/index.tsx
@@ -0,0 +1,11 @@
+import './index.css';
+
+function Spinner() {
+ return (
+
+ );
+}
+
+export default Spinner;
diff --git a/client/src/constants/default.ts b/client/src/constants/default.ts
index 62a4456..91c78bd 100644
--- a/client/src/constants/default.ts
+++ b/client/src/constants/default.ts
@@ -34,7 +34,6 @@ export const KEYS_TO_DISABLE = [
'ArrowLeft',
'ArrowRight',
];
-
export const SUPPORTED_LANGUAGES = [
'javascript',
'typescript',
diff --git a/client/src/index.css b/client/src/index.css
index e804abd..ee2a888 100644
--- a/client/src/index.css
+++ b/client/src/index.css
@@ -1,10 +1,24 @@
+@font-face {
+ font-family: '0xProto';
+ font-style: normal;
+ font-weight: normal;
+ src: url(assets/fonts/0xProtoNerdFont-Regular.ttf) format(truetype);
+}
+
+@font-face {
+ font-family: '0xProto';
+ font-style: normal;
+ font-weight: bold;
+ src: url(assets/fonts/0xProtoNerdFont-Bold.ttf) format(truetype);
+}
+
:root {
--black: #131314;
--white: #dddddd;
--crimson: #bd1839;
--background: #1d1b1b;
- font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
+ font-family: '0xProto', sans-serif;
line-height: 1.5;
font-weight: 400;
@@ -56,13 +70,13 @@ body::-webkit-scrollbar-thumb {
}
.app {
- min-height: 95vh;
+ min-height: 95vh;
}
@media (min-width: 1441px) {
.app {
width: 1368px;
- margin: 0 auto;
+ margin: 0 auto;
}
}
diff --git a/client/src/pages/Home/index.css b/client/src/pages/Home/index.css
index 78e555d..12cd826 100644
--- a/client/src/pages/Home/index.css
+++ b/client/src/pages/Home/index.css
@@ -34,6 +34,10 @@ header p {
color: var(--white);
}
+header span {
+ color: var(--crimson);
+}
+
header .cta {
all: unset;
cursor: pointer;
@@ -52,7 +56,6 @@ header .cta {
}
.features {
- margin-top: 2rem;
padding: 2.5rem 1.25rem;
display: grid;
diff --git a/client/src/pages/Home/index.tsx b/client/src/pages/Home/index.tsx
index b3951fe..2024c3e 100644
--- a/client/src/pages/Home/index.tsx
+++ b/client/src/pages/Home/index.tsx
@@ -1,16 +1,24 @@
import { NavLink } from 'react-router';
+
+import { isMobileBrowser } from 'utils';
+
import './index.css';
function Home() {
+ const isMobile = isMobileBrowser();
+
return (
diff --git a/client/src/pages/Languages/index.css b/client/src/pages/Languages/index.css
index 3c36fb6..ef7f26f 100644
--- a/client/src/pages/Languages/index.css
+++ b/client/src/pages/Languages/index.css
@@ -25,6 +25,10 @@ header h1 {
color: var(--crimson);
}
+header span {
+ color: var(--crimson);
+}
+
.languages-wrapper {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
diff --git a/client/src/pages/Languages/index.tsx b/client/src/pages/Languages/index.tsx
index fdc2f96..abe8db9 100644
--- a/client/src/pages/Languages/index.tsx
+++ b/client/src/pages/Languages/index.tsx
@@ -1,10 +1,24 @@
import { NavLink } from 'react-router';
+import { isMobileBrowser } from 'utils';
+
import { SUPPORTED_LANGUAGES } from 'constants/default';
import './index.css';
function Languages() {
+ const isMobile = isMobileBrowser();
+
+ if (isMobile) {
+ return (
+
+
+ This app is made to be used in a desktop device.
+
+
+ );
+ }
+
return (
diff --git a/client/src/pages/Typing/index.css b/client/src/pages/Typing/index.css
index ba867f7..5eef99f 100644
--- a/client/src/pages/Typing/index.css
+++ b/client/src/pages/Typing/index.css
@@ -24,3 +24,7 @@ header h1 {
text-transform: capitalize;
}
+
+header span {
+ color: var(--crimson);
+}
diff --git a/client/src/pages/Typing/index.tsx b/client/src/pages/Typing/index.tsx
index eaafcf5..4a13427 100644
--- a/client/src/pages/Typing/index.tsx
+++ b/client/src/pages/Typing/index.tsx
@@ -3,17 +3,22 @@ import { useParams } from 'react-router';
import TypingContextProvider from 'contexts/typing';
+import { isMobileBrowser } from 'utils';
+
import Code from 'components/Code';
import Stats from 'components/Stats';
import './index.css';
function Typing() {
- const {lang} = useParams();
+ const isMobile = isMobileBrowser();
+ const { lang } = useParams();
const [code, setCode] = useState('');
const [loaded, setLoaded] = useState(false);
useEffect(() => {
+ if (isMobile) return;
+
(async function () {
setCode('');
@@ -39,7 +44,17 @@ function Typing() {
setCode((prev) => prev.trim());
setLoaded(true);
})();
- }, [lang]);
+ }, [isMobile, lang]);
+
+ if (isMobile) {
+ return (
+
+
+ This app is made to be used in a desktop device.
+
+
+ );
+ }
return (
diff --git a/client/src/utils.ts b/client/src/utils.ts
new file mode 100644
index 0000000..5b7eb21
--- /dev/null
+++ b/client/src/utils.ts
@@ -0,0 +1,5 @@
+export function isMobileBrowser(): boolean {
+ const width = window.innerWidth;
+
+ return width <= 768 || (width > 768 && width <= 1024);
+}