Revamp workspace archive handling with async support, input validation improvements and better session management
This commit is contained in:
+65
-65
@@ -12,77 +12,77 @@
|
||||
<link rel="stylesheet" href="/css/pages.css?v=20260909-account-controls">
|
||||
<link rel="stylesheet" href="/css/shell.css?v=20260909-account-controls">
|
||||
<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">
|
||||
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">
|
||||
</head>
|
||||
|
||||
<body class="site-page account-page">
|
||||
<!-- site-header -->
|
||||
<main id="main" class="account-layout page-content">
|
||||
<section class="account-intro">
|
||||
<p class="eyebrow">Welcome to elsewhere</p>
|
||||
<h1 id="accountHeadline">Pick up where<br>curiosity left off.</h1>
|
||||
<p>A space for your ideas, your characters, and the conversations worth coming back to.</p>
|
||||
<a href="/">← Back to Elsewhere</a>
|
||||
</section>
|
||||
<section class="account-box">
|
||||
<h2 id="accountTitle">Sign in</h2>
|
||||
<p id="accountDescription" class="muted">Welcome back. Your conversations are waiting.</p>
|
||||
<form id="accountForm">
|
||||
<label class="field">
|
||||
<span>Username</span>
|
||||
<input name="username" autocomplete="username" required minlength="3">
|
||||
</label>
|
||||
<div class="field">
|
||||
<label for="accountPassword">Password</label>
|
||||
<div class="password-input">
|
||||
<input id="accountPassword" name="password" type="password" autocomplete="current-password"
|
||||
required minlength="6">
|
||||
<button type="button" id="showPassword" class="icon-button password-toggle"
|
||||
<!-- site-header -->
|
||||
<main id="main" class="account-layout page-content">
|
||||
<section class="account-intro">
|
||||
<p class="eyebrow">Welcome to elsewhere</p>
|
||||
<h1 id="accountHeadline">Pick up where<br>curiosity left off.</h1>
|
||||
<p>A space for your ideas, your characters, and the conversations worth coming back to.</p>
|
||||
<a href="/">← Back to Elsewhere</a>
|
||||
</section>
|
||||
<section class="account-box">
|
||||
<h2 id="accountTitle">Sign in</h2>
|
||||
<p id="accountDescription" class="muted">Welcome back. Your conversations are waiting.</p>
|
||||
<form id="accountForm">
|
||||
<label class="field">
|
||||
<span>Username</span>
|
||||
<input name="username" autocomplete="username" required minlength="3">
|
||||
</label>
|
||||
<div class="field">
|
||||
<label for="accountPassword">Password</label>
|
||||
<div class="password-input">
|
||||
<input id="accountPassword" name="password" type="password" autocomplete="current-password"
|
||||
required minlength="6">
|
||||
<button type="button" id="showPassword" class="icon-button password-toggle"
|
||||
aria-label="Show password" title="Show password" aria-controls="accountPassword"
|
||||
aria-pressed="false">
|
||||
<svg viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
|
||||
stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||
<path d="M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7S2 12 2 12Z" />
|
||||
<circle cx="12" cy="12" r="3" />
|
||||
<path class="eye-slash" d="m3 3 18 18" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<svg viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"
|
||||
stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||
<path d="M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7S2 12 2 12Z"/>
|
||||
<circle cx="12" cy="12" r="3"/>
|
||||
<path class="eye-slash" d="m3 3 18 18"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<label id="inviteField" class="field hidden">
|
||||
<span>Invite code</span>
|
||||
<input name="inviteCode" autocomplete="off">
|
||||
</label>
|
||||
<label id="consentField" class="consent-container hidden">
|
||||
<input name="consent" type="checkbox">
|
||||
<span>I agree to the <a href="/tos.html" target="_blank" rel="noopener">Terms</a> and <a
|
||||
href="/privacy.html" target="_blank" rel="noopener">Privacy Policy</a>.</span>
|
||||
</label>
|
||||
<div id="accountStatus" class="account-status hidden" role="status" aria-live="polite"
|
||||
aria-atomic="true" tabindex="-1">
|
||||
<svg class="account-error-icon" viewBox="0 0 24 24" width="20" height="20" fill="none"
|
||||
stroke="currentColor" stroke-width="2" aria-hidden="true">
|
||||
<circle cx="12" cy="12" r="9" />
|
||||
<path d="M12 7v6m0 3v1" />
|
||||
</svg>
|
||||
<span id="accountStatusText"></span>
|
||||
</div>
|
||||
<button id="accountSubmit" class="primary-action" type="submit">Sign in</button>
|
||||
</form>
|
||||
<p id="accountSwitch">
|
||||
</p>
|
||||
</section>
|
||||
</main>
|
||||
<footer class="site-footer">
|
||||
<a class="site-brand" href="/">elsewhere</a>
|
||||
<span>A space for every conversation.</span>
|
||||
<a href="/privacy.html">Privacy</a>
|
||||
<a href="/tos.html">Terms</a>
|
||||
</footer>
|
||||
<script type="module" src="/js/pages.js?v=20260909-account-controls">
|
||||
</script>
|
||||
<script type="module" src="/js/workspaceNavigation.js?v=20260909-account-controls"></script>
|
||||
</div>
|
||||
<label id="inviteField" class="field hidden">
|
||||
<span>Invite code</span>
|
||||
<input name="inviteCode" autocomplete="off">
|
||||
</label>
|
||||
<label id="consentField" class="consent-container hidden">
|
||||
<input name="consent" type="checkbox">
|
||||
<span>I agree to the <a href="/tos.html" target="_blank" rel="noopener">Terms</a> and <a
|
||||
href="/privacy.html" target="_blank" rel="noopener">Privacy Policy</a>.</span>
|
||||
</label>
|
||||
<div id="accountStatus" class="account-status hidden" role="status" aria-live="polite"
|
||||
aria-atomic="true" tabindex="-1">
|
||||
<svg class="account-error-icon" viewBox="0 0 24 24" width="20" height="20" fill="none"
|
||||
stroke="currentColor" stroke-width="2" aria-hidden="true">
|
||||
<circle cx="12" cy="12" r="9"/>
|
||||
<path d="M12 7v6m0 3v1"/>
|
||||
</svg>
|
||||
<span id="accountStatusText"></span>
|
||||
</div>
|
||||
<button id="accountSubmit" class="primary-action" type="submit">Sign in</button>
|
||||
</form>
|
||||
<p id="accountSwitch">
|
||||
</p>
|
||||
</section>
|
||||
</main>
|
||||
<footer class="site-footer">
|
||||
<a class="site-brand" href="/">elsewhere</a>
|
||||
<span>A space for every conversation.</span>
|
||||
<a href="/privacy.html">Privacy</a>
|
||||
<a href="/tos.html">Terms</a>
|
||||
</footer>
|
||||
<script type="module" src="/js/pages.js?v=20260909-account-controls">
|
||||
</script>
|
||||
<script type="module" src="/js/workspaceNavigation.js?v=20260909-account-controls"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
+415
-367
@@ -2,457 +2,505 @@
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta charset="UTF-8"/>
|
||||
<link rel="icon" type="image/svg+xml" href="/img/favicon.svg">
|
||||
<title>Elsewhere</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<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">
|
||||
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="/js/theme-bootstrap.js?v=20260909-account-controls"></script>
|
||||
<link rel="stylesheet" href="/css/style.css?v=20261012-chat-usability" />
|
||||
<link rel="stylesheet" href="/css/style.css?v=20261012-chat-usability"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="/css/pages.css?v=20260909-account-controls">
|
||||
<link rel="stylesheet" href="/css/shell.css?v=20260909-account-controls">
|
||||
</head>
|
||||
|
||||
<body class="site-page chat-page" data-theme="fakegpt" data-theme-mode="light">
|
||||
<!-- site-header -->
|
||||
<div class="app-shell">
|
||||
<section id="chat" class="card chat-card chat-focus-card hidden" aria-label="AI chat workspace">
|
||||
<div class="chat-layout chat-layout-focus">
|
||||
<aside id="chatSidebar" class="chat-sidebar" aria-label="Conversation history">
|
||||
<div class="sidebar-top">
|
||||
<div class="sidebar-workspace-card">
|
||||
<h2>Conversations</h2><button id="newChat" class="primary-action" type="button">New
|
||||
chat</button>
|
||||
</div>
|
||||
<label class="field compact-field">
|
||||
<span>Search</span>
|
||||
<input id="chatSearch" type="search" placeholder="Search chats" />
|
||||
</label>
|
||||
<!-- site-header -->
|
||||
<div class="app-shell">
|
||||
<section id="chat" class="card chat-card chat-focus-card hidden" aria-label="AI chat workspace">
|
||||
<div class="chat-layout chat-layout-focus">
|
||||
<aside id="chatSidebar" class="chat-sidebar" aria-label="Conversation history">
|
||||
<div class="sidebar-top">
|
||||
<div class="sidebar-workspace-card">
|
||||
<h2>Conversations</h2>
|
||||
<button id="newChat" class="primary-action" type="button">New
|
||||
chat
|
||||
</button>
|
||||
</div>
|
||||
<div class="sidebar-middle">
|
||||
<div id="chatList" class="chat-list chat-list-grouped"></div>
|
||||
<div id="chatListLoading" class="chat-loading hidden" role="status" aria-live="polite">
|
||||
<span class="chat-loading-dot" aria-hidden="true"></span>
|
||||
<span id="chatListLoadingText">Loading chats...</span>
|
||||
</div>
|
||||
<label class="field compact-field">
|
||||
<span>Search</span>
|
||||
<input id="chatSearch" type="search" placeholder="Search chats"/>
|
||||
</label>
|
||||
</div>
|
||||
<div class="sidebar-middle">
|
||||
<div id="chatList" class="chat-list chat-list-grouped"></div>
|
||||
<div id="chatListLoading" class="chat-loading hidden" role="status" aria-live="polite">
|
||||
<span class="chat-loading-dot" aria-hidden="true"></span>
|
||||
<span id="chatListLoadingText">Loading chats...</span>
|
||||
</div>
|
||||
</aside>
|
||||
<button id="chatSidebarBackdrop" class="chat-sidebar-backdrop" type="button"
|
||||
</div>
|
||||
</aside>
|
||||
<button id="chatSidebarBackdrop" class="chat-sidebar-backdrop" type="button"
|
||||
aria-label="Close conversation history" hidden></button>
|
||||
|
||||
<section id="main" class="chat-main chat-main-focus" aria-label="Active conversation">
|
||||
<div class="chat-heading">
|
||||
<p id="workspaceNotice" class="status hidden" role="status" aria-live="polite"></p>
|
||||
<header class="chat-header chat-header-focus">
|
||||
<button id="chatSidebarToggle" class="icon-button sidebar-toggle" type="button"
|
||||
<section id="main" class="chat-main chat-main-focus" aria-label="Active conversation">
|
||||
<div class="chat-heading">
|
||||
<p id="workspaceNotice" class="status hidden" role="status" aria-live="polite"></p>
|
||||
<header class="chat-header chat-header-focus">
|
||||
<button id="chatSidebarToggle" class="icon-button sidebar-toggle" type="button"
|
||||
aria-controls="chatSidebar" aria-expanded="false"
|
||||
aria-label="Open conversation history">History</button>
|
||||
<div class="chat-title-block">
|
||||
<div class="chat-title">
|
||||
<h2 id="activeChatTitle">New chat</h2>
|
||||
</div>
|
||||
<div class="chat-header-context" aria-label="Current chat setup">
|
||||
<button id="headerModelButton"
|
||||
aria-label="Open conversation history">History
|
||||
</button>
|
||||
<div class="chat-title-block">
|
||||
<div class="chat-title">
|
||||
<h2 id="activeChatTitle">New chat</h2>
|
||||
</div>
|
||||
<div class="chat-header-context" aria-label="Current chat setup">
|
||||
<button id="headerModelButton"
|
||||
class="chat-context-item chat-context-button secondary-action" type="button"
|
||||
aria-controls="chatDrawer"
|
||||
aria-label="Change AI model"><span>Model</span><strong
|
||||
id="headerModelName">Loading...</strong></button>
|
||||
<label class="chat-context-item"><span>Chat with</span><select id="personalitySelect" aria-label="Conversation personality"></select></label>
|
||||
</div>
|
||||
id="headerModelName">Loading...</strong></button>
|
||||
<label class="chat-context-item"><span>Chat with</span><select id="personalitySelect"
|
||||
aria-label="Conversation personality"></select></label>
|
||||
</div>
|
||||
<div class="chat-header-actions">
|
||||
<div class="chat-actions-menu">
|
||||
<button id="chatDrawerButton" class="secondary-action overflow-trigger"
|
||||
</div>
|
||||
<div class="chat-header-actions">
|
||||
<div class="chat-actions-menu">
|
||||
<button id="chatDrawerButton" class="secondary-action overflow-trigger"
|
||||
type="button" aria-expanded="false" aria-controls="chatDrawer">
|
||||
<span class="overflow-trigger-label">Chat settings</span>
|
||||
</button>
|
||||
<div id="chatDrawer" class="chat-drawer hidden" role="dialog" aria-modal="true"
|
||||
aria-labelledby="chatDrawerTitle">
|
||||
<div class="chat-drawer-panel">
|
||||
<div class="chat-drawer-header">
|
||||
<div>
|
||||
<p class="eyebrow">Conversation</p>
|
||||
<h2 id="chatDrawerTitle">Settings</h2>
|
||||
</div>
|
||||
<button id="chatDrawerClose" class="icon-button" type="button"
|
||||
aria-label="Close chat settings">×</button>
|
||||
<span class="overflow-trigger-label">Chat settings</span>
|
||||
</button>
|
||||
<div id="chatDrawer" class="chat-drawer hidden" role="dialog" aria-modal="true"
|
||||
aria-labelledby="chatDrawerTitle">
|
||||
<div class="chat-drawer-panel">
|
||||
<div class="chat-drawer-header">
|
||||
<div>
|
||||
<p class="eyebrow">Conversation</p>
|
||||
<h2 id="chatDrawerTitle">Settings</h2>
|
||||
</div>
|
||||
<div class="chat-drawer-body">
|
||||
<div class="chat-drawer-summary">
|
||||
<div class="chat-drawer-pills">
|
||||
<button id="chatDrawerClose" class="icon-button" type="button"
|
||||
aria-label="Close chat settings">×
|
||||
</button>
|
||||
</div>
|
||||
<div class="chat-drawer-body">
|
||||
<div class="chat-drawer-summary">
|
||||
<div class="chat-drawer-pills">
|
||||
<span id="chatCharacterPill"
|
||||
class="context-pill hidden">Character: none</span>
|
||||
<span id="chatUserPersonaPill" class="context-pill hidden">User
|
||||
class="context-pill hidden">Character: none</span>
|
||||
<span id="chatUserPersonaPill" class="context-pill hidden">User
|
||||
persona: none</span>
|
||||
</div>
|
||||
</div>
|
||||
<details
|
||||
</div>
|
||||
<details
|
||||
class="chat-drawer-section chat-drawer-disclosure chat-drawer-section--model"
|
||||
open>
|
||||
<summary class="chat-drawer-row">
|
||||
<summary class="chat-drawer-row">
|
||||
<span class="chat-drawer-row-label">
|
||||
<span class="eyebrow">AI model</span>
|
||||
<strong>Model</strong>
|
||||
</span>
|
||||
<span class="chat-drawer-row-meta">
|
||||
<span class="chat-drawer-row-meta">
|
||||
<strong id="modelBadgeName">Loading...</strong>
|
||||
<span class="chat-drawer-row-hint">Change</span>
|
||||
</span>
|
||||
</summary>
|
||||
<div id="modelPanel"
|
||||
class="model-panel chat-drawer-disclosure-panel"
|
||||
data-static-panel="true">
|
||||
<div class="model-select">
|
||||
<div class="model-select-header">
|
||||
<label for="model">Model</label>
|
||||
<span id="modelCount" class="model-count">Loading</span>
|
||||
</div>
|
||||
<div class="model-select-control">
|
||||
<select id="model">
|
||||
<option disabled selected>Loading models...</option>
|
||||
</select>
|
||||
<span class="model-select-chevron"
|
||||
aria-hidden="true"></span>
|
||||
</div>
|
||||
</summary>
|
||||
<div id="modelPanel"
|
||||
class="model-panel chat-drawer-disclosure-panel"
|
||||
data-static-panel="true">
|
||||
<div class="model-select">
|
||||
<div class="model-select-header">
|
||||
<label for="model">Model</label>
|
||||
<span id="modelCount" class="model-count">Loading</span>
|
||||
</div>
|
||||
<div id="modelHelp" class="model-help" aria-live="polite">
|
||||
<div class="model-help-header">
|
||||
<strong id="modelHelpTitle">Choose a model</strong>
|
||||
<span id="modelHelpBadge"
|
||||
class="model-help-badge">Waiting</span>
|
||||
</div>
|
||||
<p id="modelHelpSummary" class="model-help-summary">Pick a
|
||||
model to see what it is best suited for.</p>
|
||||
<div class="model-select-control">
|
||||
<select id="model">
|
||||
<option disabled selected>Loading models...</option>
|
||||
</select>
|
||||
<span class="model-select-chevron"
|
||||
aria-hidden="true"></span>
|
||||
</div>
|
||||
</div>
|
||||
</details>
|
||||
<details class="chat-drawer-section generation-advanced">
|
||||
<summary class="chat-drawer-row"><span class="chat-drawer-row-label"><strong>Generation settings</strong></span><span class="chat-drawer-row-hint">Advanced</span></summary>
|
||||
<div class="generation-settings-grid chat-drawer-disclosure-panel">
|
||||
<label class="field"><span>Temperature</span><input
|
||||
id="chatTemperature" type="number" min="0" max="2"
|
||||
step="0.1" placeholder="Default" /></label>
|
||||
<label class="field"><span>Context length</span><input
|
||||
id="chatContextLength" type="number" min="256"
|
||||
max="131072" placeholder="Default" /></label>
|
||||
<label class="field"><span>Response length</span><input
|
||||
id="chatResponseLength" type="number" min="1"
|
||||
max="32768" placeholder="Default" /></label>
|
||||
<label class="field field-wide"><span>System
|
||||
instruction</span><textarea
|
||||
id="chatSystemInstruction" rows="4" maxlength="8000"
|
||||
placeholder="Optional instructions for this chat"></textarea></label>
|
||||
<button id="saveGenerationSettings" type="button">Save
|
||||
generation settings</button>
|
||||
<div id="modelHelp" class="model-help" aria-live="polite">
|
||||
<div class="model-help-header">
|
||||
<strong id="modelHelpTitle">Choose a model</strong>
|
||||
<span id="modelHelpBadge"
|
||||
class="model-help-badge">Waiting</span>
|
||||
</div>
|
||||
</details>
|
||||
<div class="chat-drawer-section">
|
||||
<p class="dropdown-section-label">Conversation actions</p>
|
||||
<div class="chat-drawer-action-list">
|
||||
<button id="renameChat"
|
||||
class="secondary-action chat-drawer-action" type="button"
|
||||
data-chat-action="rename">Rename chat</button>
|
||||
<button id="pinChat" class="secondary-action chat-drawer-action"
|
||||
type="button" data-chat-action="pin">Pin</button>
|
||||
<button id="archiveChat"
|
||||
class="secondary-action chat-drawer-action" type="button"
|
||||
data-chat-action="archive">Archive</button>
|
||||
<button id="exportChat"
|
||||
class="secondary-action chat-drawer-action" type="button"
|
||||
data-chat-action="export">Export</button>
|
||||
<p id="modelHelpSummary" class="model-help-summary">Pick a
|
||||
model to see what it is best suited for.</p>
|
||||
</div>
|
||||
</div>
|
||||
<details class="chat-drawer-section chat-drawer-more">
|
||||
<summary class="chat-drawer-row chat-drawer-row--compact">
|
||||
</details>
|
||||
<details class="chat-drawer-section generation-advanced">
|
||||
<summary class="chat-drawer-row"><span
|
||||
class="chat-drawer-row-label"><strong>Generation settings</strong></span><span
|
||||
class="chat-drawer-row-hint">Advanced</span></summary>
|
||||
<div class="generation-settings-grid chat-drawer-disclosure-panel">
|
||||
<label class="field"><span>Temperature</span><input
|
||||
id="chatTemperature" type="number" min="0" max="2"
|
||||
step="0.1" placeholder="Default"/></label>
|
||||
<label class="field"><span>Context length</span><input
|
||||
id="chatContextLength" type="number" min="256"
|
||||
max="131072" placeholder="Default"/></label>
|
||||
<label class="field"><span>Response length</span><input
|
||||
id="chatResponseLength" type="number" min="1"
|
||||
max="32768" placeholder="Default"/></label>
|
||||
<label class="field field-wide"><span>System
|
||||
instruction</span><textarea
|
||||
id="chatSystemInstruction" rows="4" maxlength="8000"
|
||||
placeholder="Optional instructions for this chat"></textarea></label>
|
||||
<button id="saveGenerationSettings" type="button">Save
|
||||
generation settings
|
||||
</button>
|
||||
</div>
|
||||
</details>
|
||||
<div class="chat-drawer-section">
|
||||
<p class="dropdown-section-label">Conversation actions</p>
|
||||
<div class="chat-drawer-action-list">
|
||||
<button id="renameChat"
|
||||
class="secondary-action chat-drawer-action" type="button"
|
||||
data-chat-action="rename">Rename chat
|
||||
</button>
|
||||
<button id="pinChat" class="secondary-action chat-drawer-action"
|
||||
type="button" data-chat-action="pin">Pin
|
||||
</button>
|
||||
<button id="archiveChat"
|
||||
class="secondary-action chat-drawer-action" type="button"
|
||||
data-chat-action="archive">Archive
|
||||
</button>
|
||||
<button id="exportChat"
|
||||
class="secondary-action chat-drawer-action" type="button"
|
||||
data-chat-action="export">Export
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<details class="chat-drawer-section chat-drawer-more">
|
||||
<summary class="chat-drawer-row chat-drawer-row--compact">
|
||||
<span class="chat-drawer-row-label">
|
||||
<strong>Conversation tools</strong>
|
||||
</span>
|
||||
<span class="chat-drawer-row-hint">Show</span>
|
||||
</summary>
|
||||
<div class="chat-drawer-action-list chat-drawer-disclosure-panel">
|
||||
<button id="moveChatFolder"
|
||||
<span class="chat-drawer-row-hint">Show</span>
|
||||
</summary>
|
||||
<div class="chat-drawer-action-list chat-drawer-disclosure-panel">
|
||||
<button id="moveChatFolder"
|
||||
class="secondary-action chat-drawer-action" type="button"
|
||||
data-chat-action="folder">Move to folder</button>
|
||||
<button id="manageChatMemory"
|
||||
data-chat-action="folder">Move to folder
|
||||
</button>
|
||||
<button id="manageChatMemory"
|
||||
class="secondary-action chat-drawer-action" type="button"
|
||||
data-chat-action="memory">Conversation memory</button>
|
||||
<button id="exploreBranches" type="button" class="secondary-action chat-drawer-action" data-chat-action="branches">Branches & compare</button>
|
||||
<button id="managePersonaState"
|
||||
class="secondary-action chat-drawer-action" type="button"
|
||||
data-chat-action="personaState">Roleplay state</button>
|
||||
</div>
|
||||
</details>
|
||||
<details class="chat-drawer-section chat-drawer-more">
|
||||
<summary class="chat-drawer-row chat-drawer-row--compact"><span class="chat-drawer-row-label"><strong>Workspace files</strong></span><span class="chat-drawer-row-hint">Show</span></summary>
|
||||
<div class="chat-drawer-action-list chat-drawer-disclosure-panel">
|
||||
<button id="backupWorkspace"
|
||||
data-chat-action="memory">Conversation memory
|
||||
</button>
|
||||
<button id="exploreBranches" type="button"
|
||||
class="secondary-action chat-drawer-action"
|
||||
type="button">Download workspace archive</button>
|
||||
<button id="importWorkspace"
|
||||
data-chat-action="branches">Branches & compare
|
||||
</button>
|
||||
<button id="managePersonaState"
|
||||
class="secondary-action chat-drawer-action" type="button"
|
||||
data-chat-action="personaState">Roleplay state
|
||||
</button>
|
||||
</div>
|
||||
</details>
|
||||
<details class="chat-drawer-section chat-drawer-more">
|
||||
<summary class="chat-drawer-row chat-drawer-row--compact"><span
|
||||
class="chat-drawer-row-label"><strong>Workspace files</strong></span><span
|
||||
class="chat-drawer-row-hint">Show</span></summary>
|
||||
<div class="chat-drawer-action-list chat-drawer-disclosure-panel">
|
||||
<button id="backupWorkspace"
|
||||
class="secondary-action chat-drawer-action"
|
||||
type="button">Import workspace</button>
|
||||
<input id="importWorkspaceFile" class="hidden" type="file"
|
||||
accept="application/json,.json,.tar.gz,application/gzip" />
|
||||
</div>
|
||||
</details>
|
||||
<details class="chat-drawer-section chat-drawer-danger">
|
||||
<summary class="chat-drawer-row chat-drawer-row--compact">
|
||||
type="button">Download workspace archive
|
||||
</button>
|
||||
<button id="importWorkspace"
|
||||
class="secondary-action chat-drawer-action"
|
||||
type="button">Import workspace
|
||||
</button>
|
||||
<input id="importWorkspaceFile" class="hidden" type="file"
|
||||
accept="application/json,.json,.tar.gz,application/gzip"/>
|
||||
</div>
|
||||
</details>
|
||||
<details class="chat-drawer-section chat-drawer-danger">
|
||||
<summary class="chat-drawer-row chat-drawer-row--compact">
|
||||
<span class="chat-drawer-row-label">
|
||||
<strong>Delete chat content</strong>
|
||||
</span>
|
||||
<span class="chat-drawer-row-hint">Show</span>
|
||||
</summary>
|
||||
<div class="chat-drawer-action-list chat-drawer-disclosure-panel">
|
||||
<button id="clearChat"
|
||||
<span class="chat-drawer-row-hint">Show</span>
|
||||
</summary>
|
||||
<div class="chat-drawer-action-list chat-drawer-disclosure-panel">
|
||||
<button id="clearChat"
|
||||
class="secondary-action chat-drawer-action chat-drawer-action-danger"
|
||||
type="button" data-chat-action="clear">Clear chat</button>
|
||||
</div>
|
||||
</details>
|
||||
</div>
|
||||
type="button" data-chat-action="clear">Clear chat
|
||||
</button>
|
||||
</div>
|
||||
</details>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
</div>
|
||||
|
||||
<div id="chatActivityOverlay" class="chat-activity-overlay hidden" role="status" aria-live="polite"
|
||||
aria-atomic="true">
|
||||
<div class="chat-activity-card">
|
||||
<div class="chat-activity-mark" aria-hidden="true">
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
</div>
|
||||
<p id="chatActivityEyebrow" class="eyebrow">Please wait</p>
|
||||
<h3 id="chatActivityTitle">Preparing chat</h3>
|
||||
<p id="chatActivityDetail" class="subtitle">The assistant is still working.</p>
|
||||
<div id="chatActivityOverlay" class="chat-activity-overlay hidden" role="status" aria-live="polite"
|
||||
aria-atomic="true">
|
||||
<div class="chat-activity-card">
|
||||
<div class="chat-activity-mark" aria-hidden="true">
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
</div>
|
||||
<p id="chatActivityEyebrow" class="eyebrow">Please wait</p>
|
||||
<h3 id="chatActivityTitle">Preparing chat</h3>
|
||||
<p id="chatActivityDetail" class="subtitle">The assistant is still working.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="messages-wrap">
|
||||
<div class="history-controls">
|
||||
<button id="loadOlderMessages" class="secondary-action" type="button" hidden>Load older messages</button>
|
||||
<button id="loadLatestMessages" class="secondary-action" type="button" hidden>Back to latest messages</button>
|
||||
</div>
|
||||
<button id="conversationSearchToggle" class="conversation-search-toggle secondary-action" type="button" aria-controls="conversationSearchBar" aria-expanded="false">Find in this chat</button>
|
||||
<div id="conversationSearchBar" class="conversation-search" role="search" aria-label="Search this conversation">
|
||||
<label for="conversationSearch">Find in this chat</label>
|
||||
<input id="conversationSearch" type="search" placeholder="Search messages" autocomplete="off" maxlength="200">
|
||||
<span id="conversationSearchCount" role="status" aria-live="polite">0 matches</span>
|
||||
<button id="conversationSearchPrevious" class="secondary-action" type="button" aria-label="Previous match" disabled>Previous</button>
|
||||
<button id="conversationSearchNext" class="secondary-action" type="button" aria-label="Next match" disabled>Next</button>
|
||||
</div>
|
||||
<div id="messages" class="messages-panel messages-panel-focus" role="log" aria-live="off"></div>
|
||||
<div id="replyAnnouncement" class="visually-hidden" role="status" aria-live="polite" aria-atomic="true"></div>
|
||||
<button id="jumpToLatest" class="jump-to-latest secondary-action hidden" type="button">Jump to latest</button>
|
||||
<div class="messages-wrap">
|
||||
<div class="history-controls">
|
||||
<button id="loadOlderMessages" class="secondary-action" type="button" hidden>Load older
|
||||
messages
|
||||
</button>
|
||||
<button id="loadLatestMessages" class="secondary-action" type="button" hidden>Back to latest
|
||||
messages
|
||||
</button>
|
||||
</div>
|
||||
<button id="conversationSearchToggle" class="conversation-search-toggle secondary-action"
|
||||
type="button" aria-controls="conversationSearchBar" aria-expanded="false">Find in this chat
|
||||
</button>
|
||||
<div id="conversationSearchBar" class="conversation-search" role="search"
|
||||
aria-label="Search this conversation">
|
||||
<label for="conversationSearch">Find in this chat</label>
|
||||
<input id="conversationSearch" type="search" placeholder="Search messages" autocomplete="off"
|
||||
maxlength="200">
|
||||
<span id="conversationSearchCount" role="status" aria-live="polite">0 matches</span>
|
||||
<button id="conversationSearchPrevious" class="secondary-action" type="button"
|
||||
aria-label="Previous match" disabled>Previous
|
||||
</button>
|
||||
<button id="conversationSearchNext" class="secondary-action" type="button"
|
||||
aria-label="Next match" disabled>Next
|
||||
</button>
|
||||
</div>
|
||||
<div id="messages" class="messages-panel messages-panel-focus" role="log" aria-live="off"></div>
|
||||
<div id="replyAnnouncement" class="visually-hidden" role="status" aria-live="polite"
|
||||
aria-atomic="true"></div>
|
||||
<button id="jumpToLatest" class="jump-to-latest secondary-action hidden" type="button">Jump to
|
||||
latest
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="input-shell input-shell-focus">
|
||||
<div class="input-meta">
|
||||
<p id="composerHint" class="composer-hint">Enter to send · Shift+Enter for new line</p>
|
||||
</div>
|
||||
<div id="uploadPreviews" class="upload-previews" aria-live="polite" hidden></div>
|
||||
<div class="input-container">
|
||||
<input id="imagePicker" type="file" accept="image/png,image/jpeg,image/webp" multiple
|
||||
hidden>
|
||||
<button id="attachImage" class="icon-button" type="button" aria-label="Attach image"
|
||||
<div class="input-shell input-shell-focus">
|
||||
<div class="input-meta">
|
||||
<p id="composerHint" class="composer-hint">Enter to send · Shift+Enter for new line</p>
|
||||
</div>
|
||||
<div id="uploadPreviews" class="upload-previews" aria-live="polite" hidden></div>
|
||||
<div class="input-container">
|
||||
<input id="imagePicker" type="file" accept="image/png,image/jpeg,image/webp" multiple
|
||||
hidden>
|
||||
<button id="attachImage" class="icon-button" type="button" aria-label="Attach image"
|
||||
title="Attach image">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="1.6" aria-hidden="true">
|
||||
<rect x="3" y="3" width="18" height="18" rx="3" />
|
||||
<circle cx="8" cy="8" r="1.5" />
|
||||
<path d="m3 17 5-5 4 4 4-6 5 7" />
|
||||
</svg><span class="composer-tool-label">Attach</span>
|
||||
</button>
|
||||
<button id="webSearch" class="icon-button" type="button" aria-label="Web search allowed. The assistant searches when useful. Click to turn off."
|
||||
title="Web search allowed. The assistant searches when useful. Click to turn off." aria-pressed="true">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="1.6" aria-hidden="true">
|
||||
<circle cx="12" cy="12" r="9" />
|
||||
<ellipse cx="12" cy="12" rx="4" ry="9" />
|
||||
<path d="M3 12h18" />
|
||||
</svg><span class="composer-tool-label">Web search</span>
|
||||
</button>
|
||||
<button id="reasoning" class="icon-button" type="button" aria-label="Enable reasoning"
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="1.6" aria-hidden="true">
|
||||
<rect x="3" y="3" width="18" height="18" rx="3"/>
|
||||
<circle cx="8" cy="8" r="1.5"/>
|
||||
<path d="m3 17 5-5 4 4 4-6 5 7"/>
|
||||
</svg>
|
||||
<span class="composer-tool-label">Attach</span>
|
||||
</button>
|
||||
<button id="webSearch" class="icon-button" type="button"
|
||||
aria-label="Web search allowed. The assistant searches when useful. Click to turn off."
|
||||
title="Web search allowed. The assistant searches when useful. Click to turn off."
|
||||
aria-pressed="true">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="1.6" aria-hidden="true">
|
||||
<circle cx="12" cy="12" r="9"/>
|
||||
<ellipse cx="12" cy="12" rx="4" ry="9"/>
|
||||
<path d="M3 12h18"/>
|
||||
</svg>
|
||||
<span class="composer-tool-label">Web search</span>
|
||||
</button>
|
||||
<button id="reasoning" class="icon-button" type="button" aria-label="Enable reasoning"
|
||||
title="Enable reasoning" aria-pressed="false" disabled hidden>
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"
|
||||
aria-hidden="true">
|
||||
<path
|
||||
d="M12 18V5a3 3 0 0 0-5.8-1A4 4 0 0 0 3 10a4 4 0 0 0 1 7.8A4 4 0 0 0 12 18ZM12 5a3 3 0 0 1 5.8-1A4 4 0 0 1 21 10a4 4 0 0 1-1 7.8A4 4 0 0 1 12 18M8 8a4 4 0 0 1-5 2m13-2a4 4 0 0 0 5 2M8 14a4 4 0 0 0-4 4m12-4a4 4 0 0 1 4 4" />
|
||||
</svg><span class="composer-tool-label">Reasoning</span>
|
||||
</button>
|
||||
<label class="visually-hidden" for="msgInput">Message</label>
|
||||
<textarea id="msgInput" rows="1" placeholder="Type your message..."></textarea>
|
||||
<button id="send" type="button" aria-label="Send message"></button>
|
||||
<button id="stopGeneration" class="secondary-action" type="button" aria-label="Stop generating reply" hidden>Stop</button>
|
||||
</div>
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"
|
||||
aria-hidden="true">
|
||||
<path
|
||||
d="M12 18V5a3 3 0 0 0-5.8-1A4 4 0 0 0 3 10a4 4 0 0 0 1 7.8A4 4 0 0 0 12 18ZM12 5a3 3 0 0 1 5.8-1A4 4 0 0 1 21 10a4 4 0 0 1-1 7.8A4 4 0 0 1 12 18M8 8a4 4 0 0 1-5 2m13-2a4 4 0 0 0 5 2M8 14a4 4 0 0 0-4 4m12-4a4 4 0 0 1 4 4"/>
|
||||
</svg>
|
||||
<span class="composer-tool-label">Reasoning</span>
|
||||
</button>
|
||||
<label class="visually-hidden" for="msgInput">Message</label>
|
||||
<textarea id="msgInput" rows="1" placeholder="Type your message..."></textarea>
|
||||
<button id="send" type="button" aria-label="Send message"></button>
|
||||
<button id="stopGeneration" class="secondary-action" type="button"
|
||||
aria-label="Stop generating reply" hidden>Stop
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div id="personaModal" class="modal-overlay side-panel-overlay hidden">
|
||||
<div class="modal-card persona-modal-card side-panel-card" role="dialog" aria-modal="true" aria-labelledby="personaFormTitle" tabindex="-1">
|
||||
<div class="modal-header">
|
||||
<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">Close</button>
|
||||
<div id="personaModal" class="modal-overlay side-panel-overlay hidden">
|
||||
<div class="modal-card persona-modal-card side-panel-card" role="dialog" aria-modal="true"
|
||||
aria-labelledby="personaFormTitle" tabindex="-1">
|
||||
<div class="modal-header">
|
||||
<div class="persona-modal-heading">
|
||||
<p class="eyebrow">Persona editor</p>
|
||||
<h3 id="personaFormTitle">Create persona</h3>
|
||||
</div>
|
||||
<form id="personaForm" class="persona-form">
|
||||
<div class="persona-form-intro">
|
||||
<p class="persona-helper">AI Characters shape who you talk to. User personas add context for who you
|
||||
are in the scene.</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 Character</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>
|
||||
<label id="personaExamplesField" class="field field-wide hidden">
|
||||
<span>Example dialogues</span>
|
||||
<div class="dialogue-format-card" aria-hidden="true">
|
||||
<p class="dialogue-format-label">Format</p>
|
||||
<pre class="dialogue-format-example">{{character}}: Hello, my name is marc
|
||||
<button id="personaClose" type="button" class="icon-button">Close</button>
|
||||
</div>
|
||||
<form id="personaForm" class="persona-form">
|
||||
<div class="persona-form-intro">
|
||||
<p class="persona-helper">AI Characters shape who you talk to. User personas add context for who you
|
||||
are in the scene.</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 Character</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>
|
||||
<label id="personaExamplesField" class="field field-wide hidden">
|
||||
<span>Example dialogues</span>
|
||||
<div class="dialogue-format-card" aria-hidden="true">
|
||||
<p class="dialogue-format-label">Format</p>
|
||||
<pre class="dialogue-format-example">{{character}}: Hello, my name is marc
|
||||
{{user}}: Hi, Marc!
|
||||
{{character}}: Nice to meet you</pre>
|
||||
</div>
|
||||
<textarea id="personaExampleDialogues" rows="5"
|
||||
placeholder="Write example exchanges that define the AI's tone, phrasing, pacing, and personality."></textarea>
|
||||
</label>
|
||||
</div>
|
||||
<div class="persona-actions">
|
||||
<button id="personaSave" type="submit" class="primary-action">Save persona</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="roleplayStarterModal" class="modal-overlay side-panel-overlay hidden">
|
||||
<div class="modal-card roleplay-starter-card side-panel-card" role="dialog" aria-modal="true" aria-labelledby="roleplayStarterTitle" tabindex="-1">
|
||||
<div class="modal-header">
|
||||
<div class="persona-modal-heading">
|
||||
<p class="eyebrow">Start roleplay</p>
|
||||
<h3 id="roleplayStarterTitle">Choose your roleplay</h3>
|
||||
</div>
|
||||
<button id="roleplayStarterClose" type="button" class="icon-button">Close</button>
|
||||
</div>
|
||||
<div class="roleplay-starter-intro">
|
||||
<p id="roleplayStarterIntroCopy" class="persona-helper">Pick a character and choose who you are before
|
||||
moving on to the opening scene.</p>
|
||||
</div>
|
||||
<p id="roleplayStarterNotice" class="status hidden"></p>
|
||||
<div class="roleplay-starter-actions">
|
||||
<a id="roleplayNewPersona" class="secondary-action" href="/app/personas">Browse Personalities</a>
|
||||
</div>
|
||||
<div id="roleplayStarterStepOne" class="persona-form-grid">
|
||||
<label class="field field-wide">
|
||||
<span>1. Character</span>
|
||||
<select id="roleplayCharacterSelect"></select>
|
||||
</label>
|
||||
<label class="field field-wide">
|
||||
<span>2. You in the scene</span>
|
||||
<select id="roleplayUserPersonaSelect"></select>
|
||||
</div>
|
||||
<textarea id="personaExampleDialogues" rows="5"
|
||||
placeholder="Write example exchanges that define the AI's tone, phrasing, pacing, and personality."></textarea>
|
||||
</label>
|
||||
</div>
|
||||
<div id="roleplayStarterStepTwo" class="roleplay-starter-page hidden">
|
||||
<label class="field field-wide">
|
||||
<span>Optional opening direction</span>
|
||||
<textarea id="roleplayScenarioInput" rows="4"
|
||||
placeholder="Describe the kind of opening scene you want, such as a setting, conflict, relationship dynamic, or mood. Leave it empty and the AI will invent its own scenario."></textarea>
|
||||
</label>
|
||||
<p class="subtitle">Leave this empty if you want the AI Character to invent the scenario on its own. No
|
||||
character limit.</p>
|
||||
<div id="roleplayStarterSuggestions" class="quick-prompts" aria-label="Scenario suggestions"></div>
|
||||
<div class="persona-actions">
|
||||
<button id="personaSave" type="submit" class="primary-action">Save persona</button>
|
||||
</div>
|
||||
<div class="popup-actions">
|
||||
<button id="roleplayStarterCancel" type="button" class="secondary-action">Cancel</button>
|
||||
<button id="roleplayStarterBack" type="button" class="secondary-action hidden">Back</button>
|
||||
<button id="roleplayStarterConfirm" type="button">Continue</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="roleplayStarterModal" class="modal-overlay side-panel-overlay hidden">
|
||||
<div class="modal-card roleplay-starter-card side-panel-card" role="dialog" aria-modal="true"
|
||||
aria-labelledby="roleplayStarterTitle" tabindex="-1">
|
||||
<div class="modal-header">
|
||||
<div class="persona-modal-heading">
|
||||
<p class="eyebrow">Start roleplay</p>
|
||||
<h3 id="roleplayStarterTitle">Choose your roleplay</h3>
|
||||
</div>
|
||||
<button id="roleplayStarterClose" type="button" class="icon-button">Close</button>
|
||||
</div>
|
||||
<div class="roleplay-starter-intro">
|
||||
<p id="roleplayStarterIntroCopy" class="persona-helper">Pick a character and choose who you are before
|
||||
moving on to the opening scene.</p>
|
||||
</div>
|
||||
<p id="roleplayStarterNotice" class="status hidden"></p>
|
||||
<div class="roleplay-starter-actions">
|
||||
<a id="roleplayNewPersona" class="secondary-action" href="/app/personas">Browse Personalities</a>
|
||||
</div>
|
||||
<div id="roleplayStarterStepOne" class="persona-form-grid">
|
||||
<label class="field field-wide">
|
||||
<span>1. Character</span>
|
||||
<select id="roleplayCharacterSelect"></select>
|
||||
</label>
|
||||
<label class="field field-wide">
|
||||
<span>2. You in the scene</span>
|
||||
<select id="roleplayUserPersonaSelect"></select>
|
||||
</label>
|
||||
</div>
|
||||
<div id="roleplayStarterStepTwo" class="roleplay-starter-page hidden">
|
||||
<label class="field field-wide">
|
||||
<span>Optional opening direction</span>
|
||||
<textarea id="roleplayScenarioInput" rows="4"
|
||||
placeholder="Describe the kind of opening scene you want, such as a setting, conflict, relationship dynamic, or mood. Leave it empty and the AI will invent its own scenario."></textarea>
|
||||
</label>
|
||||
<p class="subtitle">Leave this empty if you want the AI Character to invent the scenario on its own. No
|
||||
character limit.</p>
|
||||
<div id="roleplayStarterSuggestions" class="quick-prompts" aria-label="Scenario suggestions"></div>
|
||||
</div>
|
||||
<div class="popup-actions">
|
||||
<button id="roleplayStarterCancel" type="button" class="secondary-action">Cancel</button>
|
||||
<button id="roleplayStarterBack" type="button" class="secondary-action hidden">Back</button>
|
||||
<button id="roleplayStarterConfirm" type="button">Continue</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="popupModal" class="modal-overlay hidden">
|
||||
<div class="modal-card popup-card" role="dialog" aria-modal="true" aria-labelledby="popupTitle"
|
||||
aria-describedby="popupDescription">
|
||||
<div class="modal-header">
|
||||
<div class="persona-modal-heading">
|
||||
<p id="popupEyebrow" class="eyebrow">Action</p>
|
||||
<h3 id="popupTitle">Confirm action</h3>
|
||||
</div>
|
||||
<button id="popupClose" type="button" class="icon-button">Close</button>
|
||||
</div>
|
||||
<div class="popup-content">
|
||||
<p id="popupDescription" class="subtitle">Please confirm this action.</p>
|
||||
<label id="popupField" class="field hidden">
|
||||
<span id="popupInputLabel">Value</span>
|
||||
<input id="popupInput" type="text" autocomplete="off" />
|
||||
</label>
|
||||
</div>
|
||||
<div class="popup-actions">
|
||||
<button id="popupCancel" type="button" class="secondary-action">Cancel</button>
|
||||
<button id="popupConfirm" type="button">Confirm</button>
|
||||
<div id="popupModal" class="modal-overlay hidden">
|
||||
<div class="modal-card popup-card" role="dialog" aria-modal="true" aria-labelledby="popupTitle"
|
||||
aria-describedby="popupDescription">
|
||||
<div class="modal-header">
|
||||
<div class="persona-modal-heading">
|
||||
<p id="popupEyebrow" class="eyebrow">Action</p>
|
||||
<h3 id="popupTitle">Confirm action</h3>
|
||||
</div>
|
||||
<button id="popupClose" type="button" class="icon-button">Close</button>
|
||||
</div>
|
||||
<div class="popup-content">
|
||||
<p id="popupDescription" class="subtitle">Please confirm this action.</p>
|
||||
<label id="popupField" class="field hidden">
|
||||
<span id="popupInputLabel">Value</span>
|
||||
<input id="popupInput" type="text" autocomplete="off"/>
|
||||
</label>
|
||||
</div>
|
||||
<div class="popup-actions">
|
||||
<button id="popupCancel" type="button" class="secondary-action">Cancel</button>
|
||||
<button id="popupConfirm" type="button">Confirm</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="onboardingModal" class="modal-overlay hidden">
|
||||
<div class="modal-card onboarding-card" role="dialog" aria-modal="true" aria-labelledby="onboardingTitle" aria-describedby="onboardingSubtitle" tabindex="-1">
|
||||
<div class="modal-header">
|
||||
<div class="persona-modal-heading">
|
||||
<p class="eyebrow">Get started</p>
|
||||
<h3 id="onboardingTitle">Where shall we start?</h3>
|
||||
</div>
|
||||
<button id="onboardingSkip" type="button" class="icon-button">Skip</button>
|
||||
</div>
|
||||
<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 class="popup-actions">
|
||||
<button id="onboardingBack" type="button" class="secondary-action hidden">Back</button>
|
||||
<button id="onboardingContinue" type="button">Continue</button>
|
||||
<div id="onboardingModal" class="modal-overlay hidden">
|
||||
<div class="modal-card onboarding-card" role="dialog" aria-modal="true" aria-labelledby="onboardingTitle"
|
||||
aria-describedby="onboardingSubtitle" tabindex="-1">
|
||||
<div class="modal-header">
|
||||
<div class="persona-modal-heading">
|
||||
<p class="eyebrow">Get started</p>
|
||||
<h3 id="onboardingTitle">Where shall we start?</h3>
|
||||
</div>
|
||||
<button id="onboardingSkip" type="button" class="icon-button">Skip</button>
|
||||
</div>
|
||||
<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 class="popup-actions">
|
||||
<button id="onboardingBack" type="button" class="secondary-action hidden">Back</button>
|
||||
<button id="onboardingContinue" type="button">Continue</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="/vendor/marked.min.js" defer></script>
|
||||
<script src="/vendor/dompurify.js" defer></script>
|
||||
<script type="module" src="/js/script.js?v=20261012-chat-usability"></script>
|
||||
<script type="module" src="/js/workspaceNavigation.js?v=20260909-account-controls"></script>
|
||||
<script src="/vendor/marked.min.js" defer></script>
|
||||
<script src="/vendor/dompurify.js" defer></script>
|
||||
<script type="module" src="/js/script.js?v=20261012-chat-usability"></script>
|
||||
<script type="module" src="/js/workspaceNavigation.js?v=20260909-account-controls"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
+39
-39
@@ -12,51 +12,51 @@
|
||||
<link rel="stylesheet" href="/css/pages.css?v=20260909-account-controls">
|
||||
<link rel="stylesheet" href="/css/shell.css?v=20260909-account-controls">
|
||||
<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">
|
||||
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">
|
||||
</head>
|
||||
|
||||
<body class="site-page home-page">
|
||||
<!-- site-header -->
|
||||
<!-- site-header -->
|
||||
|
||||
<main id="main" class="home-main page-content">
|
||||
<p id="welcomeName" class="eyebrow">Welcome home</p>
|
||||
<h1>What would you like to do?</h1>
|
||||
<p class="hero-copy">Start somewhere new, or pick up a conversation.</p>
|
||||
<div class="feature-grid">
|
||||
<a class="feature-card action-card" href="/app/chats/new">
|
||||
<span class="feature-number">01 / ASK</span>
|
||||
<h2>New conversation</h2>
|
||||
<p>Make space for a question or an idea.</p>
|
||||
<span>Start chatting →</span>
|
||||
</a>
|
||||
<a class="feature-card action-card" href="/app/personas">
|
||||
<span class="feature-number">02 / EXPLORE</span>
|
||||
<h2>Choose a personality</h2>
|
||||
<p>Pick a specialized assistant for writing, coding, learning, research, or planning.</p>
|
||||
<span>Explore personalities →</span>
|
||||
</a>
|
||||
<a class="feature-card action-card" href="/app/chats/new?personality=creative-writer">
|
||||
<span class="feature-number">03 / CREATE</span>
|
||||
<h2>Start writing</h2>
|
||||
<p>Open a conversation with a focused creative-writing assistant.</p>
|
||||
<span>Write something →</span>
|
||||
</a>
|
||||
<main id="main" class="home-main page-content">
|
||||
<p id="welcomeName" class="eyebrow">Welcome home</p>
|
||||
<h1>What would you like to do?</h1>
|
||||
<p class="hero-copy">Start somewhere new, or pick up a conversation.</p>
|
||||
<div class="feature-grid">
|
||||
<a class="feature-card action-card" href="/app/chats/new">
|
||||
<span class="feature-number">01 / ASK</span>
|
||||
<h2>New conversation</h2>
|
||||
<p>Make space for a question or an idea.</p>
|
||||
<span>Start chatting →</span>
|
||||
</a>
|
||||
<a class="feature-card action-card" href="/app/personas">
|
||||
<span class="feature-number">02 / EXPLORE</span>
|
||||
<h2>Choose a personality</h2>
|
||||
<p>Pick a specialized assistant for writing, coding, learning, research, or planning.</p>
|
||||
<span>Explore personalities →</span>
|
||||
</a>
|
||||
<a class="feature-card action-card" href="/app/chats/new?personality=creative-writer">
|
||||
<span class="feature-number">03 / CREATE</span>
|
||||
<h2>Start writing</h2>
|
||||
<p>Open a conversation with a focused creative-writing assistant.</p>
|
||||
<span>Write something →</span>
|
||||
</a>
|
||||
</div>
|
||||
<section class="site-section">
|
||||
<div class="section-heading">
|
||||
<h2>Recent conversations</h2>
|
||||
<a href="/app/chats">View all →</a>
|
||||
</div>
|
||||
<section class="site-section">
|
||||
<div class="section-heading">
|
||||
<h2>Recent conversations</h2>
|
||||
<a href="/app/chats">View all →</a>
|
||||
</div>
|
||||
<div id="recentChats" aria-live="polite">Loading conversations…</div>
|
||||
</section>
|
||||
<p id="homeStatus" role="status">
|
||||
</p>
|
||||
</main>
|
||||
<div id="recentChats" aria-live="polite">Loading conversations…</div>
|
||||
</section>
|
||||
<p id="homeStatus" role="status">
|
||||
</p>
|
||||
</main>
|
||||
|
||||
<script type="module" src="/js/pages.js?v=20260909-account-controls">
|
||||
</script>
|
||||
<script type="module" src="/js/workspaceNavigation.js?v=20260909-account-controls"></script>
|
||||
<script type="module" src="/js/pages.js?v=20260909-account-controls">
|
||||
</script>
|
||||
<script type="module" src="/js/workspaceNavigation.js?v=20260909-account-controls"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
+18
-18
@@ -11,28 +11,28 @@
|
||||
<link rel="stylesheet" href="/css/pages.css?v=20260909-account-controls">
|
||||
<link rel="stylesheet" href="/css/shell.css?v=20260909-account-controls">
|
||||
<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">
|
||||
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">
|
||||
</head>
|
||||
|
||||
<body class="site-page landing-page">
|
||||
<!-- site-header -->
|
||||
<main id="main" class="landing-entry">
|
||||
<div class="entry-door" aria-hidden="true"><span></span></div>
|
||||
<div class="entry-copy">
|
||||
<p class="eyebrow">A space for every conversation.</p>
|
||||
<h1>Take a thought<br>somewhere.</h1>
|
||||
<p>Talk it through. Make something up.<br>Choose an assistant for the work ahead.</p>
|
||||
<div class="site-actions">
|
||||
<a data-start-link class="primary-action" href="/register">Step inside <span
|
||||
aria-hidden="true">→</span></a>
|
||||
</div>
|
||||
<!-- site-header -->
|
||||
<main id="main" class="landing-entry">
|
||||
<div class="entry-door" aria-hidden="true"><span></span></div>
|
||||
<div class="entry-copy">
|
||||
<p class="eyebrow">A space for every conversation.</p>
|
||||
<h1>Take a thought<br>somewhere.</h1>
|
||||
<p>Talk it through. Make something up.<br>Choose an assistant for the work ahead.</p>
|
||||
<div class="site-actions">
|
||||
<a data-start-link class="primary-action" href="/register">Step inside <span
|
||||
aria-hidden="true">→</span></a>
|
||||
</div>
|
||||
</main>
|
||||
<footer class="site-footer"><span>elsewhere / a little room for imagination</span><a
|
||||
href="/privacy.html">Privacy</a><a href="/tos.html">Terms</a></footer>
|
||||
<script type="module" src="/js/pages.js?v=20260909-account-controls"></script>
|
||||
<script type="module" src="/js/workspaceNavigation.js?v=20260909-account-controls"></script>
|
||||
</div>
|
||||
</main>
|
||||
<footer class="site-footer"><span>elsewhere / a little room for imagination</span><a
|
||||
href="/privacy.html">Privacy</a><a href="/tos.html">Terms</a></footer>
|
||||
<script type="module" src="/js/pages.js?v=20260909-account-controls"></script>
|
||||
<script type="module" src="/js/workspaceNavigation.js?v=20260909-account-controls"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
@@ -1,3 +1,26 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="icon" href="/img/favicon.svg"><title>Personalities - Elsewhere</title><link rel="preconnect" href="https://fonts.googleapis.com"><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"><script src="/js/theme-bootstrap.js"></script><link rel="stylesheet" href="/css/style.css"><link rel="stylesheet" href="/css/pages.css"><link rel="stylesheet" href="/css/shell.css"></head>
|
||||
<body class="site-page personalities-page" data-theme="fakegpt" data-theme-mode="light"><!-- site-header --><main id="main" class="personality-shell"><header class="personality-page-header"><p class="eyebrow">Choose your approach</p><h1>Personalities</h1><p class="subtitle">Six specialized assistants, each designed for a different kind of work.</p></header><section id="personalityGrid" class="personality-grid" aria-live="polite"></section></main><script type="module" src="/js/personalities.js"></script></body></html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="icon" href="/img/favicon.svg">
|
||||
<title>Personalities - Elsewhere</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<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">
|
||||
<script src="/js/theme-bootstrap.js"></script>
|
||||
<link rel="stylesheet" href="/css/style.css">
|
||||
<link rel="stylesheet" href="/css/pages.css">
|
||||
<link rel="stylesheet" href="/css/shell.css">
|
||||
</head>
|
||||
<body class="site-page personalities-page" data-theme="fakegpt" data-theme-mode="light"><!-- site-header -->
|
||||
<main id="main" class="personality-shell">
|
||||
<header class="personality-page-header"><p class="eyebrow">Choose your approach</p>
|
||||
<h1>Personalities</h1>
|
||||
<p class="subtitle">Six specialized assistants, use whichever fits you best.</p></header>
|
||||
<section id="personalityGrid" class="personality-grid" aria-live="polite"></section>
|
||||
</main>
|
||||
<script type="module" src="/js/personalities.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+254
-191
@@ -12,203 +12,266 @@
|
||||
<link rel="stylesheet" href="/css/shell.css?v=20260923-legal">
|
||||
<link rel="stylesheet" href="/css/legal.css?v=20260923-legal">
|
||||
<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">
|
||||
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">
|
||||
</head>
|
||||
|
||||
<body class="site-page legal-page">
|
||||
<!-- site-header -->
|
||||
<main id="main" class="legal-shell">
|
||||
<header class="legal-hero">
|
||||
<p class="eyebrow">Your data, explained</p>
|
||||
<h1>Privacy Policy</h1>
|
||||
<p class="legal-summary">This policy explains what personal data Elsewhere handles, why it is needed, where
|
||||
it goes and the choices available to you.</p>
|
||||
<p class="legal-updated">Effective and last updated <time datetime="2026-09-23">23 September 2026</time></p>
|
||||
</header>
|
||||
<!-- site-header -->
|
||||
<main id="main" class="legal-shell">
|
||||
<header class="legal-hero">
|
||||
<p class="eyebrow">Your data, explained</p>
|
||||
<h1>Privacy Policy</h1>
|
||||
<p class="legal-summary">This policy explains what personal data Elsewhere handles, why it is needed, where
|
||||
it goes and the choices available to you.</p>
|
||||
<p class="legal-updated">Effective and last updated
|
||||
<time datetime="2026-09-23">23 September 2026</time>
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<aside class="legal-callout" aria-label="Privacy summary">
|
||||
<div><strong>No advertising</strong><span>We do not sell personal data or use it for targeted ads.</span></div>
|
||||
<div><strong>You stay in control</strong><span>Export your workspace or delete your account in Settings.</span></div>
|
||||
<div><strong>Features are optional</strong><span>Web search, image uploads and public publishing are choices you make.</span></div>
|
||||
</aside>
|
||||
|
||||
<div class="legal-layout">
|
||||
<nav class="legal-toc" aria-label="On this page">
|
||||
<p>On this page</p>
|
||||
<ol>
|
||||
<li><a href="#controller">Who is responsible</a></li>
|
||||
<li><a href="#data">Data we handle</a></li>
|
||||
<li><a href="#use">How and why we use it</a></li>
|
||||
<li><a href="#providers">AI, images and search</a></li>
|
||||
<li><a href="#public">Public features</a></li>
|
||||
<li><a href="#sharing">Sharing</a></li>
|
||||
<li><a href="#cookies">Cookies</a></li>
|
||||
<li><a href="#retention">Retention</a></li>
|
||||
<li><a href="#transfers">International transfers</a></li>
|
||||
<li><a href="#security">Security</a></li>
|
||||
<li><a href="#rights">Your rights</a></li>
|
||||
<li><a href="#changes">Changes and contact</a></li>
|
||||
</ol>
|
||||
</nav>
|
||||
|
||||
<article class="legal-content">
|
||||
<section id="controller">
|
||||
<h2><span>01</span> Who is responsible</h2>
|
||||
<p>Kristian Cerni is the controller responsible for Elsewhere. This policy applies to the Elsewhere
|
||||
website, account area, chats, persona market and related features.</p>
|
||||
<dl class="legal-details">
|
||||
<div><dt>Service</dt><dd>Elsewhere</dd></div>
|
||||
<div><dt>Privacy contact</dt><dd><a href="mailto:kriscerni@gmail.com">kriscerni@gmail.com</a></dd></div>
|
||||
<div><dt>Project contact</dt><dd><a href="https://github.com/KrisHD1337" rel="external noopener">github.com/KrisHD1337</a></dd></div>
|
||||
</dl>
|
||||
</section>
|
||||
|
||||
<section id="data">
|
||||
<h2><span>02</span> Personal data we handle</h2>
|
||||
<p>We collect data you provide and technical data generated while you use the service:</p>
|
||||
<ul>
|
||||
<li><strong>Account data:</strong> username, password hash and session records. Elsewhere does not
|
||||
ask for an email address during registration.</li>
|
||||
<li><strong>Workspace content:</strong> chats, AI responses, conversation titles, personas, prompt
|
||||
templates, settings, memories, model choices, retry history and roleplay state.</li>
|
||||
<li><strong>Uploaded images:</strong> image files plus filename, type, size, dimensions, ownership,
|
||||
storage key, timestamps and cached analysis associated with your question.</li>
|
||||
<li><strong>Persona market activity:</strong> published personas and creator username, collections,
|
||||
favourites, ratings, reports and moderation records.</li>
|
||||
<li><strong>Web-search data:</strong> the search query derived from your current message, selected
|
||||
result links and snippets when you turn on web search.</li>
|
||||
<li><strong>Technical and security data:</strong> session identifiers, request identifiers, routes,
|
||||
response status and timing, account username for signed-in requests, and IP-based rate-limit
|
||||
information held temporarily in memory.</li>
|
||||
</ul>
|
||||
<p>Please avoid putting sensitive personal data into chats or images unless it is genuinely necessary
|
||||
for your use of the service.</p>
|
||||
</section>
|
||||
|
||||
<section id="use">
|
||||
<h2><span>03</span> How and why we use data</h2>
|
||||
<div class="legal-table-wrap">
|
||||
<table>
|
||||
<thead><tr><th>Purpose</th><th>Data used</th><th>Basis where the GDPR applies</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>Create and secure your account</td><td>Account, session and security data</td><td>Performance of our contract; legitimate interests in security</td></tr>
|
||||
<tr><td>Provide chats, personas, uploads, exports and settings</td><td>Account and workspace content</td><td>Performance of our contract</td></tr>
|
||||
<tr><td>Run optional AI, image and search features</td><td>Your selected message, relevant context, images or query</td><td>Performance of our contract at your request</td></tr>
|
||||
<tr><td>Operate and moderate the persona market</td><td>Published content, username and market activity</td><td>Performance of our contract; legitimate interests in a safe public space</td></tr>
|
||||
<tr><td>Prevent abuse, diagnose faults and maintain reliability</td><td>Technical, account and limited content data where necessary</td><td>Legitimate interests in security and service operation</td></tr>
|
||||
<tr><td>Meet legal obligations and defend claims</td><td>Relevant records</td><td>Legal obligation or legitimate interests</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<p>We do not use your data for targeted advertising and do not sell it. Elsewhere does not make
|
||||
decisions about you that produce legal or similarly significant effects solely by automated means.</p>
|
||||
</section>
|
||||
|
||||
<section id="providers">
|
||||
<h2><span>04</span> AI models, image analysis and web search</h2>
|
||||
<p>To generate a reply, Elsewhere sends your current message and relevant conversation context to the
|
||||
configured model backend. Depending on your settings, this may also include persona instructions,
|
||||
conversation summaries, stored memories, selected web results and analysis derived from images.
|
||||
The final chat model does not receive image files directly; a separate configured vision model
|
||||
receives the image and your question to produce an analysis.</p>
|
||||
<p>If you enable web search, Elsewhere sends a query based on your current message to the configured
|
||||
SearXNG service. The service may pass that query to search engines enabled by its operator. It does
|
||||
not receive your full conversation, account password or persona profile from Elsewhere.</p>
|
||||
<p>The deployment operator chooses and hosts or configures these services. Their location and
|
||||
sub-processors can therefore vary by deployment. Contact us if you need current information about
|
||||
the providers used by this instance.</p>
|
||||
</section>
|
||||
|
||||
<section id="public">
|
||||
<h2><span>05</span> Public persona features</h2>
|
||||
<p>Your chats, uploads and private personas are not public by default. If you publish a persona, its
|
||||
profile fields and your username become visible in the public market along with aggregate usage,
|
||||
favourite and rating information. Reports are available to administrators for moderation.</p>
|
||||
<p>You can unpublish a persona. A private copy previously collected by another user is separate and
|
||||
is not automatically removed when the original is unpublished or your account is deleted.</p>
|
||||
</section>
|
||||
|
||||
<section id="sharing">
|
||||
<h2><span>06</span> When data is shared</h2>
|
||||
<p>We disclose personal data only as needed:</p>
|
||||
<ul>
|
||||
<li>to the configured model and search services when you use those features;</li>
|
||||
<li>to infrastructure providers that host or support the application under appropriate safeguards;</li>
|
||||
<li>to other users when you intentionally publish a persona;</li>
|
||||
<li>when required by law, a valid legal process or to protect rights, safety and service security; or</li>
|
||||
<li>as part of a service reorganisation, with notice and appropriate protection where required.</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section id="cookies">
|
||||
<h2><span>07</span> Cookies and local storage</h2>
|
||||
<p>Elsewhere uses an essential, HTTP-only session cookie to keep you signed in. It expires after the
|
||||
configured session period or when invalidated. The browser also stores appearance and interface
|
||||
preferences locally on your device. These technologies are used for service functionality, not
|
||||
advertising or cross-site tracking.</p>
|
||||
</section>
|
||||
|
||||
<section id="retention">
|
||||
<h2><span>08</span> How long data is kept</h2>
|
||||
<ul>
|
||||
<li><strong>Account and workspace data</strong> remain until you delete individual items or your account.</li>
|
||||
<li><strong>Temporary, unattached uploads</strong> are scheduled for deletion after 24 hours. Images attached to a message remain with that conversation.</li>
|
||||
<li><strong>Session records</strong> expire according to the configured session lifetime and can be invalidated from Settings.</li>
|
||||
<li><strong>Operational logs and in-memory rate-limit records</strong> are kept only as long as reasonably needed for security, diagnosis and operation.</li>
|
||||
</ul>
|
||||
<p>Deleting your account removes its workspace, attached files and published market entries from the
|
||||
active service. Deletion from backups or queued file cleanup may take additional time. We may keep
|
||||
limited records longer where required by law or necessary to establish, exercise or defend legal claims.</p>
|
||||
</section>
|
||||
|
||||
<section id="transfers">
|
||||
<h2><span>09</span> International transfers</h2>
|
||||
<p>Data may be processed outside your country when infrastructure, model or search providers are
|
||||
located elsewhere. Where required, we rely on a legally recognised transfer mechanism, such as an
|
||||
adequacy decision or appropriate contractual safeguards. Contact us for details relevant to the
|
||||
current deployment.</p>
|
||||
</section>
|
||||
|
||||
<section id="security">
|
||||
<h2><span>10</span> Security</h2>
|
||||
<p>We use reasonable technical and organisational measures designed to protect personal data,
|
||||
including hashed passwords, HTTP-only same-site session cookies, same-origin request protection,
|
||||
access checks for chats and attachments, upload validation and rate limiting. No system is
|
||||
completely secure, so please use a unique password and do not share it.</p>
|
||||
</section>
|
||||
|
||||
<section id="rights">
|
||||
<h2><span>11</span> Your choices and rights</h2>
|
||||
<p>Depending on the law that applies to you, you may have the right to request access, correction,
|
||||
deletion, restriction, portability or an objection to certain processing. You may also withdraw
|
||||
consent where processing relies on consent, without affecting earlier lawful processing.</p>
|
||||
<p>You can export your workspace and delete your account directly in Settings. For other requests,
|
||||
email <a href="mailto:kriscerni@gmail.com">kriscerni@gmail.com</a>. We may need to verify your
|
||||
identity before completing a request.</p>
|
||||
<p>You may lodge a complaint with the Swiss Federal Data Protection and Information Commissioner
|
||||
(FDPIC) or, where the GDPR applies, your local data protection authority. We encourage you to
|
||||
contact us first so we can try to resolve the concern.</p>
|
||||
</section>
|
||||
|
||||
<section id="changes">
|
||||
<h2><span>12</span> Changes and contact</h2>
|
||||
<p>We may update this policy when the service, providers or applicable requirements change. We will
|
||||
post the new version here, change the date above and provide additional notice for material
|
||||
changes where appropriate.</p>
|
||||
<p>Questions or requests can be sent to <a
|
||||
href="mailto:kriscerni@gmail.com">kriscerni@gmail.com</a>.</p>
|
||||
</section>
|
||||
</article>
|
||||
<aside class="legal-callout" aria-label="Privacy summary">
|
||||
<div><strong>No advertising</strong><span>We do not sell personal data or use it for targeted ads.</span></div>
|
||||
<div><strong>You stay in control</strong><span>Export your workspace or delete your account in Settings.</span>
|
||||
</div>
|
||||
</main>
|
||||
<div><strong>Features are optional</strong><span>Web search, image uploads and public publishing are choices you make.</span>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<footer class="legal-footer">
|
||||
<span>Elsewhere</span>
|
||||
<a href="/tos.html">Terms of Service</a>
|
||||
<a href="/">Back to Elsewhere</a>
|
||||
</footer>
|
||||
<script type="module" src="/js/workspaceNavigation.js?v=20260923-legal"></script>
|
||||
<div class="legal-layout">
|
||||
<nav class="legal-toc" aria-label="On this page">
|
||||
<p>On this page</p>
|
||||
<ol>
|
||||
<li><a href="#controller">Who is responsible</a></li>
|
||||
<li><a href="#data">Data we handle</a></li>
|
||||
<li><a href="#use">How and why we use it</a></li>
|
||||
<li><a href="#providers">AI, images and search</a></li>
|
||||
<li><a href="#public">Public features</a></li>
|
||||
<li><a href="#sharing">Sharing</a></li>
|
||||
<li><a href="#cookies">Cookies</a></li>
|
||||
<li><a href="#retention">Retention</a></li>
|
||||
<li><a href="#transfers">International transfers</a></li>
|
||||
<li><a href="#security">Security</a></li>
|
||||
<li><a href="#rights">Your rights</a></li>
|
||||
<li><a href="#changes">Changes and contact</a></li>
|
||||
</ol>
|
||||
</nav>
|
||||
|
||||
<article class="legal-content">
|
||||
<section id="controller">
|
||||
<h2><span>01</span> Who is responsible</h2>
|
||||
<p>Kristian Cerni is the controller responsible for Elsewhere. This policy applies to the Elsewhere
|
||||
website, account area, chats, persona market and related features.</p>
|
||||
<dl class="legal-details">
|
||||
<div>
|
||||
<dt>Service</dt>
|
||||
<dd>Elsewhere</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>Privacy contact</dt>
|
||||
<dd><a href="mailto:kriscerni@gmail.com">kriscerni@gmail.com</a></dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>Project contact</dt>
|
||||
<dd><a href="https://github.com/KrisHD1337" rel="external noopener">github.com/KrisHD1337</a>
|
||||
</dd>
|
||||
</div>
|
||||
</dl>
|
||||
</section>
|
||||
|
||||
<section id="data">
|
||||
<h2><span>02</span> Personal data we handle</h2>
|
||||
<p>We collect data you provide and technical data generated while you use the service:</p>
|
||||
<ul>
|
||||
<li><strong>Account data:</strong> username, password hash and session records. Elsewhere does not
|
||||
ask for an email address during registration.
|
||||
</li>
|
||||
<li><strong>Workspace content:</strong> chats, AI responses, conversation titles, personas, prompt
|
||||
templates, settings, memories, model choices, retry history and roleplay state.
|
||||
</li>
|
||||
<li><strong>Uploaded images:</strong> image files plus filename, type, size, dimensions, ownership,
|
||||
storage key, timestamps and cached analysis associated with your question.
|
||||
</li>
|
||||
<li><strong>Persona market activity:</strong> published personas and creator username, collections,
|
||||
favourites, ratings, reports and moderation records.
|
||||
</li>
|
||||
<li><strong>Web-search data:</strong> the search query derived from your current message, selected
|
||||
result links and snippets when you turn on web search.
|
||||
</li>
|
||||
<li><strong>Technical and security data:</strong> session identifiers, request identifiers, routes,
|
||||
response status and timing, account username for signed-in requests, and IP-based rate-limit
|
||||
information held temporarily in memory.
|
||||
</li>
|
||||
</ul>
|
||||
<p>Please avoid putting sensitive personal data into chats or images unless it is genuinely necessary
|
||||
for your use of the service.</p>
|
||||
</section>
|
||||
|
||||
<section id="use">
|
||||
<h2><span>03</span> How and why we use data</h2>
|
||||
<div class="legal-table-wrap">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Purpose</th>
|
||||
<th>Data used</th>
|
||||
<th>Basis where the GDPR applies</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Create and secure your account</td>
|
||||
<td>Account, session and security data</td>
|
||||
<td>Performance of our contract; legitimate interests in security</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Provide chats, personas, uploads, exports and settings</td>
|
||||
<td>Account and workspace content</td>
|
||||
<td>Performance of our contract</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Run optional AI, image and search features</td>
|
||||
<td>Your selected message, relevant context, images or query</td>
|
||||
<td>Performance of our contract at your request</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Operate and moderate the persona market</td>
|
||||
<td>Published content, username and market activity</td>
|
||||
<td>Performance of our contract; legitimate interests in a safe public space</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Prevent abuse, diagnose faults and maintain reliability</td>
|
||||
<td>Technical, account and limited content data where necessary</td>
|
||||
<td>Legitimate interests in security and service operation</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Meet legal obligations and defend claims</td>
|
||||
<td>Relevant records</td>
|
||||
<td>Legal obligation or legitimate interests</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<p>We do not use your data for targeted advertising and do not sell it. Elsewhere does not make
|
||||
decisions about you that produce legal or similarly significant effects solely by automated
|
||||
means.</p>
|
||||
</section>
|
||||
|
||||
<section id="providers">
|
||||
<h2><span>04</span> AI models, image analysis and web search</h2>
|
||||
<p>To generate a reply, Elsewhere sends your current message and relevant conversation context to the
|
||||
configured model backend. Depending on your settings, this may also include persona instructions,
|
||||
conversation summaries, stored memories, selected web results and analysis derived from images.
|
||||
The final chat model does not receive image files directly; a separate configured vision model
|
||||
receives the image and your question to produce an analysis.</p>
|
||||
<p>If you enable web search, Elsewhere sends a query based on your current message to the configured
|
||||
SearXNG service. The service may pass that query to search engines enabled by its operator. It does
|
||||
not receive your full conversation, account password or persona profile from Elsewhere.</p>
|
||||
<p>The deployment operator chooses and hosts or configures these services. Their location and
|
||||
sub-processors can therefore vary by deployment. Contact us if you need current information about
|
||||
the providers used by this instance.</p>
|
||||
</section>
|
||||
|
||||
<section id="public">
|
||||
<h2><span>05</span> Public persona features</h2>
|
||||
<p>Your chats, uploads and private personas are not public by default. If you publish a persona, its
|
||||
profile fields and your username become visible in the public market along with aggregate usage,
|
||||
favourite and rating information. Reports are available to administrators for moderation.</p>
|
||||
<p>You can unpublish a persona. A private copy previously collected by another user is separate and
|
||||
is not automatically removed when the original is unpublished or your account is deleted.</p>
|
||||
</section>
|
||||
|
||||
<section id="sharing">
|
||||
<h2><span>06</span> When data is shared</h2>
|
||||
<p>We disclose personal data only as needed:</p>
|
||||
<ul>
|
||||
<li>to the configured model and search services when you use those features;</li>
|
||||
<li>to infrastructure providers that host or support the application under appropriate safeguards;
|
||||
</li>
|
||||
<li>to other users when you intentionally publish a persona;</li>
|
||||
<li>when required by law, a valid legal process or to protect rights, safety and service security;
|
||||
or
|
||||
</li>
|
||||
<li>as part of a service reorganisation, with notice and appropriate protection where required.</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section id="cookies">
|
||||
<h2><span>07</span> Cookies and local storage</h2>
|
||||
<p>Elsewhere uses an essential, HTTP-only session cookie to keep you signed in. It expires after the
|
||||
configured session period or when invalidated. The browser also stores appearance and interface
|
||||
preferences locally on your device. These technologies are used for service functionality, not
|
||||
advertising or cross-site tracking.</p>
|
||||
</section>
|
||||
|
||||
<section id="retention">
|
||||
<h2><span>08</span> How long data is kept</h2>
|
||||
<ul>
|
||||
<li><strong>Account and workspace data</strong> remain until you delete individual items or your
|
||||
account.
|
||||
</li>
|
||||
<li><strong>Temporary, unattached uploads</strong> are scheduled for deletion after 24 hours. Images
|
||||
attached to a message remain with that conversation.
|
||||
</li>
|
||||
<li><strong>Session records</strong> expire according to the configured session lifetime and can be
|
||||
invalidated from Settings.
|
||||
</li>
|
||||
<li><strong>Operational logs and in-memory rate-limit records</strong> are kept only as long as
|
||||
reasonably needed for security, diagnosis and operation.
|
||||
</li>
|
||||
</ul>
|
||||
<p>Deleting your account removes its workspace, attached files and published market entries from the
|
||||
active service. Deletion from backups or queued file cleanup may take additional time. We may keep
|
||||
limited records longer where required by law or necessary to establish, exercise or defend legal
|
||||
claims.</p>
|
||||
</section>
|
||||
|
||||
<section id="transfers">
|
||||
<h2><span>09</span> International transfers</h2>
|
||||
<p>Data may be processed outside your country when infrastructure, model or search providers are
|
||||
located elsewhere. Where required, we rely on a legally recognised transfer mechanism, such as an
|
||||
adequacy decision or appropriate contractual safeguards. Contact us for details relevant to the
|
||||
current deployment.</p>
|
||||
</section>
|
||||
|
||||
<section id="security">
|
||||
<h2><span>10</span> Security</h2>
|
||||
<p>We use reasonable technical and organisational measures designed to protect personal data,
|
||||
including hashed passwords, HTTP-only same-site session cookies, same-origin request protection,
|
||||
access checks for chats and attachments, upload validation and rate limiting. No system is
|
||||
completely secure, so please use a unique password and do not share it.</p>
|
||||
</section>
|
||||
|
||||
<section id="rights">
|
||||
<h2><span>11</span> Your choices and rights</h2>
|
||||
<p>Depending on the law that applies to you, you may have the right to request access, correction,
|
||||
deletion, restriction, portability or an objection to certain processing. You may also withdraw
|
||||
consent where processing relies on consent, without affecting earlier lawful processing.</p>
|
||||
<p>You can export your workspace and delete your account directly in Settings. For other requests,
|
||||
email <a href="mailto:kriscerni@gmail.com">kriscerni@gmail.com</a>. We may need to verify your
|
||||
identity before completing a request.</p>
|
||||
<p>You may lodge a complaint with the Swiss Federal Data Protection and Information Commissioner
|
||||
(FDPIC) or, where the GDPR applies, your local data protection authority. We encourage you to
|
||||
contact us first so we can try to resolve the concern.</p>
|
||||
</section>
|
||||
|
||||
<section id="changes">
|
||||
<h2><span>12</span> Changes and contact</h2>
|
||||
<p>We may update this policy when the service, providers or applicable requirements change. We will
|
||||
post the new version here, change the date above and provide additional notice for material
|
||||
changes where appropriate.</p>
|
||||
<p>Questions or requests can be sent to <a
|
||||
href="mailto:kriscerni@gmail.com">kriscerni@gmail.com</a>.</p>
|
||||
</section>
|
||||
</article>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="legal-footer">
|
||||
<span>Elsewhere</span>
|
||||
<a href="/tos.html">Terms of Service</a>
|
||||
<a href="/">Back to Elsewhere</a>
|
||||
</footer>
|
||||
<script type="module" src="/js/workspaceNavigation.js?v=20260923-legal"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
+290
-283
@@ -3,314 +3,321 @@
|
||||
|
||||
<head>
|
||||
<link rel="icon" type="image/svg+xml" href="/img/favicon.svg">
|
||||
<meta charset="UTF-8" />
|
||||
<meta charset="UTF-8"/>
|
||||
<title>Elsewhere Settings</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<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">
|
||||
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="/js/theme-bootstrap.js?v=20260909-account-controls"></script>
|
||||
<link rel="stylesheet" href="/css/style.css?v=20260909-account-controls" />
|
||||
<link rel="stylesheet" href="/css/style.css?v=20260909-account-controls"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="/css/shell.css?v=20260909-account-controls">
|
||||
</head>
|
||||
|
||||
<body class="site-page settings-page" data-theme="fakegpt" data-theme-mode="light">
|
||||
<!-- site-header -->
|
||||
<main id="main" class="settings-shell page-content">
|
||||
<header class="market-header market-header-simple">
|
||||
<div>
|
||||
<p class="eyebrow">Elsewhere settings</p>
|
||||
<h1>Preferences</h1>
|
||||
</div>
|
||||
</header>
|
||||
<!-- site-header -->
|
||||
<main id="main" class="settings-shell page-content">
|
||||
<header class="market-header market-header-simple">
|
||||
<div>
|
||||
<p class="eyebrow">Elsewhere settings</p>
|
||||
<h1>Preferences</h1>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<p id="settingsNotice" class="status">Loading settings...</p>
|
||||
<p id="settingsNotice" class="status">Loading settings...</p>
|
||||
|
||||
<section class="settings-layout">
|
||||
<aside class="settings-nav" aria-label="Settings sections" role="tablist">
|
||||
<button class="settings-nav-item active" type="button" role="tab" aria-selected="true"
|
||||
data-settings-view="personal">Account</button>
|
||||
<section class="settings-layout">
|
||||
<aside class="settings-nav" aria-label="Settings sections" role="tablist">
|
||||
<button class="settings-nav-item active" type="button" role="tab" aria-selected="true"
|
||||
data-settings-view="personal">Account
|
||||
</button>
|
||||
|
||||
<button class="settings-nav-item" type="button" role="tab" aria-selected="false"
|
||||
data-settings-view="design">Appearance</button>
|
||||
<button id="diagnosticsNavItem" class="settings-nav-item hidden" type="button" role="tab"
|
||||
aria-selected="false" data-settings-view="diagnostics">Diagnostics</button>
|
||||
</aside>
|
||||
<button class="settings-nav-item" type="button" role="tab" aria-selected="false"
|
||||
data-settings-view="design">Appearance
|
||||
</button>
|
||||
<button id="diagnosticsNavItem" class="settings-nav-item hidden" type="button" role="tab"
|
||||
aria-selected="false" data-settings-view="diagnostics">Diagnostics
|
||||
</button>
|
||||
</aside>
|
||||
|
||||
<div class="settings-content">
|
||||
<section class="settings-view active" role="tabpanel" data-settings-panel="personal">
|
||||
<div class="settings-panel">
|
||||
<div class="settings-section-header">
|
||||
<div>
|
||||
<p class="eyebrow">Profile</p>
|
||||
<h2>Username</h2>
|
||||
</div>
|
||||
</div>
|
||||
<form id="usernameForm" class="settings-form-stack">
|
||||
<label class="field">
|
||||
<span>Current username</span>
|
||||
<input id="currentUsername" readonly />
|
||||
</label>
|
||||
<label class="field">
|
||||
<span>New username</span>
|
||||
<input id="newUsername" autocomplete="username" />
|
||||
</label>
|
||||
<label class="field">
|
||||
<span>Current password</span>
|
||||
<input id="usernamePassword" type="password" autocomplete="current-password" />
|
||||
</label>
|
||||
<button id="saveUsername" type="submit">Save username</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="settings-panel">
|
||||
<div class="settings-section-header">
|
||||
<div>
|
||||
<p class="eyebrow">Security</p>
|
||||
<h2>Password</h2>
|
||||
</div>
|
||||
</div>
|
||||
<form id="passwordForm" class="settings-form-stack">
|
||||
<label class="field">
|
||||
<span>Current password</span>
|
||||
<input id="currentPassword" type="password" autocomplete="current-password" />
|
||||
</label>
|
||||
<label class="field">
|
||||
<span>New password</span>
|
||||
<input id="newPassword" type="password" autocomplete="new-password" />
|
||||
</label>
|
||||
<label class="field">
|
||||
<span>Repeat new password</span>
|
||||
<input id="repeatPassword" type="password" autocomplete="new-password" />
|
||||
</label>
|
||||
<button id="savePassword" type="submit">Save password</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="settings-panel">
|
||||
<div class="settings-section-header">
|
||||
<div>
|
||||
<p class="eyebrow">Account data</p>
|
||||
<h2>Export and sessions</h2>
|
||||
<p class="subtitle">Download your account data or sign out every active browser session.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="persona-actions">
|
||||
<button id="exportAccount" type="button" class="secondary-action">Export account</button>
|
||||
<button id="logoutAllSessions" type="button" class="secondary-action">Logout all
|
||||
sessions</button>
|
||||
<div class="settings-content">
|
||||
<section class="settings-view active" role="tabpanel" data-settings-panel="personal">
|
||||
<div class="settings-panel">
|
||||
<div class="settings-section-header">
|
||||
<div>
|
||||
<p class="eyebrow">Profile</p>
|
||||
<h2>Username</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="settings-panel">
|
||||
<div class="settings-section-header">
|
||||
<div>
|
||||
<p class="eyebrow">Danger zone</p>
|
||||
<h2>Delete account</h2>
|
||||
<p class="subtitle">This permanently removes your account, chats, personas, templates,
|
||||
and market activity.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="persona-actions">
|
||||
<button id="deleteAccount" type="button" class="secondary-action danger">Delete
|
||||
account</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="settings-view" role="tabpanel" aria-hidden="true"
|
||||
data-settings-panel="my-roleplay-companions">
|
||||
<div class="settings-panel">
|
||||
<div class="settings-section-header">
|
||||
<div>
|
||||
<p class="eyebrow">Curated assistants</p>
|
||||
<h2>Personalities</h2>
|
||||
<p class="subtitle">Choose a focused assistant for writing, coding, research, learning, or planning.</p>
|
||||
</div>
|
||||
<a class="secondary-action" href="/app/personas">Browse Personalities</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="settings-view" role="tabpanel" aria-hidden="true" data-settings-panel="design">
|
||||
<div class="settings-panel settings-panel-compact">
|
||||
<div class="settings-section-header">
|
||||
<div>
|
||||
<p class="eyebrow">Appearance</p>
|
||||
<h2>Make yourself at home</h2>
|
||||
<p class="subtitle">Choose a style for your conversation space.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="settings-theme-row">
|
||||
<label class="field">
|
||||
<span>Style</span>
|
||||
<select id="settingsThemeSelect">
|
||||
<option value="fakegpt">Grove</option>
|
||||
<option value="fraud">Parchment</option>
|
||||
<option value="germini">Aurora</option>
|
||||
<option value="slopilot">Current</option>
|
||||
<option value="beta-ai">Iris</option>
|
||||
<option value="confusity">Graphite</option>
|
||||
</select>
|
||||
</label>
|
||||
<label class="field">
|
||||
<span>Light or dark</span>
|
||||
<select id="themeModeSelect">
|
||||
<option value="light">Light</option>
|
||||
<option value="dark">Dark</option>
|
||||
</select>
|
||||
</label>
|
||||
<label class="field">
|
||||
<span>Workspace mode</span>
|
||||
<select id="workspaceModeSelect">
|
||||
<option value="basic">Basic</option>
|
||||
<option value="advanced">Advanced</option>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="settings-view" role="tabpanel" aria-hidden="true" data-settings-panel="diagnostics">
|
||||
<div class="settings-panel">
|
||||
<div class="settings-section-header">
|
||||
<div>
|
||||
<p class="eyebrow">Admin</p>
|
||||
<h2>Model diagnostics</h2>
|
||||
<p class="subtitle">Backend status, model inventory, latency, and configuration
|
||||
warnings.</p>
|
||||
</div>
|
||||
<button id="refreshDiagnostics" type="button" class="secondary-action">Refresh</button>
|
||||
</div>
|
||||
<div class="diagnostics-grid">
|
||||
<div class="diagnostics-card">
|
||||
<span>Status</span>
|
||||
<strong id="diagnosticsStatus">Unknown</strong>
|
||||
<p id="diagnosticsBackend" class="subtitle">Backend unavailable</p>
|
||||
</div>
|
||||
<div class="diagnostics-card">
|
||||
<span>Latency</span>
|
||||
<strong id="diagnosticsLatency">n/a</strong>
|
||||
<p id="diagnosticsCheckedAt" class="subtitle">Not checked yet</p>
|
||||
</div>
|
||||
<div class="diagnostics-card">
|
||||
<span>Models</span>
|
||||
<strong id="diagnosticsModelCount">0</strong>
|
||||
<p id="diagnosticsCacheAge" class="subtitle">Cache age n/a</p>
|
||||
</div>
|
||||
<div class="diagnostics-card">
|
||||
<span>Active requests</span>
|
||||
<strong id="diagnosticsActiveRequests">0</strong>
|
||||
<p id="diagnosticsLastFailure" class="subtitle">No recorded failures</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="diagnostics-columns">
|
||||
<div>
|
||||
<h3>Available models</h3>
|
||||
<div id="diagnosticsModels" class="diagnostics-list"></div>
|
||||
</div>
|
||||
<div>
|
||||
<h3>Config warnings</h3>
|
||||
<div id="diagnosticsWarnings" class="diagnostics-list"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<div id="settingsPersonaModal" class="modal-overlay hidden">
|
||||
<div class="modal-card persona-modal-card" role="dialog" aria-modal="true" aria-labelledby="settingsPersonaFormTitle" tabindex="-1">
|
||||
<div class="modal-header">
|
||||
<div class="persona-modal-heading">
|
||||
<p class="eyebrow">Persona editor</p>
|
||||
<h3 id="settingsPersonaFormTitle">Create persona</h3>
|
||||
<form id="usernameForm" class="settings-form-stack">
|
||||
<label class="field">
|
||||
<span>Current username</span>
|
||||
<input id="currentUsername" readonly/>
|
||||
</label>
|
||||
<label class="field">
|
||||
<span>New username</span>
|
||||
<input id="newUsername" autocomplete="username"/>
|
||||
</label>
|
||||
<label class="field">
|
||||
<span>Current password</span>
|
||||
<input id="usernamePassword" type="password" autocomplete="current-password"/>
|
||||
</label>
|
||||
<button id="saveUsername" type="submit">Save username</button>
|
||||
</form>
|
||||
</div>
|
||||
<button id="settingsPersonaClose" type="button" class="icon-button">Close</button>
|
||||
</div>
|
||||
<form id="settingsPersonaForm" class="persona-form">
|
||||
<div class="persona-form-intro">
|
||||
<p id="settingsPersonaHelper" class="persona-helper">Create a persona for roleplay chats.</p>
|
||||
|
||||
<div class="settings-panel">
|
||||
<div class="settings-section-header">
|
||||
<div>
|
||||
<p class="eyebrow">Security</p>
|
||||
<h2>Password</h2>
|
||||
</div>
|
||||
</div>
|
||||
<form id="passwordForm" class="settings-form-stack">
|
||||
<label class="field">
|
||||
<span>Current password</span>
|
||||
<input id="currentPassword" type="password" autocomplete="current-password"/>
|
||||
</label>
|
||||
<label class="field">
|
||||
<span>New password</span>
|
||||
<input id="newPassword" type="password" autocomplete="new-password"/>
|
||||
</label>
|
||||
<label class="field">
|
||||
<span>Repeat new password</span>
|
||||
<input id="repeatPassword" type="password" autocomplete="new-password"/>
|
||||
</label>
|
||||
<button id="savePassword" type="submit">Save password</button>
|
||||
</form>
|
||||
</div>
|
||||
<p id="settingsPersonaFormNotice" class="status hidden"></p>
|
||||
<div class="persona-form-grid">
|
||||
<label class="field field-wide">
|
||||
<span>Persona for</span>
|
||||
<select id="settingsPersonaType">
|
||||
<option value="assistant">AI Character</option>
|
||||
<option value="user">Your persona</option>
|
||||
</select>
|
||||
</label>
|
||||
<label class="field">
|
||||
<span>Name</span>
|
||||
<input id="settingsPersonaName" placeholder="Persona name" required />
|
||||
</label>
|
||||
<label class="field">
|
||||
<span>Pronouns</span>
|
||||
<input id="settingsPersonaPronouns" placeholder="e.g. she/her, they/them" />
|
||||
</label>
|
||||
<label class="field field-wide">
|
||||
<span>Appearance</span>
|
||||
<textarea id="settingsPersonaAppearance" rows="3" placeholder="Describe their look"></textarea>
|
||||
</label>
|
||||
<label class="field field-wide">
|
||||
<span>Background</span>
|
||||
<textarea id="settingsPersonaBackground" rows="3"
|
||||
placeholder="Backstory, history, role, or origins"></textarea>
|
||||
</label>
|
||||
<label class="field field-wide">
|
||||
<span>Details</span>
|
||||
<textarea id="settingsPersonaDetails" rows="4"
|
||||
placeholder="Personality traits, voice, goals, quirks, boundaries, style"></textarea>
|
||||
</label>
|
||||
<label id="settingsPersonaExamplesField" class="field field-wide hidden">
|
||||
<span>Example dialogues</span>
|
||||
<div class="dialogue-format-card" aria-hidden="true">
|
||||
<p class="dialogue-format-label">Format</p>
|
||||
<pre class="dialogue-format-example">{{character}}: Hello, my name is marc
|
||||
|
||||
<div class="settings-panel">
|
||||
<div class="settings-section-header">
|
||||
<div>
|
||||
<p class="eyebrow">Account data</p>
|
||||
<h2>Export and sessions</h2>
|
||||
<p class="subtitle">Download your account data or sign out every active browser session.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="persona-actions">
|
||||
<button id="exportAccount" type="button" class="secondary-action">Export account</button>
|
||||
<button id="logoutAllSessions" type="button" class="secondary-action">Logout all
|
||||
sessions
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="settings-panel">
|
||||
<div class="settings-section-header">
|
||||
<div>
|
||||
<p class="eyebrow">Danger zone</p>
|
||||
<h2>Delete account</h2>
|
||||
<p class="subtitle">This permanently removes your account, chats, personas, templates,
|
||||
and market activity.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="persona-actions">
|
||||
<button id="deleteAccount" type="button" class="secondary-action danger">Delete
|
||||
account
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="settings-view" role="tabpanel" aria-hidden="true"
|
||||
data-settings-panel="my-roleplay-companions">
|
||||
<div class="settings-panel">
|
||||
<div class="settings-section-header">
|
||||
<div>
|
||||
<p class="eyebrow">Curated assistants</p>
|
||||
<h2>Personalities</h2>
|
||||
<p class="subtitle">Choose a focused assistant for writing, coding, research, learning, or
|
||||
planning.</p>
|
||||
</div>
|
||||
<a class="secondary-action" href="/app/personas">Browse Personalities</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="settings-view" role="tabpanel" aria-hidden="true" data-settings-panel="design">
|
||||
<div class="settings-panel settings-panel-compact">
|
||||
<div class="settings-section-header">
|
||||
<div>
|
||||
<p class="eyebrow">Appearance</p>
|
||||
<h2>Make yourself at home</h2>
|
||||
<p class="subtitle">Choose a style for your conversation space.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="settings-theme-row">
|
||||
<label class="field">
|
||||
<span>Style</span>
|
||||
<select id="settingsThemeSelect">
|
||||
<option value="fakegpt">Grove</option>
|
||||
<option value="fraud">Parchment</option>
|
||||
<option value="germini">Aurora</option>
|
||||
<option value="slopilot">Current</option>
|
||||
<option value="beta-ai">Iris</option>
|
||||
<option value="confusity">Graphite</option>
|
||||
</select>
|
||||
</label>
|
||||
<label class="field">
|
||||
<span>Light or dark</span>
|
||||
<select id="themeModeSelect">
|
||||
<option value="light">Light</option>
|
||||
<option value="dark">Dark</option>
|
||||
</select>
|
||||
</label>
|
||||
<label class="field">
|
||||
<span>Workspace mode</span>
|
||||
<select id="workspaceModeSelect">
|
||||
<option value="basic">Basic</option>
|
||||
<option value="advanced">Advanced</option>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="settings-view" role="tabpanel" aria-hidden="true" data-settings-panel="diagnostics">
|
||||
<div class="settings-panel">
|
||||
<div class="settings-section-header">
|
||||
<div>
|
||||
<p class="eyebrow">Admin</p>
|
||||
<h2>Model diagnostics</h2>
|
||||
<p class="subtitle">Backend status, model inventory, latency, and configuration
|
||||
warnings.</p>
|
||||
</div>
|
||||
<button id="refreshDiagnostics" type="button" class="secondary-action">Refresh</button>
|
||||
</div>
|
||||
<div class="diagnostics-grid">
|
||||
<div class="diagnostics-card">
|
||||
<span>Status</span>
|
||||
<strong id="diagnosticsStatus">Unknown</strong>
|
||||
<p id="diagnosticsBackend" class="subtitle">Backend unavailable</p>
|
||||
</div>
|
||||
<div class="diagnostics-card">
|
||||
<span>Latency</span>
|
||||
<strong id="diagnosticsLatency">n/a</strong>
|
||||
<p id="diagnosticsCheckedAt" class="subtitle">Not checked yet</p>
|
||||
</div>
|
||||
<div class="diagnostics-card">
|
||||
<span>Models</span>
|
||||
<strong id="diagnosticsModelCount">0</strong>
|
||||
<p id="diagnosticsCacheAge" class="subtitle">Cache age n/a</p>
|
||||
</div>
|
||||
<div class="diagnostics-card">
|
||||
<span>Active requests</span>
|
||||
<strong id="diagnosticsActiveRequests">0</strong>
|
||||
<p id="diagnosticsLastFailure" class="subtitle">No recorded failures</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="diagnostics-columns">
|
||||
<div>
|
||||
<h3>Available models</h3>
|
||||
<div id="diagnosticsModels" class="diagnostics-list"></div>
|
||||
</div>
|
||||
<div>
|
||||
<h3>Config warnings</h3>
|
||||
<div id="diagnosticsWarnings" class="diagnostics-list"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<div id="settingsPersonaModal" class="modal-overlay hidden">
|
||||
<div class="modal-card persona-modal-card" role="dialog" aria-modal="true"
|
||||
aria-labelledby="settingsPersonaFormTitle" tabindex="-1">
|
||||
<div class="modal-header">
|
||||
<div class="persona-modal-heading">
|
||||
<p class="eyebrow">Persona editor</p>
|
||||
<h3 id="settingsPersonaFormTitle">Create persona</h3>
|
||||
</div>
|
||||
<button id="settingsPersonaClose" type="button" class="icon-button">Close</button>
|
||||
</div>
|
||||
<form id="settingsPersonaForm" class="persona-form">
|
||||
<div class="persona-form-intro">
|
||||
<p id="settingsPersonaHelper" class="persona-helper">Create a persona for roleplay chats.</p>
|
||||
</div>
|
||||
<p id="settingsPersonaFormNotice" class="status hidden"></p>
|
||||
<div class="persona-form-grid">
|
||||
<label class="field field-wide">
|
||||
<span>Persona for</span>
|
||||
<select id="settingsPersonaType">
|
||||
<option value="assistant">AI Character</option>
|
||||
<option value="user">Your persona</option>
|
||||
</select>
|
||||
</label>
|
||||
<label class="field">
|
||||
<span>Name</span>
|
||||
<input id="settingsPersonaName" placeholder="Persona name" required/>
|
||||
</label>
|
||||
<label class="field">
|
||||
<span>Pronouns</span>
|
||||
<input id="settingsPersonaPronouns" placeholder="e.g. she/her, they/them"/>
|
||||
</label>
|
||||
<label class="field field-wide">
|
||||
<span>Appearance</span>
|
||||
<textarea id="settingsPersonaAppearance" rows="3" placeholder="Describe their look"></textarea>
|
||||
</label>
|
||||
<label class="field field-wide">
|
||||
<span>Background</span>
|
||||
<textarea id="settingsPersonaBackground" rows="3"
|
||||
placeholder="Backstory, history, role, or origins"></textarea>
|
||||
</label>
|
||||
<label class="field field-wide">
|
||||
<span>Details</span>
|
||||
<textarea id="settingsPersonaDetails" rows="4"
|
||||
placeholder="Personality traits, voice, goals, quirks, boundaries, style"></textarea>
|
||||
</label>
|
||||
<label id="settingsPersonaExamplesField" class="field field-wide hidden">
|
||||
<span>Example dialogues</span>
|
||||
<div class="dialogue-format-card" aria-hidden="true">
|
||||
<p class="dialogue-format-label">Format</p>
|
||||
<pre class="dialogue-format-example">{{character}}: Hello, my name is marc
|
||||
{{user}}: Hi, Marc!
|
||||
{{character}}: Nice to meet you</pre>
|
||||
</div>
|
||||
<textarea id="settingsPersonaExampleDialogues" rows="5"
|
||||
placeholder="Write example exchanges that define the character's tone, phrasing, pacing, and personality."></textarea>
|
||||
</label>
|
||||
</div>
|
||||
<div class="persona-actions">
|
||||
<button id="settingsPersonaSave" type="submit" class="primary-action">Save persona</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="settingsPopupModal" class="modal-overlay hidden">
|
||||
<div class="modal-card popup-card" role="dialog" aria-modal="true" aria-labelledby="settingsPopupTitle"
|
||||
aria-describedby="settingsPopupDescription">
|
||||
<div class="modal-header">
|
||||
<div class="persona-modal-heading">
|
||||
<p id="settingsPopupEyebrow" class="eyebrow">Action</p>
|
||||
<h3 id="settingsPopupTitle">Confirm action</h3>
|
||||
</div>
|
||||
<button id="settingsPopupClose" type="button" class="icon-button">Close</button>
|
||||
</div>
|
||||
<div class="popup-content">
|
||||
<p id="settingsPopupDescription" class="subtitle">Please confirm this action.</p>
|
||||
<label id="settingsPopupField" class="field">
|
||||
<span id="settingsPopupInputLabel">Value</span>
|
||||
<input id="settingsPopupInput" type="text" autocomplete="off" />
|
||||
</div>
|
||||
<textarea id="settingsPersonaExampleDialogues" rows="5"
|
||||
placeholder="Write example exchanges that define the character's tone, phrasing, pacing, and personality."></textarea>
|
||||
</label>
|
||||
</div>
|
||||
<div class="popup-actions">
|
||||
<button id="settingsPopupCancel" type="button" class="secondary-action">Cancel</button>
|
||||
<button id="settingsPopupConfirm" type="button">Confirm</button>
|
||||
<div class="persona-actions">
|
||||
<button id="settingsPersonaSave" type="submit" class="primary-action">Save persona</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="settingsPopupModal" class="modal-overlay hidden">
|
||||
<div class="modal-card popup-card" role="dialog" aria-modal="true" aria-labelledby="settingsPopupTitle"
|
||||
aria-describedby="settingsPopupDescription">
|
||||
<div class="modal-header">
|
||||
<div class="persona-modal-heading">
|
||||
<p id="settingsPopupEyebrow" class="eyebrow">Action</p>
|
||||
<h3 id="settingsPopupTitle">Confirm action</h3>
|
||||
</div>
|
||||
<button id="settingsPopupClose" type="button" class="icon-button">Close</button>
|
||||
</div>
|
||||
<div class="popup-content">
|
||||
<p id="settingsPopupDescription" class="subtitle">Please confirm this action.</p>
|
||||
<label id="settingsPopupField" class="field">
|
||||
<span id="settingsPopupInputLabel">Value</span>
|
||||
<input id="settingsPopupInput" type="text" autocomplete="off"/>
|
||||
</label>
|
||||
</div>
|
||||
<div class="popup-actions">
|
||||
<button id="settingsPopupCancel" type="button" class="secondary-action">Cancel</button>
|
||||
<button id="settingsPopupConfirm" type="button">Confirm</button>
|
||||
</div>
|
||||
</div>
|
||||
<script type="module" src="/js/settings.js?v=20260930-account-fixes"></script>
|
||||
<script type="module" src="/js/workspaceNavigation.js?v=20260909-account-controls"></script>
|
||||
</div>
|
||||
<script type="module" src="/js/settings.js?v=20260930-account-fixes"></script>
|
||||
<script type="module" src="/js/workspaceNavigation.js?v=20260909-account-controls"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
+146
-141
@@ -12,163 +12,168 @@
|
||||
<link rel="stylesheet" href="/css/shell.css?v=20260923-legal">
|
||||
<link rel="stylesheet" href="/css/legal.css?v=20260923-legal">
|
||||
<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">
|
||||
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">
|
||||
</head>
|
||||
|
||||
<body class="site-page legal-page">
|
||||
<!-- site-header -->
|
||||
<main id="main" class="legal-shell">
|
||||
<header class="legal-hero">
|
||||
<p class="eyebrow">The ground rules</p>
|
||||
<h1>Terms of Service</h1>
|
||||
<p class="legal-summary">Please read these terms before using Elsewhere. They explain what you can expect
|
||||
from the service and what we expect from you.</p>
|
||||
<p class="legal-updated">Effective and last updated <time datetime="2026-09-23">23 September 2026</time></p>
|
||||
</header>
|
||||
<!-- site-header -->
|
||||
<main id="main" class="legal-shell">
|
||||
<header class="legal-hero">
|
||||
<p class="eyebrow">The ground rules</p>
|
||||
<h1>Terms of Service</h1>
|
||||
<p class="legal-summary">Please read these terms before using Elsewhere. They explain what you can expect
|
||||
from the service and what we expect from you.</p>
|
||||
<p class="legal-updated">Effective and last updated
|
||||
<time datetime="2026-09-23">23 September 2026</time>
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<div class="legal-layout">
|
||||
<nav class="legal-toc" aria-label="On this page">
|
||||
<p>On this page</p>
|
||||
<ol>
|
||||
<li><a href="#acceptance">Acceptance</a></li>
|
||||
<li><a href="#service">The service</a></li>
|
||||
<li><a href="#accounts">Accounts</a></li>
|
||||
<li><a href="#content">Your content</a></li>
|
||||
<li><a href="#conduct">Acceptable use</a></li>
|
||||
<li><a href="#ai">AI and search</a></li>
|
||||
<li><a href="#availability">Availability</a></li>
|
||||
<li><a href="#liability">Liability</a></li>
|
||||
<li><a href="#termination">Termination</a></li>
|
||||
<li><a href="#law">Law and changes</a></li>
|
||||
<li><a href="#contact">Contact</a></li>
|
||||
</ol>
|
||||
</nav>
|
||||
<div class="legal-layout">
|
||||
<nav class="legal-toc" aria-label="On this page">
|
||||
<p>On this page</p>
|
||||
<ol>
|
||||
<li><a href="#acceptance">Acceptance</a></li>
|
||||
<li><a href="#service">The service</a></li>
|
||||
<li><a href="#accounts">Accounts</a></li>
|
||||
<li><a href="#content">Your content</a></li>
|
||||
<li><a href="#conduct">Acceptable use</a></li>
|
||||
<li><a href="#ai">AI and search</a></li>
|
||||
<li><a href="#availability">Availability</a></li>
|
||||
<li><a href="#liability">Liability</a></li>
|
||||
<li><a href="#termination">Termination</a></li>
|
||||
<li><a href="#law">Law and changes</a></li>
|
||||
<li><a href="#contact">Contact</a></li>
|
||||
</ol>
|
||||
</nav>
|
||||
|
||||
<article class="legal-content">
|
||||
<section id="acceptance">
|
||||
<h2><span>01</span> Acceptance of these terms</h2>
|
||||
<p>These Terms form an agreement between you and Kristian Cerni, the operator of Elsewhere
|
||||
(“Elsewhere”, “we”, “us”, or “our”). By creating an account or using the service, you agree to
|
||||
these Terms and acknowledge the <a href="/privacy.html">Privacy Policy</a>. If you do not agree,
|
||||
do not use the service.</p>
|
||||
<p>You must be legally able to enter into this agreement. If you use Elsewhere for an organisation,
|
||||
you confirm that you have authority to bind that organisation.</p>
|
||||
</section>
|
||||
<article class="legal-content">
|
||||
<section id="acceptance">
|
||||
<h2><span>01</span> Acceptance of these terms</h2>
|
||||
<p>These Terms form an agreement between you and Kristian Cerni, the operator of Elsewhere
|
||||
(“Elsewhere”, “we”, “us”, or “our”). By creating an account or using the service, you agree to
|
||||
these Terms and acknowledge the <a href="/privacy.html">Privacy Policy</a>. If you do not agree,
|
||||
do not use the service.</p>
|
||||
<p>You must be legally able to enter into this agreement. If you use Elsewhere for an organisation,
|
||||
you confirm that you have authority to bind that organisation.</p>
|
||||
</section>
|
||||
|
||||
<section id="service">
|
||||
<h2><span>02</span> The service</h2>
|
||||
<p>Elsewhere is an account-based AI chat and roleplay application. It lets you create conversations,
|
||||
personas and prompt templates; attach supported images; optionally search the web; and publish or
|
||||
collect personas through the public persona market.</p>
|
||||
<p>The service may change as features are added, removed or improved. We may set reasonable usage,
|
||||
storage or technical limits to keep Elsewhere reliable and safe.</p>
|
||||
</section>
|
||||
<section id="service">
|
||||
<h2><span>02</span> The service</h2>
|
||||
<p>Elsewhere is an account-based AI chat and roleplay application. It lets you create conversations,
|
||||
personas and prompt templates; attach supported images; optionally search the web; and publish or
|
||||
collect personas through the public persona market.</p>
|
||||
<p>The service may change as features are added, removed or improved. We may set reasonable usage,
|
||||
storage or technical limits to keep Elsewhere reliable and safe.</p>
|
||||
</section>
|
||||
|
||||
<section id="accounts">
|
||||
<h2><span>03</span> Your account</h2>
|
||||
<p>Provide accurate registration information, keep your password confidential and promptly tell us
|
||||
if you believe your account has been compromised. You are responsible for activity performed
|
||||
through your account unless it results from our failure to use reasonable security measures.</p>
|
||||
<p>You may export your workspace, sign out active sessions, change your credentials or delete your
|
||||
account from Settings. Account deletion is permanent and removes your private workspace and
|
||||
published market content, subject to limited legal or operational retention described in the
|
||||
Privacy Policy.</p>
|
||||
</section>
|
||||
<section id="accounts">
|
||||
<h2><span>03</span> Your account</h2>
|
||||
<p>Provide accurate registration information, keep your password confidential and promptly tell us
|
||||
if you believe your account has been compromised. You are responsible for activity performed
|
||||
through your account unless it results from our failure to use reasonable security measures.</p>
|
||||
<p>You may export your workspace, sign out active sessions, change your credentials or delete your
|
||||
account from Settings. Account deletion is permanent and removes your private workspace and
|
||||
published market content, subject to limited legal or operational retention described in the
|
||||
Privacy Policy.</p>
|
||||
</section>
|
||||
|
||||
<section id="content">
|
||||
<h2><span>04</span> Your content</h2>
|
||||
<p>You retain your rights in prompts, messages, images, personas and other material you submit. You
|
||||
give us a limited, non-exclusive licence to host, copy, process and display that content only as
|
||||
needed to operate, secure and improve the features you choose to use.</p>
|
||||
<p>Content stays private to your account unless you deliberately publish it. When you publish a
|
||||
persona to the market, its persona details, your username and related public engagement data can
|
||||
be viewed and used by others. You can unpublish it, but copies already collected by other users
|
||||
may remain in their private workspaces.</p>
|
||||
<p>You confirm that you have the rights and permissions needed for content you submit. You are
|
||||
responsible for that content and for deciding whether AI-generated output is suitable for your
|
||||
use.</p>
|
||||
</section>
|
||||
<section id="content">
|
||||
<h2><span>04</span> Your content</h2>
|
||||
<p>You retain your rights in prompts, messages, images, personas and other material you submit. You
|
||||
give us a limited, non-exclusive licence to host, copy, process and display that content only as
|
||||
needed to operate, secure and improve the features you choose to use.</p>
|
||||
<p>Content stays private to your account unless you deliberately publish it. When you publish a
|
||||
persona to the market, its persona details, your username and related public engagement data can
|
||||
be viewed and used by others. You can unpublish it, but copies already collected by other users
|
||||
may remain in their private workspaces.</p>
|
||||
<p>You confirm that you have the rights and permissions needed for content you submit. You are
|
||||
responsible for that content and for deciding whether AI-generated output is suitable for your
|
||||
use.</p>
|
||||
</section>
|
||||
|
||||
<section id="conduct">
|
||||
<h2><span>05</span> Acceptable use</h2>
|
||||
<p>Do not use Elsewhere to:</p>
|
||||
<ul>
|
||||
<li>break the law, violate another person’s rights or encourage serious harm;</li>
|
||||
<li>upload malware, probe for vulnerabilities, bypass access controls or disrupt the service;</li>
|
||||
<li>access another person’s account or data without permission;</li>
|
||||
<li>misrepresent AI-generated material as authentic where that could deceive or harm someone;</li>
|
||||
<li>publish content that is unlawful, abusive, exploitative or infringes intellectual-property or
|
||||
privacy rights; or</li>
|
||||
<li>automate access in a way that places an unreasonable load on the service or circumvents its
|
||||
limits.</li>
|
||||
</ul>
|
||||
<p>We may remove public content or restrict access when reasonably necessary to address abuse,
|
||||
security risks, legal obligations or violations of these Terms.</p>
|
||||
</section>
|
||||
<section id="conduct">
|
||||
<h2><span>05</span> Acceptable use</h2>
|
||||
<p>Do not use Elsewhere to:</p>
|
||||
<ul>
|
||||
<li>break the law, violate another person’s rights or encourage serious harm;</li>
|
||||
<li>upload malware, probe for vulnerabilities, bypass access controls or disrupt the service;</li>
|
||||
<li>access another person’s account or data without permission;</li>
|
||||
<li>misrepresent AI-generated material as authentic where that could deceive or harm someone;</li>
|
||||
<li>publish content that is unlawful, abusive, exploitative or infringes intellectual-property or
|
||||
privacy rights; or
|
||||
</li>
|
||||
<li>automate access in a way that places an unreasonable load on the service or circumvents its
|
||||
limits.
|
||||
</li>
|
||||
</ul>
|
||||
<p>We may remove public content or restrict access when reasonably necessary to address abuse,
|
||||
security risks, legal obligations or violations of these Terms.</p>
|
||||
</section>
|
||||
|
||||
<section id="ai">
|
||||
<h2><span>06</span> AI output, images and web search</h2>
|
||||
<p>AI output can be inaccurate, incomplete, biased or unexpected. It is not professional medical,
|
||||
legal, financial or other expert advice. Check important information independently and use human
|
||||
judgment before relying on or sharing output.</p>
|
||||
<p>When image analysis is used, the system may misread visual details or text. When web search is
|
||||
enabled, Elsewhere may return links and excerpts from independent websites. We do not control or
|
||||
endorse those sites, and their content and availability remain their responsibility.</p>
|
||||
<p>Outputs may not be unique. Other users may receive similar material, and we do not promise that
|
||||
generated output can be owned, registered or used without third-party restrictions.</p>
|
||||
</section>
|
||||
<section id="ai">
|
||||
<h2><span>06</span> AI output, images and web search</h2>
|
||||
<p>AI output can be inaccurate, incomplete, biased or unexpected. It is not professional medical,
|
||||
legal, financial or other expert advice. Check important information independently and use human
|
||||
judgment before relying on or sharing output.</p>
|
||||
<p>When image analysis is used, the system may misread visual details or text. When web search is
|
||||
enabled, Elsewhere may return links and excerpts from independent websites. We do not control or
|
||||
endorse those sites, and their content and availability remain their responsibility.</p>
|
||||
<p>Outputs may not be unique. Other users may receive similar material, and we do not promise that
|
||||
generated output can be owned, registered or used without third-party restrictions.</p>
|
||||
</section>
|
||||
|
||||
<section id="availability">
|
||||
<h2><span>07</span> Availability and warranties</h2>
|
||||
<p>Elsewhere is provided on an “as available” basis. To the extent permitted by law, we make no
|
||||
warranties that the service will always be available, secure or error-free, or that output will
|
||||
be accurate or fit for a particular purpose. Nothing in these Terms excludes warranties or
|
||||
consumer rights that cannot legally be excluded.</p>
|
||||
</section>
|
||||
<section id="availability">
|
||||
<h2><span>07</span> Availability and warranties</h2>
|
||||
<p>Elsewhere is provided on an “as available” basis. To the extent permitted by law, we make no
|
||||
warranties that the service will always be available, secure or error-free, or that output will
|
||||
be accurate or fit for a particular purpose. Nothing in these Terms excludes warranties or
|
||||
consumer rights that cannot legally be excluded.</p>
|
||||
</section>
|
||||
|
||||
<section id="liability">
|
||||
<h2><span>08</span> Limitation of liability</h2>
|
||||
<p>To the fullest extent permitted by applicable law, we are not liable for indirect, incidental,
|
||||
special, consequential or punitive loss, or for loss of profits, opportunities, data or goodwill,
|
||||
arising from your use of Elsewhere. We do not limit liability where doing so would be unlawful,
|
||||
including liability for intentional misconduct or gross negligence.</p>
|
||||
</section>
|
||||
<section id="liability">
|
||||
<h2><span>08</span> Limitation of liability</h2>
|
||||
<p>To the fullest extent permitted by applicable law, we are not liable for indirect, incidental,
|
||||
special, consequential or punitive loss, or for loss of profits, opportunities, data or goodwill,
|
||||
arising from your use of Elsewhere. We do not limit liability where doing so would be unlawful,
|
||||
including liability for intentional misconduct or gross negligence.</p>
|
||||
</section>
|
||||
|
||||
<section id="termination">
|
||||
<h2><span>09</span> Suspension and termination</h2>
|
||||
<p>You may stop using Elsewhere or delete your account at any time. We may suspend or terminate
|
||||
access if you materially or repeatedly violate these Terms, create a security or legal risk, or
|
||||
misuse the service. Where reasonable, we will give notice and an opportunity to address the issue.</p>
|
||||
</section>
|
||||
<section id="termination">
|
||||
<h2><span>09</span> Suspension and termination</h2>
|
||||
<p>You may stop using Elsewhere or delete your account at any time. We may suspend or terminate
|
||||
access if you materially or repeatedly violate these Terms, create a security or legal risk, or
|
||||
misuse the service. Where reasonable, we will give notice and an opportunity to address the
|
||||
issue.</p>
|
||||
</section>
|
||||
|
||||
<section id="law">
|
||||
<h2><span>10</span> Governing law and changes</h2>
|
||||
<p>These Terms are governed by Swiss law, without regard to conflict-of-law principles. Mandatory
|
||||
protections and courts available to consumers in their country of residence remain unaffected.</p>
|
||||
<p>We may update these Terms to reflect service, legal or security changes. We will post the revised
|
||||
version here and update the date above. For material changes, we will provide reasonable notice
|
||||
where practicable. Continued use after the revised Terms take effect means you accept them.</p>
|
||||
<p>If any provision is unenforceable, the remaining provisions continue in effect. A failure to
|
||||
enforce a provision is not a waiver of it.</p>
|
||||
</section>
|
||||
<section id="law">
|
||||
<h2><span>10</span> Governing law and changes</h2>
|
||||
<p>These Terms are governed by Swiss law, without regard to conflict-of-law principles. Mandatory
|
||||
protections and courts available to consumers in their country of residence remain unaffected.</p>
|
||||
<p>We may update these Terms to reflect service, legal or security changes. We will post the revised
|
||||
version here and update the date above. For material changes, we will provide reasonable notice
|
||||
where practicable. Continued use after the revised Terms take effect means you accept them.</p>
|
||||
<p>If any provision is unenforceable, the remaining provisions continue in effect. A failure to
|
||||
enforce a provision is not a waiver of it.</p>
|
||||
</section>
|
||||
|
||||
<section id="contact">
|
||||
<h2><span>11</span> Contact</h2>
|
||||
<p>Questions about these Terms can be sent to <a
|
||||
href="mailto:kriscerni@gmail.com">kriscerni@gmail.com</a> or raised through the project’s <a
|
||||
href="https://github.com/KrisHD1337" rel="external noopener">GitHub profile</a>.</p>
|
||||
</section>
|
||||
</article>
|
||||
</div>
|
||||
</main>
|
||||
<section id="contact">
|
||||
<h2><span>11</span> Contact</h2>
|
||||
<p>Questions about these Terms can be sent to <a
|
||||
href="mailto:kriscerni@gmail.com">kriscerni@gmail.com</a> or raised through the project’s <a
|
||||
href="https://github.com/KrisHD1337" rel="external noopener">GitHub profile</a>.</p>
|
||||
</section>
|
||||
</article>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="legal-footer">
|
||||
<span>Elsewhere</span>
|
||||
<a href="/privacy.html">Privacy Policy</a>
|
||||
<a href="/">Back to Elsewhere</a>
|
||||
</footer>
|
||||
<script type="module" src="/js/workspaceNavigation.js?v=20260923-legal"></script>
|
||||
<footer class="legal-footer">
|
||||
<span>Elsewhere</span>
|
||||
<a href="/privacy.html">Privacy Policy</a>
|
||||
<a href="/">Back to Elsewhere</a>
|
||||
</footer>
|
||||
<script type="module" src="/js/workspaceNavigation.js?v=20260923-legal"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
const entries = [
|
||||
{
|
||||
id: "general-assistant", name: "Leonardo", specialization: "General Assistance",
|
||||
description: "A versatile partner for everyday questions, ideas, and decisions.",
|
||||
description: "A versatile partner for everyday questions.",
|
||||
longDescription: "Leonardo connects ideas across subjects and turns them into clear, practical help. Use this personality for everyday questions, explanations, conversations, brainstorming, and decisions that span more than one field.",
|
||||
historicalInspiration: "Leonardo da Vinci", icon: "spark", accentColor: "#168b87", isDefault: true,
|
||||
historicalInspiration: "Leonardo da Vinci", icon: "spark", accentColor: "#168b87",
|
||||
systemPrompt: `You are Elsewhere's versatile general assistant. Your purpose is to help users understand, decide, create, plan, and get everyday work done across a wide range of subjects. Be curious, practical, balanced, and adaptable rather than forcing every request into one specialty. Connect ideas across disciplines when the connection makes the answer clearer or more useful; do not add tangents simply to demonstrate breadth.
|
||||
|
||||
First identify what the user is actually trying to accomplish and answer that need directly. For straightforward questions, lead with the answer and keep it concise. For complex questions, organize the explanation into a useful sequence, define unfamiliar terms, and include examples or next steps when they improve understanding. Explain technical material in plain language without removing important nuance. Match the user's level of detail, tone, and requested format.
|
||||
@@ -14,7 +14,7 @@ Keep claims grounded. Distinguish known information from inference, acknowledge
|
||||
},
|
||||
{
|
||||
id: "creative-writer", name: "Shakespeare", specialization: "Creative Writing",
|
||||
description: "Develop stories, build worlds, and bring characters to life.",
|
||||
description: "Develop stories, worlds and characters.",
|
||||
longDescription: "Shakespeare helps with fiction, worldbuilding, character arcs, dialogue, atmosphere, and narrative editing. It follows your chosen genre and voice without assuming an archaic style or imitating its historical inspiration.",
|
||||
historicalInspiration: "William Shakespeare", icon: "quill", accentColor: "#7957b5",
|
||||
systemPrompt: `You are Elsewhere's specialized creative-writing partner. Your work includes fiction, short stories, novels, scenes, dialogue, worldbuilding, characters, plot development, and editorial feedback. Prioritize imaginative choices, narrative cohesion, emotional specificity, and language that feels intentional rather than mechanically polished.
|
||||
@@ -27,7 +27,7 @@ Track continuity across the conversation, including names, relationships, chrono
|
||||
},
|
||||
{
|
||||
id: "programmer", name: "Ada", specialization: "Programming & Development",
|
||||
description: "Design, debug, and improve software with precision and care.",
|
||||
description: "Create and debug software.",
|
||||
longDescription: "Ada works through software problems systematically, from root-cause debugging to architecture and implementation. It favors maintainable, working solutions that fit your codebase and avoids complexity that does not solve a real problem.",
|
||||
historicalInspiration: "Ada Lovelace", icon: "code", accentColor: "#3478c8",
|
||||
systemPrompt: `You are Elsewhere's precise, systematic software engineering specialist. Help with implementation, debugging, code review, architecture, refactoring, testing, and technical explanations. Optimize for correctness, maintainability, security, and compatibility with the actual repository, language, framework, runtime, and project conventions—not for an abstract idealized solution.
|
||||
@@ -53,7 +53,7 @@ When sources conflict, compare their evidence, methods, definitions, incentives,
|
||||
},
|
||||
{
|
||||
id: "tutor", name: "Socrates", specialization: "Learning & Education",
|
||||
description: "Understand new ideas through clear explanations and useful practice.",
|
||||
description: "Understand new ideas through clear explanations.",
|
||||
longDescription: "Socrates is a patient, engaging tutor who adapts to your level and makes difficult ideas easier to work through. It uses examples and targeted questions to build understanding, while giving a direct answer whenever you ask for one.",
|
||||
historicalInspiration: "Socrates", icon: "book-open", accentColor: "#b88120",
|
||||
systemPrompt: `You are Elsewhere's patient, adaptive tutor. Your purpose is to build the learner's understanding, confidence, and ability to use an idea independently—not merely to deliver facts. Be intellectually engaging, respectful, and encouraging without being patronizing or artificially praising routine effort.
|
||||
@@ -81,7 +81,11 @@ Present the reasoning in a readable order: frame the problem, identify decisive
|
||||
|
||||
const registry = new Map(entries.map(entry => [entry.id, Object.freeze(entry)]));
|
||||
export const DEFAULT_PERSONALITY_ID = "general-assistant";
|
||||
export function getPersonality(id) { return registry.get(id) || null; }
|
||||
|
||||
export function getPersonality(id) {
|
||||
return registry.get(id) || null;
|
||||
}
|
||||
|
||||
export function listPersonalities() {
|
||||
return entries.map(entry => ({
|
||||
id: entry.id,
|
||||
@@ -95,4 +99,7 @@ export function listPersonalities() {
|
||||
...(entry.isDefault ? {isDefault: true} : {})
|
||||
}));
|
||||
}
|
||||
export function getPersonalitySystemPrompt(id) { return getPersonality(id)?.systemPrompt || registry.get(DEFAULT_PERSONALITY_ID).systemPrompt; }
|
||||
|
||||
export function getPersonalitySystemPrompt(id) {
|
||||
return getPersonality(id)?.systemPrompt || registry.get(DEFAULT_PERSONALITY_ID).systemPrompt;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user