Added ChatUI branding & put theming behind an env variable (#298)

* Moved all huggingchat branding behind an env variable

* Refactored branding to use multiple env variables

* pr review

* prettier

* move the ethics modal behind the flag PUBLIC_APP_DISCLAIMER

* inline chat ui logo so it would take the color

* flex-none
pull/320/head
Nathan Sarrazin 2023-06-16 13:45:58 +02:00 committed by GitHub
parent abe7804d91
commit 5d07536967
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 178 additions and 113 deletions

13
.env
View File

@ -68,3 +68,16 @@ PUBLIC_ANNOUNCEMENT_BANNERS=`[
PARQUET_EXPORT_DATASET=
PARQUET_EXPORT_HF_TOKEN=
PARQUET_EXPORT_SECRET=
PUBLIC_APP_NAME=ChatUI # name used as title throughout the app
PUBLIC_APP_ASSETS=chatui # used to find logos & favicons in static/$PUBLIC_APP_ASSETS
PUBLIC_APP_COLOR=blue # can be any of tailwind colors: https://tailwindcss.com/docs/customizing-colors#default-color-palette
PUBLIC_APP_DATA_SHARING=#set to 1 to enable options & text regarding data sharing
PUBLIC_APP_DISCLAIMER=#set to 1 to show a disclaimer on login page
# PUBLIC_APP_NAME=HuggingChat
# PUBLIC_APP_ASSETS=huggingchat
# PUBLIC_APP_COLOR=yellow
# PUBLIC_APP_DATA_SHARING=1
# PUBLIC_APP_DISCLAIMER=1

View File

@ -2,29 +2,7 @@
<html lang="en" class="h-full">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.svg" type="image/svg+xml" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" type="image/png" />
<!-- Icon Support for iOS Bookmark Home Screen -->
<link
rel="apple-touch-icon"
href="%sveltekit.assets%/touch-icon-ipad-retina.png"
sizes="167x167"
type="image/png"
/>
<link
rel="apple-touch-icon"
href="%sveltekit.assets%/touch-icon-ipad.png"
sizes="152x152"
type="image/png"
/>
<link
rel="apple-touch-icon"
href="%sveltekit.assets%/touch-icon-iphone-retina.png"
sizes="180x180"
type="image/png"
/>
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
<title>HuggingChat</title>
<script>
if (
localStorage.theme === "dark" ||

View File

@ -4,6 +4,7 @@ import {
PUBLIC_GOOGLE_ANALYTICS_ID,
PUBLIC_DEPRECATED_GOOGLE_ANALYTICS_ID,
PUBLIC_ORIGIN,
PUBLIC_APP_DISCLAIMER,
} from "$env/static/public";
import { collections } from "$lib/server/database";
import { base } from "$app/paths";
@ -67,9 +68,14 @@ export const handle: Handle = async ({ event, resolve }) => {
return errorResponse(401, ERROR_MESSAGES.authOnly);
}
// if login is not required and the call is not from /settings, we check if the user has accepted the ethics modal first.
// if login is not required and the call is not from /settings and we display the ethics modal with PUBLIC_APP_DISCLAIMER
// we check if the user has accepted the ethics modal first.
// If login is required, `ethicsModalAcceptedAt` is already true at this point, so do not pass this condition. This saves a DB call.
if (!requiresUser && !event.url.pathname.startsWith(`${base}/settings`)) {
if (
!requiresUser &&
!event.url.pathname.startsWith(`${base}/settings`) &&
!!PUBLIC_APP_DISCLAIMER
) {
const hasAcceptedEthicsModal = await collections.settings.countDocuments({
sessionId: event.locals.sessionId,
ethicsModalAcceptedAt: { $exists: true },

View File

@ -5,7 +5,7 @@
<div class="flex items-center rounded-xl bg-gray-100 p-1 text-sm dark:bg-gray-800 {classNames}">
<span
class="mr-2 inline-flex items-center rounded-lg bg-gradient-to-br from-yellow-300 px-2 py-1 text-xxs font-medium uppercase leading-3 text-yellow-700 dark:from-[#373010] dark:text-yellow-400"
class="mr-2 inline-flex items-center rounded-lg bg-gradient-to-br from-primary-300 px-2 py-1 text-xxs font-medium uppercase leading-3 text-primary-700 dark:from-primary-900 dark:text-primary-400"
>New</span
>
{title}

View File

@ -2,12 +2,11 @@
import { browser } from "$app/environment";
import { base } from "$app/paths";
import { page } from "$app/stores";
import { PUBLIC_VERSION } from "$env/static/public";
import Logo from "$lib/components/icons/Logo.svelte";
import { PUBLIC_APP_DATA_SHARING, PUBLIC_APP_NAME, PUBLIC_VERSION } from "$env/static/public";
import LogoHuggingFaceBorderless from "$lib/components/icons/LogoHuggingFaceBorderless.svelte";
import Modal from "$lib/components/Modal.svelte";
import type { LayoutData } from "../../routes/$types";
import Logo from "./icons/Logo.svelte";
export let settings: LayoutData["settings"];
const isIframe = browser && window.self !== window.parent;
@ -15,10 +14,11 @@
<Modal>
<div
class="flex w-full flex-col items-center gap-6 bg-gradient-to-t from-yellow-500/40 via-yellow-500/10 to-yellow-500/0 px-4 pb-10 pt-9 text-center"
class="flex w-full flex-col items-center gap-6 bg-gradient-to-t from-primary-500/40 via-primary-500/10 to-primary-500/0 px-4 pb-10 pt-9 text-center "
>
<h2 class="flex items-center text-2xl font-semibold text-gray-800">
<Logo classNames="text-3xl mr-1.5" />HuggingChat
<Logo classNames="mr-1" />
{PUBLIC_APP_NAME}
<div
class="ml-3 flex h-6 items-center rounded-lg border border-gray-100 bg-gray-50 px-2 text-base text-gray-400"
>
@ -32,20 +32,27 @@
AI is an area of active research with known problems such as biased generation and
misinformation. Do not use this application for high-stakes decisions or advice.
</p>
<p class="px-2 text-sm text-gray-500">
Your conversations will be shared with model authors unless you disable it from your settings.
</p>
{#if PUBLIC_APP_DATA_SHARING}
<p class="px-2 text-sm text-gray-500">
Your conversations will be shared with model authors unless you disable it from your
settings.
</p>
{/if}
<form
action="{base}/{$page.data.requiresLogin ? 'login' : 'settings'}"
target={isIframe ? "_blank" : ""}
method="POST"
class="flex w-full flex-col items-center gap-2"
>
{#if $page.data.requiresLogin}
<button
type="submit"
class="mt-2 flex items-center whitespace-nowrap rounded-full bg-black px-5 py-2 text-lg font-semibold text-gray-100 transition-colors hover:bg-yellow-500"
class="mt-2 flex items-center whitespace-nowrap rounded-full bg-black px-5 py-2 text-lg font-semibold text-gray-100 transition-colors hover:bg-primary-500"
>
Sign in with <LogoHuggingFaceBorderless classNames="text-xl mr-1 ml-1.5" /> Hugging Face
Sign in
{#if PUBLIC_APP_NAME === "HuggingChat"}
with <LogoHuggingFaceBorderless classNames="text-xl mr-1 ml-1.5" /> Hugging Face
{/if}
</button>
<p class="mt-2 px-2 text-sm text-gray-500">to start chatting right away</p>
{:else}
@ -55,7 +62,7 @@
{/each}
<button
type="submit"
class="mt-2 rounded-full bg-black px-5 py-2 text-lg font-semibold text-gray-100 transition-colors hover:bg-yellow-500"
class="mt-2 rounded-full bg-black px-5 py-2 text-lg font-semibold text-gray-100 transition-colors hover:bg-primary-500"
>
Start chatting
</button>

View File

@ -41,7 +41,7 @@
{#each models as model}
<div
class="rounded-xl border border-gray-100 {model.id === selectedModelId
? 'bg-gradient-to-r from-yellow-200/40 via-yellow-500/10'
? 'bg-gradient-to-r from-primary-200/40 via-primary-500/10'
: ''}"
>
<label class="group flex cursor-pointer p-3" on:change aria-label={model.displayName}>
@ -62,7 +62,7 @@
</span>
<CarbonCheckmark
class="-mr-1 -mt-1 ml-auto shrink-0 text-xl {model.id === selectedModelId
? 'text-yellow-400'
? 'text-primary-400'
: 'text-transparent group-hover:text-gray-200'}"
/>
</label>

View File

@ -4,7 +4,7 @@
import Logo from "$lib/components/icons/Logo.svelte";
import { switchTheme } from "$lib/switchTheme";
import { PUBLIC_ORIGIN } from "$env/static/public";
import { PUBLIC_APP_NAME, PUBLIC_ORIGIN } from "$env/static/public";
import NavConversationItem from "./NavConversationItem.svelte";
import type { LayoutData } from "../../routes/$types";
@ -23,8 +23,8 @@
<div class="sticky top-0 flex flex-none items-center justify-between px-3 py-3.5 max-sm:pt-0">
<a class="flex items-center rounded-xl text-lg font-semibold" href="{PUBLIC_ORIGIN}{base}/">
<Logo classNames="mr-1 text-3xl" />
HuggingChat
<Logo classNames="mr-1" />
{PUBLIC_APP_NAME}
</a>
<a
href={`${base}/`}
@ -75,18 +75,20 @@
>
Settings
</button>
<a
href="https://huggingface.co/spaces/huggingchat/chat-ui/discussions"
target="_blank"
rel="noreferrer"
class="flex h-9 flex-none items-center gap-1.5 rounded-lg pl-3 pr-2 text-gray-500 hover:bg-gray-100 dark:text-gray-400 dark:hover:bg-gray-700"
>
Feedback
</a>
<a
href="{base}/privacy"
class="flex h-9 flex-none items-center gap-1.5 rounded-lg pl-3 pr-2 text-gray-500 hover:bg-gray-100 dark:text-gray-400 dark:hover:bg-gray-700"
>
About & Privacy
</a>
{#if PUBLIC_APP_NAME === "HuggingChat"}
<a
href="https://huggingface.co/spaces/huggingchat/chat-ui/discussions"
target="_blank"
rel="noreferrer"
class="flex h-9 flex-none items-center gap-1.5 rounded-lg pl-3 pr-2 text-gray-500 hover:bg-gray-100 dark:text-gray-400 dark:hover:bg-gray-700"
>
Feedback
</a>
<a
href="{base}/privacy"
class="flex h-9 flex-none items-center gap-1.5 rounded-lg pl-3 pr-2 text-gray-500 hover:bg-gray-100 dark:text-gray-400 dark:hover:bg-gray-700"
>
About & Privacy
</a>
{/if}
</div>

View File

@ -7,6 +7,7 @@
import type { Settings } from "$lib/types/Settings";
import { enhance } from "$app/forms";
import { base } from "$app/paths";
import { PUBLIC_APP_DATA_SHARING } from "$env/static/public";
export let settings: Pick<Settings, "shareConversationsWithModelAuthors">;
@ -32,32 +33,35 @@
method="post"
action="{base}/settings"
>
<label class="flex cursor-pointer select-none items-center gap-2 text-gray-500">
{#each Object.entries(settings).filter(([k]) => k !== "shareConversationsWithModelAuthors") as [key, val]}
<input type="hidden" name={key} value={val} />
{/each}
<Switch
name="shareConversationsWithModelAuthors"
bind:checked={shareConversationsWithModelAuthors}
/>
Share conversations with model authors
</label>
{#if PUBLIC_APP_DATA_SHARING}
<label class="flex cursor-pointer select-none items-center gap-2 text-gray-500">
{#each Object.entries(settings).filter(([k]) => k !== "shareConversationsWithModelAuthors") as [key, val]}
<input type="hidden" name={key} value={val} />
{/each}
<Switch
name="shareConversationsWithModelAuthors"
bind:checked={shareConversationsWithModelAuthors}
/>
Share conversations with model authors
</label>
<p class="text-gray-800">
Sharing your data will help improve the training data and make open models better over time.
</p>
<p class="text-gray-800">
You can change this setting at any time, it applies to all your conversations.
</p>
<p class="text-gray-800">
Read more about this model's authors,
<a
href="https://open-assistant.io/"
target="_blank"
rel="noreferrer"
class="underline decoration-gray-300 hover:decoration-gray-700">Open Assistant</a
>.
</p>
<p class="text-gray-800">
Sharing your data will help improve the training data and make open models better over
time.
</p>
<p class="text-gray-800">
You can change this setting at any time, it applies to all your conversations.
</p>
<p class="text-gray-800">
Read more about this model's authors,
<a
href="https://open-assistant.io/"
target="_blank"
rel="noreferrer"
class="underline decoration-gray-300 hover:decoration-gray-700">Open Assistant</a
>.
</p>
{/if}
<form
method="post"
action="{base}/conversations?/delete"

View File

@ -1,5 +1,5 @@
<script lang="ts">
import { PUBLIC_VERSION } from "$env/static/public";
import { PUBLIC_APP_NAME, PUBLIC_VERSION } from "$env/static/public";
import { PUBLIC_ANNOUNCEMENT_BANNERS } from "$env/static/public";
import Logo from "$lib/components/icons/Logo.svelte";
import { createEventDispatcher } from "svelte";
@ -31,8 +31,8 @@
<div class="lg:col-span-1">
<div>
<div class="mb-3 flex items-center text-2xl font-semibold">
<Logo classNames="mr-1 text-yellow-400 text-4xl flex-none" />
HuggingChat
<Logo classNames="mr-1 flex-none" />
{PUBLIC_APP_NAME}
<div
class="ml-3 flex h-6 items-center rounded-lg border border-gray-100 bg-gray-50 px-2 text-base text-gray-400 dark:border-gray-700/60 dark:bg-gray-800"
>

View File

@ -137,7 +137,7 @@
type="button"
on:click={() => dispatch("share")}
>
<CarbonExport class="text-[.6rem] sm:mr-1.5 sm:text-yellow-500" />
<CarbonExport class="text-[.6rem] sm:mr-1.5 sm:text-primary-500" />
<div class="max-sm:hidden">Share this conversation</div>
</button>
{/if}

View File

@ -1,25 +1,28 @@
<script lang="ts">
import { page } from "$app/stores";
import { PUBLIC_APP_ASSETS, PUBLIC_APP_NAME, PUBLIC_ORIGIN } from "$env/static/public";
import { base } from "$app/paths";
export let classNames = "";
</script>
<svg
width="1em"
height="1em"
class={classNames}
viewBox="0 0 13 12"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
fill="#FFD21E"
d="M1.76 5.63a3.7 3.7 0 0 1 3.7-3.7h1.7a3.43 3.43 0 0 1 0 6.87H3.07L2.01 9.83a.14.14 0 0 1-.25-.1v-4.1Z"
{#if PUBLIC_APP_ASSETS === "chatui"}
<svg
height="30"
width="30"
viewBox="0 0 30 30"
xmlns="http://www.w3.org/2000/svg"
class={classNames}
>
<path
d="M4.06151 14.1464C4.06151 11.8818 4.9611 9.71004 6.56237 8.10877C8.16364 6.5075 10.3354 5.60791 12.6 5.60791H16.5231C18.6254 5.60791 20.6416 6.44307 22.1282 7.92965C23.6148 9.41624 24.45 11.4325 24.45 13.5348C24.45 15.6372 23.6148 17.6534 22.1282 19.14C20.6416 20.6266 18.6254 21.4618 16.5231 21.4618H7.08459L4.63844 23.8387C4.59547 23.8942 4.53557 23.9343 4.4678 23.9527C4.40004 23.9712 4.32811 23.9671 4.2629 23.941C4.1977 23.9149 4.14276 23.8683 4.10643 23.8082C4.07009 23.7481 4.05432 23.6778 4.06151 23.6079V14.1464Z"
class="fill-primary-500"
/>
</svg>
{:else}
<object
class={classNames}
data="{PUBLIC_ORIGIN || $page.url.origin}{base}/{PUBLIC_APP_ASSETS}/favicon.svg"
title="{PUBLIC_APP_NAME} logo"
/>
<path
fill="#32343D"
d="M7.37 4.8c.13.05.19.33.33.25a.54.54 0 0 0 .22-.73.54.54 0 0 0-.73-.22.54.54 0 0 0-.22.73c.06.13.27-.08.4-.03ZM4.83 4.8c-.14.05-.2.33-.33.25a.54.54 0 0 1-.23-.73A.54.54 0 0 1 5 4.1c.26.14.36.47.22.73-.06.13-.27-.08-.4-.03ZM6.12 7.4c1.06 0 1.4-.96 1.4-1.44 0-.49-.62.26-1.4.26-.77 0-1.4-.75-1.4-.26 0 .48.34 1.43 1.4 1.43Z"
/>
<path
fill="#FF323D"
d="M6.97 7.12c-.2.16-.49.27-.85.27-.34 0-.6-.1-.81-.24a.94.94 0 0 1 .57-.49c.04-.01.09.06.13.14.05.07.1.15.14.15.05 0 .1-.08.14-.15.05-.08.1-.15.14-.13a.93.93 0 0 1 .54.45Z"
/>
</svg>
{/if}

View File

@ -4,7 +4,7 @@
import { page } from "$app/stores";
import "../styles/main.css";
import { base } from "$app/paths";
import { PUBLIC_ORIGIN } from "$env/static/public";
import { PUBLIC_ORIGIN, PUBLIC_APP_DISCLAIMER } from "$env/static/public";
import { shareConversation } from "$lib/shareConversation";
import { UrlDependency } from "$lib/types/UrlDependency";
@ -15,6 +15,7 @@
import Toast from "$lib/components/Toast.svelte";
import SettingsModal from "$lib/components/SettingsModal.svelte";
import LoginModal from "$lib/components/LoginModal.svelte";
import { PUBLIC_APP_ASSETS, PUBLIC_APP_NAME } from "$env/static/public";
export let data;
@ -94,18 +95,54 @@
const requiresLogin =
!$page.error &&
(data.requiresLogin ? !data.user : !data.settings.ethicsModalAcceptedAt) &&
!$page.route.id?.startsWith("/r/");
!$page.route.id?.startsWith("/r/") &&
(data.requiresLogin
? !data.user
: !data.settings.ethicsModalAcceptedAt && !!PUBLIC_APP_DISCLAIMER);
</script>
<svelte:head>
<title>{PUBLIC_APP_NAME}</title>
<meta name="description" content="The first open source alternative to ChatGPT. 💪" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:site" content="@huggingface" />
<meta property="og:title" content="HuggingChat" />
<meta property="og:title" content={PUBLIC_APP_NAME} />
<meta property="og:type" content="website" />
<meta property="og:url" content="{PUBLIC_ORIGIN || $page.url.origin}{base}" />
<meta property="og:image" content="{PUBLIC_ORIGIN || $page.url.origin}{base}/thumbnail.png" />
<meta
property="og:image"
content="{PUBLIC_ORIGIN || $page.url.origin}{base}/{PUBLIC_APP_ASSETS}/thumbnail.png"
/>
<link
rel="icon"
href="{PUBLIC_ORIGIN || $page.url.origin}{base}/{PUBLIC_APP_ASSETS}/favicon.svg"
type="image/svg+xml"
/>
<link
rel="icon"
href="{PUBLIC_ORIGIN || $page.url.origin}{base}/{PUBLIC_APP_ASSETS}/favicon.png"
type="image/png"
/>
<!-- Icon Support for iOS Bookmark Home Screen -->
<link
rel="apple-touch-icon"
href="{PUBLIC_ORIGIN || $page.url.origin}{base}/{PUBLIC_APP_ASSETS}/touch-icon-ipad-retina.png"
sizes="167x167"
type="image/png"
/>
<link
rel="apple-touch-icon"
href="{PUBLIC_ORIGIN || $page.url.origin}{base}/{PUBLIC_APP_ASSETS}/touch-icon-ipad.png"
sizes="152x152"
type="image/png"
/>
<link
rel="apple-touch-icon"
href="{PUBLIC_ORIGIN ||
$page.url.origin}{base}/{PUBLIC_APP_ASSETS}/touch-icon-iphone-retina.png"
sizes="180x180"
type="image/png"
/>
</svelte:head>
<div

View File

@ -2,6 +2,7 @@
import { goto } from "$app/navigation";
import { base } from "$app/paths";
import { page } from "$app/stores";
import { PUBLIC_APP_DISCLAIMER } from "$env/static/public";
import ChatWindow from "$lib/components/chat/ChatWindow.svelte";
import { ERROR_MESSAGES, error } from "$lib/stores/errors";
import { pendingMessage } from "$lib/stores/pendingMessage";
@ -80,5 +81,7 @@
currentModel={findCurrentModel(data.models, data.model)}
settings={data.settings}
loginRequired={!$page.error &&
(data.requiresLogin ? !data.user : !data.settings.ethicsModalAcceptedAt)}
(data.requiresLogin
? !data.user
: !data.settings.ethicsModalAcceptedAt && !!PUBLIC_APP_DISCLAIMER)}
/>

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

@ -0,0 +1,6 @@
<svg width="30" height="30" viewBox="0 0 30 30"
xmlns="http://www.w3.org/2000/svg">
<path
d="M4.06151 14.1464C4.06151 11.8818 4.9611 9.71004 6.56237 8.10877C8.16364 6.5075 10.3354 5.60791 12.6 5.60791H16.5231C18.6254 5.60791 20.6416 6.44307 22.1282 7.92965C23.6148 9.41624 24.45 11.4325 24.45 13.5348C24.45 15.6372 23.6148 17.6534 22.1282 19.14C20.6416 20.6266 18.6254 21.4618 16.5231 21.4618H7.08459L4.63844 23.8387C4.59547 23.8942 4.53557 23.9343 4.4678 23.9527C4.40004 23.9712 4.32811 23.9671 4.2629 23.941C4.1977 23.9149 4.14276 23.8683 4.10643 23.8082C4.07009 23.7481 4.05432 23.6778 4.06151 23.6079V14.1464Z"
style="fill:rgb(107, 114, 128)"></path>
</svg>

After

Width:  |  Height:  |  Size: 685 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@ -1,4 +1,4 @@
<svg width="1em" height="1em" viewBox="0 0 13 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<svg width="30" height="30" viewBox="0 0 13 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
fill="#FFD21E"
d="M1.76 5.63a3.7 3.7 0 0 1 3.7-3.7h1.7a3.43 3.43 0 0 1 0 6.87H3.07L2.01 9.83a.14.14 0 0 1-.25-.1v-4.1Z"

Before

Width:  |  Height:  |  Size: 799 B

After

Width:  |  Height:  |  Size: 797 B

View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

Before

Width:  |  Height:  |  Size: 7.9 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB

View File

Before

Width:  |  Height:  |  Size: 7.9 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB

View File

Before

Width:  |  Height:  |  Size: 9.0 KiB

After

Width:  |  Height:  |  Size: 9.0 KiB

View File

@ -1,12 +1,11 @@
import adapter from "@sveltejs/adapter-node";
import { vitePreprocess } from "@sveltejs/kit/vite";
import dotenv from "dotenv";
import pkg from "./package.json" assert { type: "json" };
dotenv.config({ path: "./.env.local" });
dotenv.config({ path: "./.env" });
process.env.PUBLIC_VERSION = pkg.version.replace(/\.0\b/g, "");
process.env.PUBLIC_VERSION = process.env.npm_package_version;
/** @type {import('@sveltejs/kit').Config} */
const config = {

View File

@ -1,4 +1,8 @@
const defaultTheme = require("tailwindcss/defaultTheme");
const colors = require("tailwindcss/colors");
import dotenv from "dotenv";
dotenv.config({ path: "./.env" });
/** @type {import('tailwindcss').Config} */
export default {
@ -6,6 +10,9 @@ export default {
content: ["./src/**/*.{html,js,svelte,ts}"],
theme: {
extend: {
colors: {
primary: colors[process.env.PUBLIC_APP_COLOR],
},
// fontFamily: {
// sans: ['"Inter"', ...defaultTheme.fontFamily.sans]
// },