i18n finished (no content yet)

"/" path is now i18n complete - text, image, favicon are all defined in dictionaries (src/i18n/<lang>.js)
Blog should be too
This commit is contained in:
Cyril Šebek 2024-06-06 12:55:12 +02:00
parent 48c48d145a
commit 92aed66774
Signed by: blboun3
SSH Key Fingerprint: SHA256:ESaOKDAPaR/9j4DJ3sU4VdxTcL7qWUxpAyPSK2LLKbY
14 changed files with 367 additions and 141 deletions

View File

@ -1,22 +1,30 @@
---
import SinglePage from "../layouts/SinglePage.astro"
import SinglePage from "../layouts/SinglePage.astro";
import { dictionary } from "../i18n/dictionary";
import AboutModule from "./AboutModule.astro";
const { title, description } = dictionary[Astro.currentLocale];
import { getLangFromUrl, useTranslations } from "../i18n/utils";
const t = useTranslations(getLangFromUrl(Astro.url));
---
<SinglePage>
<div class="h-full max-h-dvh max-w-full grid grid-rows-3 gap-4">
<AboutModule row="0" image="/temp.jpg">
<h1 class="text-accent text-center text-lg md:text-xl xl:text-3xl font-bold py-3 lg:py-10">Lorem</h1>
<p class="text-content text-center text-md xl:text-lg xl:px-10">Lorem ipsum dolor sit amet consectetur, adipisicing elit. Atque consequatur voluptatibus nobis dolores repellendus similique, ut sit odit commodi optio tempore totam, quaerat at distinctio nisi dolore magnam quia perferendis.</p>
</AboutModule>
<AboutModule row="1" image="/temp.jpg" flipped>
<h1 class="text-accent text-center text-lg md:text-xl xl:text-3xl font-bold py-3 lg:py-10">Ipsum</h1>
<p class="text-content text-center text-md xl:text-lg xl:px-10">Lorem ipsum dolor sit amet consectetur, adipisicing elit. Atque consequatur voluptatibus nobis dolores repellendus similique, ut sit odit commodi optio tempore totam, quaerat at distinctio nisi dolore magnam quia perferendis.</p>
</AboutModule>
<AboutModule row="2" image="/temp.jpg" alt="image">
<h1 class="text-accent text-center text-lg md:text-xl xl:text-3xl font-bold py-3 lg:py-10">Dolor</h1>
<p class="text-content text-center text-md xl:text-lg xl:px-10">Lorem ipsum dolor sit amet consectetur, adipisicing elit. Atque consequatur voluptatibus nobis dolores repellendus similique, ut sit odit commodi optio tempore totam, quaerat at distinctio nisi dolore magnam quia perferendis.</p>
</AboutModule>
<div class="h-full max-h-dvh max-w-full grid grid-rows-3 gap-4">
<!-- Automaticly generate n (=3) bars with content -->
{
[0,1,2].map(i =>
<AboutModule
row={i}
image={t("about")[i].image}
flipped={i % 2}
>
<h1 class="text-accent text-center text-lg md:text-xl xl:text-3xl font-bold py-3 lg:py-10">
{t("about")[i].title}
</h1>
<p class="text-content text-center text-md xl:text-lg xl:px-10">
{t("about")[i].content}
</p>
</AboutModule>
)
}
</div>
</SinglePage>

View File

@ -1,26 +1,22 @@
---
import SinglePage from "../layouts/SinglePage.astro";
import { getLangFromUrl, useTranslations } from "../i18n/utils";
import { dictionary } from "../i18n/dictionary";
const { title, description } = dictionary[Astro.currentLocale];
const t = useTranslations(getLangFromUrl(Astro.url))
---
<SinglePage>
<!-- Hero Image -->
<div class="w-full flex justify-center mt-20">
<img src="/temp.jpg" alt="" class="rounded-full" />
<!-- https://loremflickr.com/g/200/200/cat,girl/all?lock=135 -->
<img src={t("hero").image} alt="" class="rounded-full" />
</div>
<!-- Hero Text -->
<div class="mt-[6rem]">
<h1 class="text-accent text-4xl w-full text-center font-extrabold">
Lorem Ipsum
{t("hero").title}
</h1>
<h2 class="text-content text-lg w-full text-center mt-[3.2rem]">
Lorem ipsum dolor, sit amet consectetur adipisicing elit. A suscipit
facilis doloribus, dicta cupiditate sint nisi ad explicabo cumque
dolorem quaerat hic aliquid. Iste quia aspernatur nam distinctio,
animi dolorum?
{t("hero").content}
</h2>
</div>
<!-- Call action buttons -->
@ -28,12 +24,12 @@ const { title, description } = dictionary[Astro.currentLocale];
<button
type="button"
class="text-3xl bg-accent text-bkg p-1 rounded-md bg-opacity-75 hover:bg-opacity-100 m-2"
>Lorem</button
>{t("hero").buttons[0]}</button
>
<button
type="button"
class="text-2xl m-2 bg-secondary/60 rounded-md p-1 hover:bg-secondary text-content"
>ipsum dolor</button
>{t("hero").buttons[1]}</button
>
</div>
</SinglePage>

View File

@ -1,3 +1,4 @@
import { useTranslations } from "../i18n/utils";
import {
Card,
CardContent,
@ -12,11 +13,10 @@ import {
TabsTrigger,
} from "../components/ui/tabs";
import { dictionary } from "../i18n/dictionary";
export function ShowcaseTabs({ currentLocale }) {
const { showcase } = dictionary[currentLocale];
const t = useTranslations(currentLocale);
const showcase = t("showcase");
return (
<Tabs
defaultValue={showcase[0].value}

View File

@ -7,11 +7,11 @@ import {
CardTitle,
} from "./ui/card";
const { post, lang } = Astro.props;
const { post } = Astro.props;
---
<div>
<a href={`${Astro.url.origin}/${lang ? lang : "en"}/blog/${post.blog_slug}`}>
<a href={`${Astro.url.origin}/${Astro.currentLocale}/blog/${post.blog_slug}`}>
<Card>
<CardHeader>
<img

View File

@ -1,33 +1,85 @@
export const cs = {
title: "CS Test",
showcase: [
title: "Lorem Ipsum", // Title of the main page in browser's handlebard
description: "Page description here", // HTML page description
/*
Hero module of the page
*/
hero: {
title: "Lorem",
content: "ipsum dolor",
image: "/temp.jpg",
buttons: ["Button 1", "Button 2"],
},
/*
About module of the page
*/
about: [
{
value: "thisPage",
handle: "Projekt 1",
title: "This Page",
href: "/potato",
description:
"random text os iuoiu fsd ufiodsu foid sufo dsufois dufoisd eee sfsdffsdfsd sd sd ds dsfsv sd dss ds ds ufiosdufi osdufsdfsd iofusdoifudu siofsdfids ofudsiouoi",
// About page first block title
title: "Lorem",
// Content of about page first block
content:
"Lorem ipsum dolor sit amet consectetur, adipisicing elit. Atque consequatur voluptatibus nobis dolores repellendus similique, ut sit odit commodi optio tempore totam, quaerat at distinctio nisi dolore magnam quia perferendis.",
// Image
image: "/temp.jpg",
imageAlt: "text",
},
{
value: "thatPage",
title: "That Page",
handle: "Projekt 2",
href: "/potat2",
description: "random text",
// About page second block title
title: "Ipsum",
// Content of about page's second block
content:
"Lorem ipsum dolor sit amet consectetur, adipisicing elit. Atque consequatur voluptatibus nobis dolores repellendus similique, ut sit odit commodi optio tempore totam, quaerat at distinctio nisi dolore magnam quia perferendis.",
// Image
image: "/temp.jpg",
imageAlt: "text",
},
{
value: "otherPage",
title: "Other Page",
handle: "Projekt 3",
href: "/kartoffeln",
description: "random text",
// About page third block title
title: "Ipsum",
// Content of about page's third block
content:
"Lorem ipsum dolor sit amet consectetur, adipisicing elit. Atque consequatur voluptatibus nobis dolores repellendus similique, ut sit odit commodi optio tempore totam, quaerat at distinctio nisi dolore magnam quia perferendis.",
// Image
image: "/temp.jpg",
imageAlt: "text",
},
],
/*
Showcase module of the page
*/
showcase: [
{
value: "first",
handle: "Website",
title: "My personal webpage",
href: "/potato",
description:
"My personal website, clearly you've found it. Made in Astro.js with help of shadcnui components.",
image: "/temp.jpg",
imageAlt: "Screenshot of this website",
},
{
value: "second",
title: "Self-hostable",
handle: "HomeLab",
href: "/potat2",
description:
"It has now been a few years since I've started with selfhosting. It started as one single Raspberry Pi 4, then it grew to cluster of 4 Pis... and now I have 2 old IBM servers (x3550 m4).",
image: "/temp.jpg",
imageAlt: "Photo of my personal homelab",
},
{
value: "third",
title: "ESA's Astro Pi Challenge 2022/23",
handle: "ESA Astro Pi",
href: "/kartoffeln",
description:
"Astro Pi is a competition for high school students by the European Space Agency. It's goal is to make it possible for students to run their code on the ISS. I was part of the Barrande team from our school. As our mission we chose Classification of Earth's topology using AI in Real-Time and I was the one tasked with programmign the AI. The mission was very successfull and we were nominated to 10 best teams. Reports and other data can be found on ESA's website.",
image: "/temp.jpg",
imageAlt: "Image for of our task and results explanation",
},
],
postsTagged: "All posts tagged with",
};

View File

@ -1,34 +1,86 @@
export const de = {
title: "DE Test",
showcase: [
title: "Lorem Ipsum", // Title of the main page in browser's handlebard
description: "Page description here", // HTML page description
/*
Hero module of the page
*/
hero: {
title: "Lorem",
content: "ipsum dolor",
image: "/temp.jpg",
buttons: ["Button 1", "Button 2"],
},
/*
About module of the page
*/
about: [
{
value: "thisPage",
handle: "Projekt 1 DE",
title: "This Page",
href: "/potato",
description:
"random text os iuoiu fsd ufiodsu foid sufo dsufois dufoisd eee sfsdffsdfsd sd sd ds dsfsv sd dss ds ds ufiosdufi osdufsdfsd iofusdoifudu siofsdfids ofudsiouoi",
// About page first block title
title: "Lorem",
// Content of about page first block
content:
"Lorem ipsum dolor sit amet consectetur, adipisicing elit. Atque consequatur voluptatibus nobis dolores repellendus similique, ut sit odit commodi optio tempore totam, quaerat at distinctio nisi dolore magnam quia perferendis.",
// Image
image: "/temp.jpg",
imageAlt: "text",
},
{
value: "thatPage",
title: "That Page",
handle: "Projekt 2 DE",
href: "/potat2",
description: "random text",
// About page second block title
title: "Ipsum",
// Content of about page's second block
content:
"Lorem ipsum dolor sit amet consectetur, adipisicing elit. Atque consequatur voluptatibus nobis dolores repellendus similique, ut sit odit commodi optio tempore totam, quaerat at distinctio nisi dolore magnam quia perferendis.",
// Image
image: "/temp.jpg",
imageAlt: "text",
},
{
value: "otherPage",
title: "Other Page",
handle: "Projekt 3 DE",
href: "/kartoffeln",
description: "random text",
// About page third block title
title: "Ipsum",
// Content of about page's third block
content:
"Lorem ipsum dolor sit amet consectetur, adipisicing elit. Atque consequatur voluptatibus nobis dolores repellendus similique, ut sit odit commodi optio tempore totam, quaerat at distinctio nisi dolore magnam quia perferendis.",
// Image
image: "/temp.jpg",
imageAlt: "text",
},
],
/*
Showcase module of the page
*/
showcase: [
{
value: "first",
handle: "Website",
title: "My personal webpage",
href: "/potato",
description:
"My personal website, clearly you've found it. Made in Astro.js with help of shadcnui components.",
image: "/temp.jpg",
imageAlt: "Screenshot of this website",
},
{
value: "second",
title: "Self-hostable",
handle: "HomeLab",
href: "/potat2",
description:
"It has now been a few years since I've started with selfhosting. It started as one single Raspberry Pi 4, then it grew to cluster of 4 Pis... and now I have 2 old IBM servers (x3550 m4).",
image: "/temp.jpg",
imageAlt: "Photo of my personal homelab",
},
{
value: "third",
title: "ESA's Astro Pi Challenge 2022/23",
handle: "ESA Astro Pi",
href: "/kartoffeln",
description:
"Astro Pi is a competition for high school students by the European Space Agency. It's goal is to make it possible for students to run their code on the ISS. I was part of the Barrande team from our school. As our mission we chose Classification of Earth's topology using AI in Real-Time and I was the one tasked with programmign the AI. The mission was very successfull and we were nominated to 10 best teams. Reports and other data can be found on ESA's website.",
image: "/temp.jpg",
imageAlt: "Image for of our task and results explanation",
},
],
postsTagged: "All posts tagged with",
};

View File

@ -1,34 +1,86 @@
export const en = {
title: "EN Test",
showcase: [
{
value: "thisPage",
handle: "Projekt 1 EN",
title: "This Page",
href: "/potato",
description:
"random text os iuoiu fsd ufiodsu foid sufo dsufois dufoisd eee sfsdffsdfsd sd sd ds dsfsv sd dss ds ds ufiosdufi osdufsdfsd iofusdoifudu siofsdfids ofudsiouoi",
image: "/temp.jpg",
imageAlt: "text",
},
{
value: "thatPage",
title: "That Page",
handle: "Projekt 2 EN",
href: "/potat2",
description: "random text",
image: "/temp.jpg",
imageAlt: "text",
},
{
value: "otherPage",
title: "Other Page",
handle: "Projekt 3 EN",
href: "/kartoffeln",
description: "random text",
image: "/temp.jpg",
imageAlt: "text",
},
],
};
title: "Lorem Ipsum", // Title of the main page in browser's handlebard
description: "Page description here", // HTML page description
favicon: "/favicon.svg",
/*
Hero module of the page
*/
hero: {
title: "Lorem",
content: "ipsum dolor",
image: "/temp.jpg",
buttons: ["Button 1", "Button 2"],
},
/*
About module of the page
*/
about: [
{
// About page first block title
title: "Lorem",
// Content of about page first block
content:
"Lorem ipsum dolor sit amet consectetur, adipisicing elit. Atque consequatur voluptatibus nobis dolores repellendus similique, ut sit odit commodi optio tempore totam, quaerat at distinctio nisi dolore magnam quia perferendis.",
// Image
image: "/temp.jpg",
},
{
// About page second block title
title: "Ipsum",
// Content of about page's second block
content:
"Lorem ipsum dolor sit amet consectetur, adipisicing elit. Atque consequatur voluptatibus nobis dolores repellendus similique, ut sit odit commodi optio tempore totam, quaerat at distinctio nisi dolore magnam quia perferendis.",
// Image
image: "/temp.jpg",
},
{
// About page third block title
title: "Ipsum",
// Content of about page's third block
content:
"Lorem ipsum dolor sit amet consectetur, adipisicing elit. Atque consequatur voluptatibus nobis dolores repellendus similique, ut sit odit commodi optio tempore totam, quaerat at distinctio nisi dolore magnam quia perferendis.",
// Image
image: "/temp.jpg",
},
],
/*
Showcase module of the page
*/
showcase: [
{
value: "first",
handle: "Website",
title: "My personal webpage",
href: "/potato",
description:
"My personal website, clearly you've found it. Made in Astro.js with help of Shadcn/UI components.",
image: "/temp.jpg",
imageAlt: "Screenshot of this website",
},
{
value: "second",
title: "Self-hostable",
handle: "HomeLab",
href: "/potat2",
description:
"It has now been a few years since I've started with selfhosting. It started as one single Raspberry Pi 4, then it grew to cluster of 4 Pis... and now I have 2 old IBM servers (x3550 m4).",
image: "/temp.jpg",
imageAlt: "Photo of my personal homelab",
},
{
value: "third",
title: "ESA's Astro Pi Challenge 2022/23",
handle: "ESA Astro Pi",
href: "/kartoffeln",
description:
"Astro Pi is a competition for high school students by the European Space Agency. It's goal is to make it possible for students to run their code on the ISS. I was part of the Barrande team from our school. As our mission we chose Classification of Earth's topology using AI in Real-Time and I was the one tasked with programmign the AI. The mission was very successfull and we were nominated to 10 best teams. Reports and other data can be found on ESA's website.",
image: "/temp.jpg",
imageAlt: "Image for of our task and results explanation",
},
],
postsTagged: "All posts tagged with",
};

View File

@ -1,34 +1,86 @@
export const fr = {
title: "FR Test",
showcase: [
title: "Lorem Ipsum", // Title of the main page in browser's handlebard
description: "Page description here", // HTML page description
/*
Hero module of the page
*/
hero: {
title: "Lorem",
content: "ipsum dolor",
image: "/temp.jpg",
buttons: ["Button 1", "Button 2"],
},
/*
About module of the page
*/
about: [
{
value: "thisPage",
handle: "Projekt 1 FR",
title: "This Page",
href: "/potato",
description:
"random text os iuoiu fsd ufiodsu foid sufo dsufois dufoisd eee sfsdffsdfsd sd sd ds dsfsv sd dss ds ds ufiosdufi osdufsdfsd iofusdoifudu siofsdfids ofudsiouoi",
// About page first block title
title: "Lorem",
// Content of about page first block
content:
"Lorem ipsum dolor sit amet consectetur, adipisicing elit. Atque consequatur voluptatibus nobis dolores repellendus similique, ut sit odit commodi optio tempore totam, quaerat at distinctio nisi dolore magnam quia perferendis.",
// Image
image: "/temp.jpg",
imageAlt: "text",
},
{
value: "thatPage",
title: "That Page",
handle: "Projekt 2 FR",
href: "/potat2",
description: "random text",
// About page second block title
title: "Ipsum",
// Content of about page's second block
content:
"Lorem ipsum dolor sit amet consectetur, adipisicing elit. Atque consequatur voluptatibus nobis dolores repellendus similique, ut sit odit commodi optio tempore totam, quaerat at distinctio nisi dolore magnam quia perferendis.",
// Image
image: "/temp.jpg",
imageAlt: "text",
},
{
value: "otherPage",
title: "Other Page",
handle: "Projekt 3 FR",
href: "/kartoffeln",
description: "random text",
// About page third block title
title: "Ipsum",
// Content of about page's third block
content:
"Lorem ipsum dolor sit amet consectetur, adipisicing elit. Atque consequatur voluptatibus nobis dolores repellendus similique, ut sit odit commodi optio tempore totam, quaerat at distinctio nisi dolore magnam quia perferendis.",
// Image
image: "/temp.jpg",
imageAlt: "text",
},
],
/*
Showcase module of the page
*/
showcase: [
{
value: "first",
handle: "Website",
title: "My personal webpage",
href: "/potato",
description:
"My personal website, clearly you've found it. Made in Astro.js with help of shadcnui components.",
image: "/temp.jpg",
imageAlt: "Screenshot of this website",
},
{
value: "second",
title: "Self-hostable",
handle: "HomeLab",
href: "/potat2",
description:
"It has now been a few years since I've started with selfhosting. It started as one single Raspberry Pi 4, then it grew to cluster of 4 Pis... and now I have 2 old IBM servers (x3550 m4).",
image: "/temp.jpg",
imageAlt: "Photo of my personal homelab",
},
{
value: "third",
title: "ESA's Astro Pi Challenge 2022/23",
handle: "ESA Astro Pi",
href: "/kartoffeln",
description:
"Astro Pi is a competition for high school students by the European Space Agency. It's goal is to make it possible for students to run their code on the ISS. I was part of the Barrande team from our school. As our mission we chose Classification of Earth's topology using AI in Real-Time and I was the one tasked with programmign the AI. The mission was very successfull and we were nominated to 10 best teams. Reports and other data can be found on ESA's website.",
image: "/temp.jpg",
imageAlt: "Image for of our task and results explanation",
},
],
postsTagged: "All posts tagged with",
};

View File

@ -3,7 +3,10 @@ const { title, description, lang, themeOverride } = Astro.props;
import { ViewTransitions } from 'astro:transitions';
import Navbar from "../components/Navbar.astro";
import "../style/index.css";
import { useTranslations } from '../i18n/utils';
//import "../style/globals.css";
const t = useTranslations(lang)
---
<!doctype html>
@ -12,7 +15,7 @@ import "../style/index.css";
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content={description} />
<link rel="shortcut icon" href="/favicon.svg">
<link rel="shortcut icon" href={t("favicon")}>
<title>{title}</title>
<ViewTransitions />
</head>

View File

@ -32,6 +32,11 @@ const { Content } = await page.render();
<!--<img src={page.data.image.url} alt={page.data.image.alt} class="rounded-lg max-h-[25vh] m-auto"> -->
<h1 class="lg:text-4xl text-2xl">{page.data.title}</h1>
<p>{page.data.author} • {formattedDate}</p>
<div class="flex justify-center">
{ page.data.tags?.map((tag) =>
<a href={`${Astro.url.origin}/${Astro.currentLocale}/blog/tags/${tag}`}>#{tag}</a>
)}
</div>
</div>
<Content />
</article>

View File

@ -18,6 +18,7 @@ var posts = await getBlogPosts();
var filtered_posts = posts.filter(
(post) => post.data.language == Astro.currentLocale,
);
---
<MainLayout title={title} description={description} lang={Astro.currentLocale}>

View File

@ -1,7 +1,7 @@
---
import MainLayout from "../../../../layouts/MainLayout.astro";
import SinglePageBlogMode from "../../../../layouts/SinglePageBlogMode.astro";
import { LANGUAGES } from "../../../../i18n/utils";
import { LANGUAGES, getLangFromUrl, useTranslations } from "../../../../i18n/utils";
import { getBlogPosts } from "../../../../content/config";
import PostsList from "../../../../components/PostsList.astro";
@ -13,16 +13,20 @@ export async function getStaticPaths() {
tags.map((tag) => {
Object.keys(LANGUAGES).map((lang) => {
paths.push({
if(tag){
paths.push({
params: { lang: lang, tag: tag },
props: { posts: allPosts },
});
}
});
});
return paths;
}
const t = useTranslations(getLangFromUrl(Astro.url))
const { lang, tag } = Astro.params;
const { posts } = Astro.props;
@ -31,6 +35,7 @@ const filteredPosts = posts.filter((post) => post.data.tags?.includes(tag) && po
<MainLayout title={tag} description={"desc"} lang={lang}>
<SinglePageBlogMode>
<h1 class="text-2xl text-center font-bold text-content mb-10 mt-5">{t("postsTagged")} "{tag}"</h1>
<PostsList filteredPosts={filteredPosts} lang={Astro.currentLocale} />
</SinglePageBlogMode>
</MainLayout>

View File

@ -5,9 +5,9 @@ import About from "../../components/About.astro";
import Showcase from "../../components/Showcase.astro";
//@ts-ignore
import { dictionary } from "../../i18n/dictionary";
import { getLangFromUrl, useTranslations } from "../../i18n/utils";
const { title, description } = dictionary[Astro.currentLocale];
const t = useTranslations(getLangFromUrl(Astro.url));
export async function getStaticPaths() {
return ["en", "fr", "cs", "de"].map((lang) => {
@ -15,7 +15,7 @@ export async function getStaticPaths() {
});
}
---
<MainLayout title={title} description={description} lang={Astro.currentLocale} themeOverride="theme_auto">
<MainLayout title={t("title")} description={t("description")} lang={Astro.currentLocale} themeOverride="theme_auto">
<Hero />
<About />
<Showcase />

View File

@ -12,7 +12,7 @@ Dark Mode: https://www.realtimecolors.com/dashboard?colors=e7e7e9-0f0f0f-5819c5
Light mode
*/
--light-color-bkg: 0deg, 0%, 94%;
--light-color-bkgNavbar: 0deg, 0%, 20%;
--light-color-bkgNavbar: 0deg, 0%, 50%;
--light-color-content: 240deg, 4%, 9%;
--light-color-primary: 54deg, 100%, 50%;
--light-color-secondary: 237deg, 100%, 93%;
@ -25,8 +25,8 @@ Dark Mode: https://www.realtimecolors.com/dashboard?colors=e7e7e9-0f0f0f-5819c5
--light-input: 214.3 31.8% 91.4%;
--light-muted: 210 40% 96.1%;
--light-muted-foreground: 215 17% 34%;
--light-popover: 0 0% 100%; /* merge to bkgNavbar */
--light-popover-foreground: 222.2 47.4% 11.2%; /* merge to bkg */
--light-popover: 0 0% 100%;
--light-popover-foreground: 222.2 47.4% 11.2%;
--light-border: 214.3 31.8% 91.4%;
--light-card: 0 0% 100%;
--light-card-foreground: 222.2 47.4% 11.2%;
@ -52,8 +52,8 @@ Dark Mode: https://www.realtimecolors.com/dashboard?colors=e7e7e9-0f0f0f-5819c5
--dark-input: 216 34% 17%;
--dark-muted: 0 0% 15%;
--dark-muted-foreground: 215.4 31% 71%;
--dark-popover: 224 71% 4%; /* merge to bkgNavbar */
--dark-popover-foreground: 215 20.2% 65.1%; /* merge to bkg */
--dark-popover: 224 71% 4%;
--dark-popover-foreground: 215 20.2% 65.1%;
--dark-border: 9 20% 21%;
--dark-card: 0 0% 15%;
--dark-card-foreground: 213 31% 91%;