rebrand
This commit is contained in:
@@ -1,9 +1,13 @@
|
|||||||
# KrisHD_AI
|
# Elsewhere
|
||||||
|
|
||||||
KrisHD_AI is an Express + SQLite app for account-based chat, persona management, roleplay chat sessions, and a simple persona market backed by a remote model API.
|
Elsewhere is an Express + SQLite app for account-based chat, persona management, roleplay chat sessions, and a simple persona market backed by a remote model API.
|
||||||
|
|
||||||
|
A space for every conversation. Six appearance styles (Grove, Parchment, Aurora, Current, Iris, and Graphite) each support light and dark modes. The Elsewhere identity stays consistent across styles. Internal theme and storage keys remain stable to preserve saved preferences.
|
||||||
|
|
||||||
## Setup
|
## Setup
|
||||||
|
|
||||||
|
Node.js 22 or newer is required.
|
||||||
|
|
||||||
1. Install dependencies with `npm install`.
|
1. Install dependencies with `npm install`.
|
||||||
2. Copy `.env.example` to `.env` and set at least `SESSION_SECRET`.
|
2. Copy `.env.example` to `.env` and set at least `SESSION_SECRET`.
|
||||||
3. Start the app with `npm run dev` for local development or `npm start` for a normal server run.
|
3. Start the app with `npm run dev` for local development or `npm start` for a normal server run.
|
||||||
|
|||||||
+5
-2
@@ -3,6 +3,9 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "server.js",
|
"main": "server.js",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=22"
|
||||||
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node server.js",
|
"start": "node server.js",
|
||||||
"dev": "node --watch server.js",
|
"dev": "node --watch server.js",
|
||||||
@@ -10,8 +13,8 @@
|
|||||||
"test": "node --test"
|
"test": "node --test"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bcrypt": "^5.1.1",
|
"bcrypt": "^6.0.0",
|
||||||
"better-sqlite3": "^9.5.0",
|
"better-sqlite3": "^13.0.3",
|
||||||
"body-parser": "^1.20.2",
|
"body-parser": "^1.20.2",
|
||||||
"express": "^4.19.2",
|
"express": "^4.19.2",
|
||||||
"express-session": "^1.17.3",
|
"express-session": "^1.17.3",
|
||||||
|
|||||||
@@ -6,11 +6,12 @@ export const onboardingPrompts = {
|
|||||||
roleplay: ["Start a roleplay scene with immediate tension.", "Give me a dramatic opening with clear stakes."]
|
roleplay: ["Start a roleplay scene with immediate tension.", "Give me a dramatic opening with clear stakes."]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Stable keys preserve existing saved appearance preferences.
|
||||||
export const themes = {
|
export const themes = {
|
||||||
"fakegpt": {name: "FakeGPT", short: "FG"},
|
"fakegpt": {name: "Grove", short: "GR"},
|
||||||
"fraud": {name: "Fraud", short: "FR"},
|
"fraud": {name: "Parchment", short: "PA"},
|
||||||
"germini": {name: "Germini", short: "GE"},
|
"germini": {name: "Aurora", short: "AU"},
|
||||||
"slopilot": {name: "Slopilot", short: "SP"},
|
"slopilot": {name: "Current", short: "CU"},
|
||||||
"beta-ai": {name: "Beta AI", short: "BA"},
|
"beta-ai": {name: "Iris", short: "IR"},
|
||||||
"confusity": {name: "Confusity", short: "CF"}
|
"confusity": {name: "Graphite", short: "GP"}
|
||||||
};
|
};
|
||||||
|
|||||||
+4
-4
@@ -112,8 +112,8 @@ const onboardingContinue = $("onboardingContinue");
|
|||||||
const onboardingSkip = $("onboardingSkip");
|
const onboardingSkip = $("onboardingSkip");
|
||||||
const authScreens = document.querySelectorAll(".auth-screen");
|
const authScreens = document.querySelectorAll(".auth-screen");
|
||||||
const toggleButtons = document.querySelectorAll(".auth-toggle .toggle");
|
const toggleButtons = document.querySelectorAll(".auth-toggle .toggle");
|
||||||
const themeNameTargets = document.querySelectorAll("[data-theme-name]");
|
const brandNameTargets = document.querySelectorAll("[data-brand-name]");
|
||||||
const themeLogoTargets = document.querySelectorAll("[data-theme-logo]");
|
const brandLogoTargets = document.querySelectorAll("[data-brand-logo]");
|
||||||
const modelSection = document.querySelector(".chat-drawer-section--model");
|
const modelSection = document.querySelector(".chat-drawer-section--model");
|
||||||
const personaSection = document.querySelector(".chat-drawer-section--persona");
|
const personaSection = document.querySelector(".chat-drawer-section--persona");
|
||||||
|
|
||||||
@@ -231,8 +231,8 @@ export {
|
|||||||
sendBtn,
|
sendBtn,
|
||||||
saveGenerationSettingsBtn,
|
saveGenerationSettingsBtn,
|
||||||
sessionUser,
|
sessionUser,
|
||||||
themeLogoTargets,
|
brandLogoTargets,
|
||||||
themeNameTargets,
|
brandNameTargets,
|
||||||
toggleButtons,
|
toggleButtons,
|
||||||
userPersonaList
|
userPersonaList
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -24,16 +24,17 @@ export function applyTheme(themeKey, {
|
|||||||
persist = true,
|
persist = true,
|
||||||
title = null,
|
title = null,
|
||||||
themeSelect = null,
|
themeSelect = null,
|
||||||
nameTargets = document.querySelectorAll("[data-theme-name]"),
|
nameTargets = document.querySelectorAll("[data-brand-name]"),
|
||||||
logoTargets = document.querySelectorAll("[data-theme-logo]")
|
logoTargets = document.querySelectorAll("[data-brand-logo]")
|
||||||
} = {}) {
|
} = {}) {
|
||||||
const nextTheme = normalizeTheme(themeKey);
|
const nextTheme = normalizeTheme(themeKey);
|
||||||
const theme = themes[nextTheme];
|
const theme = themes[nextTheme];
|
||||||
|
document.documentElement.dataset.theme = nextTheme;
|
||||||
document.body.dataset.theme = nextTheme;
|
document.body.dataset.theme = nextTheme;
|
||||||
if (typeof title === "function") document.title = title(theme);
|
if (typeof title === "function") document.title = title(theme);
|
||||||
if (typeof title === "string") document.title = title;
|
if (typeof title === "string") document.title = title;
|
||||||
nameTargets.forEach((target) => { target.textContent = theme.name; });
|
nameTargets.forEach((target) => { target.textContent = "elsewhere"; });
|
||||||
logoTargets.forEach((target) => { target.textContent = theme.short; });
|
logoTargets.forEach((target) => { target.textContent = ""; target.classList.add("doorway-mark"); });
|
||||||
if (themeSelect) themeSelect.value = nextTheme;
|
if (themeSelect) themeSelect.value = nextTheme;
|
||||||
if (persist) localStorage.setItem(THEME_STORAGE_KEY, nextTheme);
|
if (persist) localStorage.setItem(THEME_STORAGE_KEY, nextTheme);
|
||||||
document.dispatchEvent(new CustomEvent("appearancechange", {detail: {theme: nextTheme}}));
|
document.dispatchEvent(new CustomEvent("appearancechange", {detail: {theme: nextTheme}}));
|
||||||
@@ -42,6 +43,7 @@ export function applyTheme(themeKey, {
|
|||||||
|
|
||||||
export function applyThemeMode(modeKey, {persist = true, modeSelect = null} = {}) {
|
export function applyThemeMode(modeKey, {persist = true, modeSelect = null} = {}) {
|
||||||
const nextMode = normalizeThemeMode(modeKey);
|
const nextMode = normalizeThemeMode(modeKey);
|
||||||
|
document.documentElement.dataset.themeMode = nextMode;
|
||||||
document.body.dataset.themeMode = nextMode;
|
document.body.dataset.themeMode = nextMode;
|
||||||
if (modeSelect) modeSelect.value = nextMode;
|
if (modeSelect) modeSelect.value = nextMode;
|
||||||
if (persist) localStorage.setItem(THEME_MODE_STORAGE_KEY, nextMode);
|
if (persist) localStorage.setItem(THEME_MODE_STORAGE_KEY, nextMode);
|
||||||
|
|||||||
+10
-8
@@ -2,12 +2,13 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8"/>
|
<meta charset="UTF-8"/>
|
||||||
<title>FakeGPT</title>
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
|
||||||
|
<title>Elsewhere</title>
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;700&family=Manrope:wght@400;500;600;700;800&display=swap" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;700&family=Manrope:wght@400;500;600;700;800&display=swap" rel="stylesheet">
|
||||||
<script src="app/theme-bootstrap.js"></script>
|
<script src="app/theme-bootstrap.js"></script>
|
||||||
<link rel="stylesheet" href="style.css?v=20260809-2"/>
|
<link rel="stylesheet" href="style.css?v=20260909-elsewhere"/>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
</head>
|
</head>
|
||||||
<body data-theme="fakegpt" data-theme-mode="light">
|
<body data-theme="fakegpt" data-theme-mode="light">
|
||||||
@@ -15,10 +16,11 @@
|
|||||||
<section id="auth" class="card auth-card auth-card-compact">
|
<section id="auth" class="card auth-card auth-card-compact">
|
||||||
<div class="auth-hero auth-hero-compact">
|
<div class="auth-hero auth-hero-compact">
|
||||||
<div class="brand">
|
<div class="brand">
|
||||||
<div class="logo logo-placeholder" aria-hidden="true"></div>
|
<div class="logo doorway-mark" aria-hidden="true"></div>
|
||||||
<div>
|
<div>
|
||||||
<p class="eyebrow">Private workspace</p>
|
<p class="eyebrow">Your conversation space</p>
|
||||||
<h1 data-theme-name>FakeGPT</h1>
|
<h1 class="brand-wordmark" data-brand-name>elsewhere</h1>
|
||||||
|
<p class="brand-tagline">A space for every conversation.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -80,7 +82,7 @@
|
|||||||
<div class="sidebar-workspace-card">
|
<div class="sidebar-workspace-card">
|
||||||
<div>
|
<div>
|
||||||
<p class="eyebrow">Workspace</p>
|
<p class="eyebrow">Workspace</p>
|
||||||
<h2 data-theme-name>FakeGPT</h2>
|
<h2 class="brand-wordmark" data-brand-name>elsewhere</h2>
|
||||||
<p id="sessionUser" class="sidebar-account-name">Signed out</p>
|
<p id="sessionUser" class="sidebar-account-name">Signed out</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="sidebar-header-actions sidebar-workspace-actions">
|
<div class="sidebar-header-actions sidebar-workspace-actions">
|
||||||
@@ -409,11 +411,11 @@
|
|||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<div class="persona-modal-heading">
|
<div class="persona-modal-heading">
|
||||||
<p class="eyebrow">Get started</p>
|
<p class="eyebrow">Get started</p>
|
||||||
<h3 id="onboardingTitle">What do you want to do?</h3>
|
<h3 id="onboardingTitle">Where shall we start?</h3>
|
||||||
</div>
|
</div>
|
||||||
<button id="onboardingSkip" type="button" class="icon-button">Skip</button>
|
<button id="onboardingSkip" type="button" class="icon-button">Skip</button>
|
||||||
</div>
|
</div>
|
||||||
<p id="onboardingSubtitle" class="subtitle">Pick one path to set up your first successful chat.</p>
|
<p id="onboardingSubtitle" class="subtitle">Ask a question, explore an idea, or step into a story.</p>
|
||||||
<div id="onboardingChoices" class="onboarding-choices"></div>
|
<div id="onboardingChoices" class="onboarding-choices"></div>
|
||||||
<div class="popup-actions">
|
<div class="popup-actions">
|
||||||
<button id="onboardingBack" type="button" class="secondary-action hidden">Back</button>
|
<button id="onboardingBack" type="button" class="secondary-action hidden">Back</button>
|
||||||
|
|||||||
+4
-3
@@ -2,12 +2,13 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8"/>
|
<meta charset="UTF-8"/>
|
||||||
<title>FakeGPT Market</title>
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
|
||||||
|
<title>Elsewhere Market</title>
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;700&family=Manrope:wght@400;500;600;700;800&display=swap" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;700&family=Manrope:wght@400;500;600;700;800&display=swap" rel="stylesheet">
|
||||||
<script src="app/theme-bootstrap.js"></script>
|
<script src="app/theme-bootstrap.js"></script>
|
||||||
<link rel="stylesheet" href="style.css?v=20260809-2"/>
|
<link rel="stylesheet" href="style.css?v=20260909-elsewhere"/>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
</head>
|
</head>
|
||||||
<body data-theme="fakegpt" data-theme-mode="light">
|
<body data-theme="fakegpt" data-theme-mode="light">
|
||||||
@@ -15,7 +16,7 @@
|
|||||||
<header class="market-header market-header-simple">
|
<header class="market-header market-header-simple">
|
||||||
<div>
|
<div>
|
||||||
<p class="eyebrow">Shared personas</p>
|
<p class="eyebrow">Shared personas</p>
|
||||||
<h1><span data-theme-name>FakeGPT</span> Market</h1>
|
<h1><span class="brand-wordmark" data-brand-name>elsewhere</span> Market</h1>
|
||||||
</div>
|
</div>
|
||||||
<div class="market-header-actions">
|
<div class="market-header-actions">
|
||||||
<button id="refreshMarket" class="secondary-action" type="button">Refresh</button>
|
<button id="refreshMarket" class="secondary-action" type="button">Refresh</button>
|
||||||
|
|||||||
+2
-2
@@ -59,7 +59,7 @@ const marketPopupDescription = $("marketPopupDescription");
|
|||||||
const marketPopupField = $("marketPopupField");
|
const marketPopupField = $("marketPopupField");
|
||||||
const marketPopupInputLabel = $("marketPopupInputLabel");
|
const marketPopupInputLabel = $("marketPopupInputLabel");
|
||||||
const marketPopupInput = $("marketPopupInput");
|
const marketPopupInput = $("marketPopupInput");
|
||||||
const themeNameTargets = document.querySelectorAll("[data-theme-name]");
|
const brandNameTargets = document.querySelectorAll("[data-brand-name]");
|
||||||
const marketPersonaFields = {
|
const marketPersonaFields = {
|
||||||
name: marketPersonaName,
|
name: marketPersonaName,
|
||||||
pronouns: marketPersonaPronouns,
|
pronouns: marketPersonaPronouns,
|
||||||
@@ -673,7 +673,7 @@ marketPersonaForm.addEventListener("submit", (event) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
window.addEventListener("load", async () => {
|
window.addEventListener("load", async () => {
|
||||||
initializeAppearance({title: (theme) => `${theme.name} Market`, nameTargets: themeNameTargets});
|
initializeAppearance({title: "Elsewhere Market", nameTargets: brandNameTargets});
|
||||||
const params = new URLSearchParams(window.location.search);
|
const params = new URLSearchParams(window.location.search);
|
||||||
setMarketSort("assistant", params.get("assistantSort") || "best", {reload: false});
|
setMarketSort("assistant", params.get("assistantSort") || "best", {reload: false});
|
||||||
setMarketSort("user", params.get("userSort") || "best", {reload: false});
|
setMarketSort("user", params.get("userSort") || "best", {reload: false});
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||||
<title>Privacy Policy – DeepFake</title>
|
<title>Privacy Policy – DeepFake</title>
|
||||||
|
|||||||
+8
-8
@@ -111,8 +111,8 @@ import {
|
|||||||
sendBtn,
|
sendBtn,
|
||||||
saveGenerationSettingsBtn,
|
saveGenerationSettingsBtn,
|
||||||
sessionUser,
|
sessionUser,
|
||||||
themeLogoTargets,
|
brandLogoTargets,
|
||||||
themeNameTargets,
|
brandNameTargets,
|
||||||
toggleButtons,
|
toggleButtons,
|
||||||
userPersonaList
|
userPersonaList
|
||||||
} from "./app/dom.js";
|
} from "./app/dom.js";
|
||||||
@@ -227,8 +227,8 @@ function renderOnboardingStep() {
|
|||||||
onboardingBack.classList.toggle("hidden", onboardingStep === 1);
|
onboardingBack.classList.toggle("hidden", onboardingStep === 1);
|
||||||
onboardingContinue.classList.toggle("hidden", onboardingStep === 2);
|
onboardingContinue.classList.toggle("hidden", onboardingStep === 2);
|
||||||
if (onboardingStep === 1) {
|
if (onboardingStep === 1) {
|
||||||
onboardingTitle.textContent = "What do you want to do?";
|
onboardingTitle.textContent = "Where shall we start?";
|
||||||
onboardingSubtitle.textContent = "Choose one path. You can switch anytime.";
|
onboardingSubtitle.textContent = "Ask a question, explore an idea, or step into a story.";
|
||||||
[["ask", "Ask questions"], ["brainstorm", "Brainstorm ideas"], ["roleplay", "Roleplay with a character"]].forEach(([key, label]) => {
|
[["ask", "Ask questions"], ["brainstorm", "Brainstorm ideas"], ["roleplay", "Roleplay with a character"]].forEach(([key, label]) => {
|
||||||
const button = document.createElement("button");
|
const button = document.createElement("button");
|
||||||
button.type = "button";
|
button.type = "button";
|
||||||
@@ -812,7 +812,7 @@ function renderMessageEmptyState() {
|
|||||||
actions.className = "messages-empty-actions";
|
actions.className = "messages-empty-actions";
|
||||||
|
|
||||||
if (!chat) {
|
if (!chat) {
|
||||||
title.textContent = "Start a chat";
|
title.textContent = "Where shall we start?";
|
||||||
description.textContent = "Choose a starting point.";
|
description.textContent = "Choose a starting point.";
|
||||||
actions.append(
|
actions.append(
|
||||||
createStarterAction("New chat", "primary-action", () => { void createNewChat(); }),
|
createStarterAction("New chat", "primary-action", () => { void createNewChat(); }),
|
||||||
@@ -951,9 +951,9 @@ function updateModelHelp() {
|
|||||||
function applyTheme(themeKey, persist = true) {
|
function applyTheme(themeKey, persist = true) {
|
||||||
applySharedTheme(themeKey, {
|
applySharedTheme(themeKey, {
|
||||||
persist,
|
persist,
|
||||||
title: (theme) => theme.name,
|
title: "Elsewhere",
|
||||||
nameTargets: themeNameTargets,
|
nameTargets: brandNameTargets,
|
||||||
logoTargets: themeLogoTargets
|
logoTargets: brandLogoTargets
|
||||||
});
|
});
|
||||||
updateWorkspaceCopy();
|
updateWorkspaceCopy();
|
||||||
renderModelSection();
|
renderModelSection();
|
||||||
|
|||||||
+14
-13
@@ -1,20 +1,21 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
|
||||||
<meta charset="UTF-8"/>
|
<meta charset="UTF-8"/>
|
||||||
<title>Settings</title>
|
<title>Elsewhere Settings</title>
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;700&family=Manrope:wght@400;500;600;700;800&display=swap" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;700&family=Manrope:wght@400;500;600;700;800&display=swap" rel="stylesheet">
|
||||||
<script src="app/theme-bootstrap.js"></script>
|
<script src="app/theme-bootstrap.js"></script>
|
||||||
<link rel="stylesheet" href="style.css?v=20260809-2"/>
|
<link rel="stylesheet" href="style.css?v=20260909-elsewhere"/>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
</head>
|
</head>
|
||||||
<body data-theme="fakegpt" data-theme-mode="light">
|
<body data-theme="fakegpt" data-theme-mode="light">
|
||||||
<div class="settings-shell card">
|
<div class="settings-shell card">
|
||||||
<header class="market-header market-header-simple">
|
<header class="market-header market-header-simple">
|
||||||
<div>
|
<div>
|
||||||
<p class="eyebrow">Settings</p>
|
<p class="eyebrow">Elsewhere settings</p>
|
||||||
<h1>Preferences</h1>
|
<h1>Preferences</h1>
|
||||||
</div>
|
</div>
|
||||||
<div class="market-header-actions">
|
<div class="market-header-actions">
|
||||||
@@ -135,24 +136,24 @@
|
|||||||
<div class="settings-section-header">
|
<div class="settings-section-header">
|
||||||
<div>
|
<div>
|
||||||
<p class="eyebrow">Appearance</p>
|
<p class="eyebrow">Appearance</p>
|
||||||
<h2>Theme</h2>
|
<h2>Make yourself at home</h2>
|
||||||
<p class="subtitle">Themes are only changed here.</p>
|
<p class="subtitle">Choose a style for your conversation space.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="settings-theme-row">
|
<div class="settings-theme-row">
|
||||||
<label class="field">
|
<label class="field">
|
||||||
<span>Theme</span>
|
<span>Style</span>
|
||||||
<select id="settingsThemeSelect">
|
<select id="settingsThemeSelect">
|
||||||
<option value="fakegpt">FakeGPT</option>
|
<option value="fakegpt">Grove</option>
|
||||||
<option value="fraud">Fraud</option>
|
<option value="fraud">Parchment</option>
|
||||||
<option value="germini">Germini</option>
|
<option value="germini">Aurora</option>
|
||||||
<option value="slopilot">Slopilot</option>
|
<option value="slopilot">Current</option>
|
||||||
<option value="beta-ai">Beta AI</option>
|
<option value="beta-ai">Iris</option>
|
||||||
<option value="confusity">Confusity</option>
|
<option value="confusity">Graphite</option>
|
||||||
</select>
|
</select>
|
||||||
</label>
|
</label>
|
||||||
<label class="field">
|
<label class="field">
|
||||||
<span>Theme mode</span>
|
<span>Light or dark</span>
|
||||||
<select id="themeModeSelect">
|
<select id="themeModeSelect">
|
||||||
<option value="light">Light</option>
|
<option value="light">Light</option>
|
||||||
<option value="dark">Dark</option>
|
<option value="dark">Dark</option>
|
||||||
|
|||||||
+4
-4
@@ -127,7 +127,7 @@ function promptSettingsPopup({
|
|||||||
}
|
}
|
||||||
|
|
||||||
function applyTheme(themeKey, persist = true) {
|
function applyTheme(themeKey, persist = true) {
|
||||||
return applySharedTheme(themeKey, {persist, title: "Settings", themeSelect: settingsThemeSelect});
|
return applySharedTheme(themeKey, {persist, title: "Elsewhere Settings", themeSelect: settingsThemeSelect});
|
||||||
}
|
}
|
||||||
|
|
||||||
function applyThemeMode(modeKey, persist = true) {
|
function applyThemeMode(modeKey, persist = true) {
|
||||||
@@ -526,11 +526,11 @@ passwordForm.addEventListener("submit", async (event) => {
|
|||||||
|
|
||||||
settingsThemeSelect.addEventListener("change", (event) => {
|
settingsThemeSelect.addEventListener("change", (event) => {
|
||||||
applyTheme(event.target.value);
|
applyTheme(event.target.value);
|
||||||
setNotice("Theme updated.", "success");
|
setNotice("Style updated.", "success");
|
||||||
});
|
});
|
||||||
themeModeSelect.addEventListener("change", (event) => {
|
themeModeSelect.addEventListener("change", (event) => {
|
||||||
applyThemeMode(event.target.value);
|
applyThemeMode(event.target.value);
|
||||||
setNotice(`Theme mode set to ${document.body.dataset.themeMode}.`, "success");
|
setNotice(`Appearance set to ${document.body.dataset.themeMode}.`, "success");
|
||||||
});
|
});
|
||||||
workspaceModeSelect.addEventListener("change", (event) => {
|
workspaceModeSelect.addEventListener("change", (event) => {
|
||||||
const mode = event.target.value === "advanced" ? "advanced" : "basic";
|
const mode = event.target.value === "advanced" ? "advanced" : "basic";
|
||||||
@@ -572,7 +572,7 @@ settingsPopupInput.addEventListener("keydown", (event) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
window.addEventListener("load", async () => {
|
window.addEventListener("load", async () => {
|
||||||
initializeAppearance({title: "Settings", themeSelect: settingsThemeSelect, modeSelect: themeModeSelect});
|
initializeAppearance({title: "Elsewhere Settings", themeSelect: settingsThemeSelect, modeSelect: themeModeSelect});
|
||||||
workspaceModeSelect.value = localStorage.getItem("krishd-workspace-mode") || "basic";
|
workspaceModeSelect.value = localStorage.getItem("krishd-workspace-mode") || "basic";
|
||||||
const params = new URLSearchParams(window.location.search);
|
const params = new URLSearchParams(window.location.search);
|
||||||
const view = params.get("view") || "personal";
|
const view = params.get("view") || "personal";
|
||||||
|
|||||||
+8
-1
@@ -1,4 +1,4 @@
|
|||||||
/* KrisHD AI design system — rebuilt from scratch. */
|
/* Elsewhere design system. */
|
||||||
|
|
||||||
/* ---------- Foundation ---------- */
|
/* ---------- Foundation ---------- */
|
||||||
:root {
|
:root {
|
||||||
@@ -611,3 +611,10 @@ input:focus, textarea:focus, select:focus { border-color: var(--brand); }
|
|||||||
@keyframes loading-bar { 0%, 100% { height: 7px; opacity: .45; } 50% { height: 18px; opacity: 1; } }
|
@keyframes loading-bar { 0%, 100% { height: 7px; opacity: .45; } 50% { height: 18px; opacity: 1; } }
|
||||||
@keyframes pulse { 50% { opacity: .35; } }
|
@keyframes pulse { 50% { opacity: .35; } }
|
||||||
@keyframes wave { 50% { height: 28px; } }
|
@keyframes wave { 50% { height: 28px; } }
|
||||||
|
|
||||||
|
/* Permanent Elsewhere identity, shared by every appearance style. */
|
||||||
|
.brand-wordmark { font-family: "Manrope", "Segoe UI", sans-serif; font-weight: 700; letter-spacing: -.055em; }
|
||||||
|
.brand-tagline { margin: 12px 0 0; color: var(--text-soft); font-size: .95rem; }
|
||||||
|
.doorway-mark { position: relative; flex-shrink: 0; }
|
||||||
|
.doorway-mark::before { content: ""; width: 22px; height: 30px; border: 2px solid currentColor; border-bottom: 0; border-radius: 10px 10px 0 0; }
|
||||||
|
.doorway-mark::after { content: ""; position: absolute; width: 13px; height: 25px; left: calc(50% - 10px); top: calc(50% - 8px); border: 2px solid currentColor; background: var(--brand); transform: skewY(-18deg); transform-origin: left top; }
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||||
<title>Terms of Service – DeepFake</title>
|
<title>Terms of Service – DeepFake</title>
|
||||||
|
|||||||
Reference in New Issue
Block a user