implement various changes to styling
This commit is contained in:
+38
-36
@@ -163,12 +163,6 @@
|
||||
|
||||
<div id="messages" class="messages-panel messages-panel-focus"></div>
|
||||
|
||||
<div id="emptyState" class="empty-state">
|
||||
<p class="eyebrow">No messages yet</p>
|
||||
<h3>Write something when you're ready.</h3>
|
||||
<p>This can stay a plain chat. Personas and shared presets are optional.</p>
|
||||
</div>
|
||||
|
||||
<div class="input-shell input-shell-focus">
|
||||
<div class="input-meta">
|
||||
<p class="composer-hint">Enter sends. Shift+Enter adds a new line.</p>
|
||||
@@ -184,40 +178,48 @@
|
||||
</div>
|
||||
|
||||
<div id="personaModal" class="modal-overlay hidden">
|
||||
<div class="modal-card">
|
||||
<div class="modal-card persona-modal-card">
|
||||
<div class="modal-header">
|
||||
<h3 id="personaFormTitle">Create persona</h3>
|
||||
<div class="persona-modal-heading">
|
||||
<p class="eyebrow">Persona editor</p>
|
||||
<h3 id="personaFormTitle">Create persona</h3>
|
||||
</div>
|
||||
<button id="personaClose" type="button" class="icon-button">Cancel</button>
|
||||
</div>
|
||||
<form id="personaForm" class="persona-form">
|
||||
<label class="field">
|
||||
<span>Persona for</span>
|
||||
<select id="personaType">
|
||||
<option value="assistant">AI persona</option>
|
||||
<option value="user">Your persona</option>
|
||||
</select>
|
||||
</label>
|
||||
<p class="persona-helper">AI personas shape the assistant. Your persona gives the model user-side context.</p>
|
||||
<label class="field">
|
||||
<span>Name</span>
|
||||
<input id="personaName" placeholder="Persona name" required/>
|
||||
</label>
|
||||
<label class="field">
|
||||
<span>Pronouns</span>
|
||||
<input id="personaPronouns" placeholder="e.g. she/her, they/them"/>
|
||||
</label>
|
||||
<label class="field">
|
||||
<span>Appearance</span>
|
||||
<textarea id="personaAppearance" rows="2" placeholder="Describe their look"></textarea>
|
||||
</label>
|
||||
<label class="field">
|
||||
<span>Background</span>
|
||||
<textarea id="personaBackground" rows="2" placeholder="Backstory or origins"></textarea>
|
||||
</label>
|
||||
<label class="field">
|
||||
<span>Details</span>
|
||||
<textarea id="personaDetails" rows="3" placeholder="Personality traits, voice, quirks, goals"></textarea>
|
||||
</label>
|
||||
<div class="persona-form-intro">
|
||||
<p class="persona-helper">AI personas shape the assistant. User personas add context for how replies should read you.</p>
|
||||
</div>
|
||||
<p id="personaFormNotice" class="status hidden"></p>
|
||||
<div class="persona-form-grid">
|
||||
<label class="field field-wide">
|
||||
<span>Persona for</span>
|
||||
<select id="personaType">
|
||||
<option value="assistant">AI persona</option>
|
||||
<option value="user">Your persona</option>
|
||||
</select>
|
||||
</label>
|
||||
<label class="field">
|
||||
<span>Persona name</span>
|
||||
<input id="personaName" placeholder="Persona name" required/>
|
||||
</label>
|
||||
<label class="field">
|
||||
<span>Persona pronouns</span>
|
||||
<input id="personaPronouns" placeholder="e.g. she/her, they/them"/>
|
||||
</label>
|
||||
<label class="field field-wide">
|
||||
<span>Appearance</span>
|
||||
<textarea id="personaAppearance" rows="3" placeholder="Describe their look"></textarea>
|
||||
</label>
|
||||
<label class="field field-wide">
|
||||
<span>Background</span>
|
||||
<textarea id="personaBackground" rows="3" placeholder="Backstory, history, role, or origins"></textarea>
|
||||
</label>
|
||||
<label class="field field-wide">
|
||||
<span>Details</span>
|
||||
<textarea id="personaDetails" rows="4" placeholder="Personality traits, voice, goals, quirks, boundaries, style"></textarea>
|
||||
</label>
|
||||
</div>
|
||||
<div class="persona-actions">
|
||||
<button id="personaSave" type="submit" class="primary-action">Save persona</button>
|
||||
</div>
|
||||
|
||||
+19
-9
@@ -1,6 +1,6 @@
|
||||
const $ = (id) => document.getElementById(id);
|
||||
const authDiv = $("auth"), chatDiv = $("chat"), authMsg = $("authMsg");
|
||||
const messagesDiv = $("messages"), emptyState = $("emptyState"), modelSelect = $("model");
|
||||
const messagesDiv = $("messages"), modelSelect = $("model");
|
||||
const loginForm = $("loginForm"), registerForm = $("registerForm"), msgInput = $("msgInput"), sendBtn = $("send");
|
||||
const loginUsernameInput = $("loginUsername"), loginPasswordInput = $("loginPassword");
|
||||
const registerUsernameInput = $("registerUsername"), registerPasswordInput = $("registerPassword");
|
||||
@@ -12,6 +12,7 @@ const personaList = $("personaList"), userPersonaList = $("userPersonaList");
|
||||
const personaForm = $("personaForm"), personaFormTitle = $("personaFormTitle"), personaTypeSelect = $("personaType");
|
||||
const personaNameInput = $("personaName"), personaPronounsInput = $("personaPronouns"), personaAppearanceInput = $("personaAppearance");
|
||||
const personaBackgroundInput = $("personaBackground"), personaDetailsInput = $("personaDetails");
|
||||
const personaFormNotice = $("personaFormNotice");
|
||||
const newPersonaBtn = $("newPersona"), newUserPersonaBtn = $("newUserPersona"), clearPersonaBtn = $("clearPersona"), clearUserPersonaBtn = $("clearUserPersona");
|
||||
const activePersonaStatus = $("activePersonaStatus"), activeUserPersonaStatus = $("activeUserPersonaStatus");
|
||||
const personaModal = $("personaModal"), personaCloseBtn = $("personaClose"), personaMenuButton = $("personaMenuButton"), personaPopover = $("personaPopover");
|
||||
@@ -46,6 +47,16 @@ const del = (url) => request(url, null, "DELETE");
|
||||
|
||||
function setAuthMessage(message, state = "") { authMsg.textContent = message; authMsg.className = state ? `status ${state}` : "status"; }
|
||||
function setNotice(message, state = "") { return {message, state}; }
|
||||
function setPersonaFormNotice(message = "", state = "") {
|
||||
if (!personaFormNotice) return;
|
||||
if (!message) {
|
||||
personaFormNotice.textContent = "";
|
||||
personaFormNotice.className = "status hidden";
|
||||
return;
|
||||
}
|
||||
personaFormNotice.textContent = message;
|
||||
personaFormNotice.className = state ? `status ${state}` : "status";
|
||||
}
|
||||
function setMessageContent(el, content) {
|
||||
if (window.marked && window.DOMPurify) {
|
||||
el.innerHTML = DOMPurify.sanitize(marked.parse(content, {breaks: true}));
|
||||
@@ -53,7 +64,6 @@ function setMessageContent(el, content) {
|
||||
el.textContent = content;
|
||||
}
|
||||
}
|
||||
function updateEmptyState() { emptyState.classList.toggle("visible", currentMessages.length === 0); }
|
||||
function getChatById(id) { return chatSessions.find((chat) => chat.id === id); }
|
||||
|
||||
function addMessage(content, isUser = false, isLoading = false) {
|
||||
@@ -87,7 +97,6 @@ function addMessage(content, isUser = false, isLoading = false) {
|
||||
function renderMessages() {
|
||||
messagesDiv.innerHTML = "";
|
||||
currentMessages.forEach((msg) => addMessage(msg.content, msg.role === "user"));
|
||||
updateEmptyState();
|
||||
updateChatActionState();
|
||||
}
|
||||
|
||||
@@ -178,10 +187,11 @@ function openPersonaForm(persona = null, personaType = "assistant") {
|
||||
personaTypeSelect.value = personaType; personaTypeSelect.disabled = false;
|
||||
personaNameInput.value = ""; personaPronounsInput.value = ""; personaAppearanceInput.value = ""; personaBackgroundInput.value = ""; personaDetailsInput.value = "";
|
||||
}
|
||||
setPersonaFormNotice("");
|
||||
personaNameInput.focus();
|
||||
}
|
||||
|
||||
function closePersonaForm() { personaModal.classList.add("hidden"); editingPersonaId = null; editingPersonaType = "assistant"; personaTypeSelect.disabled = false; }
|
||||
function closePersonaForm() { personaModal.classList.add("hidden"); editingPersonaId = null; editingPersonaType = "assistant"; personaTypeSelect.disabled = false; setPersonaFormNotice(""); }
|
||||
function closePersonaPopover() { personaPopover.classList.add("hidden"); personaMenuButton.setAttribute("aria-expanded", "false"); }
|
||||
|
||||
function renderPersonaList(items, activeId, listElement, personaType) {
|
||||
@@ -252,9 +262,9 @@ async function clearPersona(type) {
|
||||
|
||||
async function savePersona() {
|
||||
const payload = {personaType: personaTypeSelect.value, name: personaNameInput.value.trim(), pronouns: personaPronounsInput.value.trim(), appearance: personaAppearanceInput.value.trim(), background: personaBackgroundInput.value.trim(), details: personaDetailsInput.value.trim()};
|
||||
if (!payload.name) return setNotice("Persona name is required.", "error");
|
||||
if (!payload.name) return setPersonaFormNotice("Persona name is required.", "error");
|
||||
const res = editingPersonaId ? await put(`/personas/${editingPersonaId}`, payload) : await post("/personas", payload);
|
||||
if (res.error) return setNotice(res.error, "error");
|
||||
if (res.error) return setPersonaFormNotice(res.error, "error");
|
||||
const wasEditing = Boolean(editingPersonaId);
|
||||
await loadPersonas(); closePersonaForm(); setNotice(wasEditing ? "Persona updated." : "Persona created.", "success");
|
||||
}
|
||||
@@ -391,7 +401,7 @@ async function sendMessage() {
|
||||
const autoTitle = message.length > 40 ? `${message.slice(0, 40)}...` : message;
|
||||
currentChat.title = autoTitle; updateWorkspaceCopy(); renderChatList(); await put(`/chats/${activeChatId}`, {title: autoTitle});
|
||||
}
|
||||
currentMessages.push({role: "user", content: message}); addMessage(message, true); updateEmptyState(); updateChatActionState();
|
||||
currentMessages.push({role: "user", content: message}); addMessage(message, true); updateChatActionState();
|
||||
msgInput.value = ""; msgInput.style.height = "auto"; setLoadingState(true); setNotice("Generating reply...");
|
||||
const loadingMsg = addMessage("", false, true);
|
||||
try {
|
||||
@@ -423,7 +433,7 @@ registerForm.addEventListener("submit", (event) => { event.preventDefault(); han
|
||||
$("logout").addEventListener("click", async () => {
|
||||
await post("/logout", {}); chatDiv.style.display = "none"; authDiv.style.display = "grid";
|
||||
activeChatId = null; currentUsername = ""; currentSummary = null; chatSessions = []; currentMessages = []; assistantPersonas = []; userPersonas = [];
|
||||
activePersonaId = null; activeUserPersonaId = null; publishedPersonaIds = new Set(); messagesDiv.innerHTML = ""; renderChatList(); updateEmptyState(); updateChatActionState();
|
||||
activePersonaId = null; activeUserPersonaId = null; publishedPersonaIds = new Set(); messagesDiv.innerHTML = ""; renderChatList(); updateChatActionState();
|
||||
showAuthScreen("login"); setAuthMessage("Logged out.", "success"); setNotice("Ready.");
|
||||
});
|
||||
sendBtn.addEventListener("click", sendMessage);
|
||||
@@ -440,5 +450,5 @@ personaMenuButton.addEventListener("click", togglePersonaPopover); personaPopove
|
||||
document.addEventListener("keydown", (event) => { if (event.key === "Escape") { closePersonaPopover(); closePersonaForm(); } });
|
||||
window.addEventListener("load", async () => {
|
||||
applyTheme(localStorage.getItem("krishd-theme") || "fakegpt", false);
|
||||
setNotice("Ready."); updateEmptyState(); updateChatActionState(); await checkSession();
|
||||
setNotice("Ready."); updateChatActionState(); await checkSession();
|
||||
});
|
||||
|
||||
+96
-25
@@ -334,8 +334,7 @@ h2 {
|
||||
.subtitle,
|
||||
.persona-guidance,
|
||||
.persona-helper,
|
||||
.composer-hint,
|
||||
.empty-state p:last-child {
|
||||
.composer-hint {
|
||||
margin: 0;
|
||||
color: var(--text-soft);
|
||||
line-height: 1.6;
|
||||
@@ -390,7 +389,6 @@ h2 {
|
||||
.input-shell,
|
||||
.chat-sidebar,
|
||||
.messages-panel,
|
||||
.empty-state,
|
||||
.persona-popover,
|
||||
.modal-card,
|
||||
.market-shell {
|
||||
@@ -758,7 +756,6 @@ select:focus {
|
||||
|
||||
.workspace-overview,
|
||||
.messages-panel,
|
||||
.empty-state,
|
||||
.input-shell {
|
||||
border-radius: var(--radius-lg);
|
||||
padding: 14px;
|
||||
@@ -863,18 +860,6 @@ select:focus {
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.empty-state {
|
||||
display: none;
|
||||
align-content: center;
|
||||
justify-items: start;
|
||||
gap: 8px;
|
||||
background: rgba(250, 244, 235, 0.75);
|
||||
}
|
||||
|
||||
.empty-state.visible {
|
||||
display: grid;
|
||||
}
|
||||
|
||||
.msg {
|
||||
max-width: min(78%, 780px);
|
||||
padding: 14px 16px;
|
||||
@@ -1175,22 +1160,83 @@ select:focus {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
padding: 24px;
|
||||
background: rgba(24, 32, 31, 0.16);
|
||||
backdrop-filter: blur(4px);
|
||||
background: rgba(12, 16, 18, 0.3);
|
||||
backdrop-filter: blur(10px);
|
||||
z-index: 50;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.modal-card {
|
||||
width: min(560px, 95vw);
|
||||
width: min(760px, 95vw);
|
||||
max-height: calc(100vh - 48px);
|
||||
border-radius: var(--radius-lg);
|
||||
padding: 18px;
|
||||
padding: 20px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.persona-form {
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
gap: 18px;
|
||||
padding: 0;
|
||||
border: none;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.persona-modal-card {
|
||||
display: grid;
|
||||
gap: 18px;
|
||||
}
|
||||
|
||||
.persona-modal-heading {
|
||||
display: grid;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.persona-form-intro {
|
||||
padding: 16px 18px;
|
||||
border-radius: 16px;
|
||||
background: rgba(24, 32, 31, 0.04);
|
||||
border: 1px solid rgba(24, 32, 31, 0.08);
|
||||
}
|
||||
|
||||
.persona-form > .status {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.persona-form-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: 14px;
|
||||
}
|
||||
|
||||
.field-wide {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.persona-form .field,
|
||||
.persona-form .field-wide {
|
||||
padding: 14px;
|
||||
border-radius: var(--radius-md);
|
||||
background: rgba(24, 32, 31, 0.03);
|
||||
border: 1px solid rgba(24, 32, 31, 0.06);
|
||||
}
|
||||
|
||||
.persona-form .field textarea {
|
||||
min-height: 112px;
|
||||
}
|
||||
|
||||
.persona-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
position: sticky;
|
||||
bottom: 0;
|
||||
padding-top: 10px;
|
||||
background: inherit;
|
||||
}
|
||||
|
||||
.persona-actions .primary-action {
|
||||
width: auto;
|
||||
min-width: 180px;
|
||||
}
|
||||
|
||||
.market-shell {
|
||||
@@ -1432,7 +1478,9 @@ body[data-theme="fakegpt"] .chat-item button,
|
||||
body[data-theme="fakegpt"] .session-chip,
|
||||
body[data-theme="fakegpt"] .settings-nav,
|
||||
body[data-theme="fakegpt"] .settings-nav-item:not(.active),
|
||||
body[data-theme="fakegpt"] .settings-theme-note {
|
||||
body[data-theme="fakegpt"] .settings-theme-note,
|
||||
body[data-theme="fakegpt"] .persona-form-intro,
|
||||
body[data-theme="fakegpt"] .persona-form .field {
|
||||
background: rgba(18, 24, 21, 0.96);
|
||||
color: #d7fff3;
|
||||
border: 1px solid rgba(36, 255, 180, 0.16);
|
||||
@@ -1515,7 +1563,9 @@ body[data-theme="fraud"] .icon-button,
|
||||
body[data-theme="fraud"] .session-chip,
|
||||
body[data-theme="fraud"] .settings-nav,
|
||||
body[data-theme="fraud"] .settings-nav-item:not(.active),
|
||||
body[data-theme="fraud"] .settings-theme-note {
|
||||
body[data-theme="fraud"] .settings-theme-note,
|
||||
body[data-theme="fraud"] .persona-form-intro,
|
||||
body[data-theme="fraud"] .persona-form .field {
|
||||
background: rgba(255, 249, 242, 0.88);
|
||||
color: #4b3d31;
|
||||
border: 1px solid rgba(84, 62, 43, 0.08);
|
||||
@@ -1628,7 +1678,9 @@ body[data-theme="slopilot"] .session-chip {
|
||||
|
||||
body[data-theme="slopilot"] .settings-nav,
|
||||
body[data-theme="slopilot"] .settings-nav-item:not(.active),
|
||||
body[data-theme="slopilot"] .settings-theme-note {
|
||||
body[data-theme="slopilot"] .settings-theme-note,
|
||||
body[data-theme="slopilot"] .persona-form-intro,
|
||||
body[data-theme="slopilot"] .persona-form .field {
|
||||
background: #ffffff;
|
||||
border-color: rgba(13, 104, 255, 0.12);
|
||||
}
|
||||
@@ -1714,7 +1766,9 @@ body[data-theme="confusity"] .session-chip {
|
||||
|
||||
body[data-theme="confusity"] .settings-nav,
|
||||
body[data-theme="confusity"] .settings-nav-item:not(.active),
|
||||
body[data-theme="confusity"] .settings-theme-note {
|
||||
body[data-theme="confusity"] .settings-theme-note,
|
||||
body[data-theme="confusity"] .persona-form-intro,
|
||||
body[data-theme="confusity"] .persona-form .field {
|
||||
background: #ffffff;
|
||||
border-color: rgba(17, 24, 39, 0.08);
|
||||
}
|
||||
@@ -1795,6 +1849,19 @@ body[data-theme="confusity"] .settings-nav-item.active {
|
||||
border: 1px solid rgba(17, 24, 39, 0.16);
|
||||
}
|
||||
|
||||
body[data-theme="germini"] .persona-form-intro,
|
||||
body[data-theme="germini"] .persona-form .field {
|
||||
background: rgba(255, 255, 255, 0.26);
|
||||
border: 1px solid rgba(255, 255, 255, 0.3);
|
||||
backdrop-filter: blur(18px);
|
||||
}
|
||||
|
||||
body[data-theme="beta-ai"] .persona-form-intro,
|
||||
body[data-theme="beta-ai"] .persona-form .field {
|
||||
background: linear-gradient(180deg, rgba(255, 255, 255, 0.88), rgba(243, 238, 255, 0.92));
|
||||
border: 1px solid rgba(90, 103, 255, 0.08);
|
||||
}
|
||||
|
||||
@keyframes gemFloat {
|
||||
0%, 100% {
|
||||
transform: translateY(0);
|
||||
@@ -1923,6 +1990,10 @@ body[data-theme="confusity"] .settings-nav-item.active {
|
||||
justify-self: stretch;
|
||||
}
|
||||
|
||||
.persona-form-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.settings-shell .market-header-simple {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user