895 lines
38 KiB
HTML
895 lines
38 KiB
HTML
<!--
|
|
This is free software for the public good of a permacomputer hosted at
|
|
permacomputer.com, an always-on computer by the people, for the people.
|
|
One which is durable, easy to repair, & distributed like tap water
|
|
for machine learning intelligence.
|
|
|
|
The permacomputer is community-owned infrastructure optimized around
|
|
four values:
|
|
|
|
TRUTH First principles, math & science, open source code freely distributed
|
|
FREEDOM Voluntary partnerships, freedom from tyranny & corporate control
|
|
HARMONY Minimal waste, self-renewing systems with diverse thriving connections
|
|
LOVE Be yourself without hurting others, cooperation through natural law
|
|
|
|
This software contributes to that vision by making machine learning
|
|
accessible to everyone through a free, open, embeddable chat interface.
|
|
Code is seeds to sprout on any abandoned technology.
|
|
-->
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<meta name="theme-color" content="#43a047">
|
|
<meta name="color-scheme" content="light dark">
|
|
<title>Styleguide - uncloseai.js Component Reference | uncloseai.com</title>
|
|
|
|
<!-- PicoCSS -->
|
|
<link rel="stylesheet" href="/css/pico.classless.min.css">
|
|
<!-- ChunkFive Font -->
|
|
<link rel="stylesheet" href="/css/chunkfive/stylesheet.css" type="text/css" charset="utf-8" />
|
|
<!-- Sidebar Theme -->
|
|
<link rel="stylesheet" href="/css/sidebar-theme.css">
|
|
|
|
<!-- Highlight.js for syntax highlighting -->
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/styles/a11y-dark.min.css" />
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/highlight.min.js"></script>
|
|
|
|
<!-- Theme Switcher Script -->
|
|
<script>
|
|
function switchTheme(theme) {
|
|
if (theme === "auto") {
|
|
document.documentElement.removeAttribute('data-theme');
|
|
} else {
|
|
document.documentElement.setAttribute('data-theme', theme);
|
|
}
|
|
}
|
|
|
|
// Disable custom styling for uncloseai.js - use PicoCSS instead
|
|
window.UNCLOSEAI_CUSTOM_STYLING = false;
|
|
</script>
|
|
|
|
<script src="https://uncloseai.com/uncloseai.js" type="module"></script>
|
|
|
|
<style>
|
|
/* Styleguide-specific styles */
|
|
.sg-swatch-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
|
|
gap: 12px;
|
|
margin: 16px 0;
|
|
}
|
|
.sg-swatch {
|
|
border-radius: 8px;
|
|
overflow: hidden;
|
|
border: 1px solid var(--muted-border-color);
|
|
}
|
|
.sg-swatch-color {
|
|
height: 64px;
|
|
}
|
|
.sg-swatch-label {
|
|
padding: 8px;
|
|
font-size: 0.8em;
|
|
font-family: monospace;
|
|
line-height: 1.4;
|
|
}
|
|
|
|
/* Vault gate demo containers */
|
|
.sg-vault-demo {
|
|
border-radius: 12px;
|
|
overflow: hidden;
|
|
position: relative;
|
|
min-height: 380px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 24px;
|
|
margin: 16px 0;
|
|
}
|
|
.sg-vault-demo-dark {
|
|
background: #1a1a2e;
|
|
color: white;
|
|
}
|
|
.sg-vault-demo-light {
|
|
background: #f8f9fa;
|
|
color: #212529;
|
|
}
|
|
|
|
/* Vault card styling for static demos */
|
|
.sg-vault-card {
|
|
display: grid;
|
|
gap: 14px;
|
|
width: 100%;
|
|
max-width: 420px;
|
|
text-align: center;
|
|
padding: 28px 24px;
|
|
border-radius: 12px;
|
|
}
|
|
.sg-vault-card-dark {
|
|
background: rgba(255, 255, 255, 0.06);
|
|
border: 1px solid rgba(255, 255, 255, 0.12);
|
|
}
|
|
.sg-vault-card-light {
|
|
background: white;
|
|
border: 1px solid rgba(0, 0, 0, 0.08);
|
|
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
|
|
}
|
|
.sg-vault-icon {
|
|
font-size: 1.8em;
|
|
line-height: 1;
|
|
}
|
|
.sg-vault-title {
|
|
font-family: 'ChunkFiveRegular', monospace;
|
|
font-size: 1.5em;
|
|
letter-spacing: -0.02em;
|
|
}
|
|
.sg-vault-explanation {
|
|
font-size: 0.85em;
|
|
line-height: 1.5;
|
|
}
|
|
.sg-vault-explanation-dark {
|
|
color: rgba(255, 255, 255, 0.72);
|
|
}
|
|
.sg-vault-explanation-light {
|
|
color: #495057;
|
|
}
|
|
.sg-vault-input {
|
|
width: 100%;
|
|
padding: 12px 14px;
|
|
font-size: 0.95em;
|
|
border-radius: 8px;
|
|
border: 1.5px solid transparent;
|
|
outline: none;
|
|
transition: border-color 0.2s, box-shadow 0.2s;
|
|
box-sizing: border-box;
|
|
}
|
|
.sg-vault-input-dark {
|
|
background: rgba(255, 255, 255, 0.07);
|
|
border-color: rgba(255, 255, 255, 0.12);
|
|
color: white;
|
|
}
|
|
.sg-vault-input-dark::placeholder {
|
|
color: rgba(255, 255, 255, 0.4);
|
|
}
|
|
.sg-vault-input-light {
|
|
background: #f8f9fa;
|
|
border-color: #dee2e6;
|
|
color: #212529;
|
|
}
|
|
.sg-vault-input-light::placeholder {
|
|
color: #adb5bd;
|
|
}
|
|
.sg-vault-submit {
|
|
width: 100%;
|
|
padding: 12px;
|
|
font-size: 0.95em;
|
|
font-weight: 600;
|
|
border: none;
|
|
border-radius: 8px;
|
|
cursor: pointer;
|
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
color: white;
|
|
transition: opacity 0.15s, box-shadow 0.15s;
|
|
letter-spacing: 0.02em;
|
|
}
|
|
.sg-vault-submit:hover {
|
|
opacity: 0.92;
|
|
box-shadow: 0 2px 8px rgba(102, 126, 234, 0.35);
|
|
}
|
|
.sg-vault-error {
|
|
font-size: 0.85em;
|
|
color: #dc3545;
|
|
}
|
|
|
|
/* Chat message demos */
|
|
.sg-chat-demo {
|
|
border-radius: 8px;
|
|
padding: 16px;
|
|
display: grid;
|
|
gap: 12px;
|
|
margin: 16px 0;
|
|
}
|
|
.sg-chat-demo-dark {
|
|
background: #1a1a1a;
|
|
}
|
|
.sg-chat-demo-light {
|
|
background: #f8f9fa;
|
|
}
|
|
.sg-msg-user {
|
|
background: rgba(0, 123, 255, 0.95);
|
|
color: white;
|
|
padding: 12px 16px;
|
|
border-radius: 18px 18px 4px 18px;
|
|
max-width: 80%;
|
|
margin-left: auto;
|
|
width: fit-content;
|
|
font-size: 14px;
|
|
}
|
|
.sg-msg-ai {
|
|
padding: 12px 16px;
|
|
border-radius: 18px 18px 18px 4px;
|
|
max-width: 80%;
|
|
margin-right: auto;
|
|
width: fit-content;
|
|
font-size: 14px;
|
|
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
|
|
}
|
|
.sg-msg-ai-dark {
|
|
background: #2d3748;
|
|
color: #e2e8f0;
|
|
}
|
|
.sg-msg-ai-light {
|
|
background: white;
|
|
color: #495057;
|
|
}
|
|
.sg-msg-user-dark {
|
|
background: #667eea;
|
|
}
|
|
|
|
/* Modal header demo */
|
|
.sg-header-demo {
|
|
padding: 16px;
|
|
color: white;
|
|
display: grid;
|
|
grid-template-columns: 1fr auto;
|
|
align-items: center;
|
|
border-radius: 12px;
|
|
margin: 16px 0;
|
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
}
|
|
.sg-header-demo-purple {
|
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
}
|
|
.sg-header-demo-green {
|
|
background: linear-gradient(45deg, #4CAF50 0%, #45a049 100%);
|
|
}
|
|
.sg-header-title {
|
|
font-weight: 600;
|
|
font-size: 20px;
|
|
}
|
|
.sg-header-title-brand {
|
|
font-family: 'ChunkFiveRegular', monospace;
|
|
}
|
|
.sg-header-subtitle {
|
|
font-size: 12px;
|
|
opacity: 0.9;
|
|
}
|
|
.sg-header-btn {
|
|
background: rgba(255, 255, 255, 0.2);
|
|
border: none;
|
|
color: white;
|
|
font-size: 18px;
|
|
width: 36px;
|
|
height: 36px;
|
|
border-radius: 50%;
|
|
cursor: pointer;
|
|
display: grid;
|
|
place-content: center;
|
|
}
|
|
.sg-header-btn-row {
|
|
display: grid;
|
|
grid-auto-flow: column;
|
|
grid-auto-columns: max-content;
|
|
gap: 8px;
|
|
align-items: center;
|
|
}
|
|
|
|
/* Control strip demo */
|
|
.sg-controls-demo {
|
|
padding: 8px 16px;
|
|
border: 1px solid var(--muted-border-color);
|
|
border-radius: 8px;
|
|
display: grid;
|
|
grid-auto-flow: column;
|
|
grid-auto-columns: max-content;
|
|
gap: 18px;
|
|
overflow-x: auto;
|
|
margin: 16px 0;
|
|
}
|
|
.sg-btn-control {
|
|
padding: 8px 12px;
|
|
border: 1px solid #dee2e6;
|
|
border-radius: 6px;
|
|
cursor: pointer;
|
|
font-size: 18px;
|
|
color: var(--color);
|
|
background: var(--card-background-color);
|
|
transition: all 0.2s;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
/* Button gallery */
|
|
.sg-btn-grid {
|
|
display: flex;
|
|
gap: 12px;
|
|
flex-wrap: wrap;
|
|
align-items: center;
|
|
margin: 16px 0;
|
|
}
|
|
.sg-gradient-btn {
|
|
padding: 10px 20px;
|
|
font-size: 0.95em;
|
|
font-weight: 600;
|
|
border: none;
|
|
border-radius: 8px;
|
|
cursor: pointer;
|
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
color: white;
|
|
}
|
|
.sg-send-btn {
|
|
width: 44px;
|
|
height: 44px;
|
|
padding: 0;
|
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
color: white;
|
|
border: none;
|
|
border-radius: 50%;
|
|
cursor: pointer;
|
|
font-size: 20px;
|
|
font-weight: bold;
|
|
display: grid;
|
|
place-items: center;
|
|
}
|
|
|
|
/* Input demo */
|
|
.sg-input-demo {
|
|
display: grid;
|
|
gap: 12px;
|
|
margin: 16px 0;
|
|
max-width: 400px;
|
|
}
|
|
.sg-input {
|
|
padding: 12px;
|
|
border: 1px solid var(--muted-border-color);
|
|
border-radius: 24px;
|
|
font-size: 16px;
|
|
font-family: inherit;
|
|
outline: none;
|
|
transition: border-color 0.2s;
|
|
background: var(--card-background-color);
|
|
color: var(--color);
|
|
}
|
|
.sg-input:focus {
|
|
border-color: #667eea;
|
|
}
|
|
.sg-input-rect {
|
|
padding: 12px 14px;
|
|
font-size: 0.95em;
|
|
border-radius: 8px;
|
|
border: 1.5px solid var(--muted-border-color);
|
|
outline: none;
|
|
transition: border-color 0.2s, box-shadow 0.2s;
|
|
box-sizing: border-box;
|
|
background: var(--card-background-color);
|
|
color: var(--color);
|
|
}
|
|
.sg-input-rect:focus {
|
|
border-color: #667eea;
|
|
box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.2);
|
|
}
|
|
|
|
/* Message actions demo */
|
|
.sg-msg-actions {
|
|
display: grid;
|
|
grid-auto-flow: column;
|
|
grid-auto-columns: max-content;
|
|
gap: 18px;
|
|
opacity: 0.8;
|
|
justify-content: end;
|
|
font-size: 14px;
|
|
margin-top: 4px;
|
|
}
|
|
.sg-msg-action-btn {
|
|
background: none;
|
|
border: none;
|
|
cursor: pointer;
|
|
color: var(--color);
|
|
opacity: 0.6;
|
|
font-size: 14px;
|
|
}
|
|
|
|
/* Floating button demo */
|
|
.sg-floating-demo {
|
|
display: flex;
|
|
justify-content: center;
|
|
margin: 16px 0;
|
|
}
|
|
.sg-floating-btn {
|
|
width: 120px;
|
|
height: 55px;
|
|
border-radius: 22px;
|
|
font-family: 'ChunkFiveRegular', monospace;
|
|
font-size: 13px;
|
|
cursor: pointer;
|
|
box-shadow: 0 4px 12px rgba(0,0,0,0.3);
|
|
background: #000;
|
|
border: 2px solid #fff;
|
|
color: #fff;
|
|
display: grid;
|
|
place-content: center;
|
|
}
|
|
|
|
/* Two column layout for side-by-side demos */
|
|
.sg-side-by-side {
|
|
display: grid;
|
|
grid-template-columns: 1fr 1fr;
|
|
gap: 16px;
|
|
margin: 16px 0;
|
|
}
|
|
@media (max-width: 768px) {
|
|
.sg-side-by-side {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
}
|
|
|
|
/* Section labels */
|
|
.sg-label {
|
|
font-size: 0.75em;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.1em;
|
|
opacity: 0.6;
|
|
margin-bottom: 8px;
|
|
}
|
|
</style>
|
|
</head>
|
|
|
|
<body>
|
|
<!-- Mobile menu toggle -->
|
|
<button class="sidebar-toggle" onclick="document.querySelector('.sidebar').classList.toggle('open')">
|
|
☰
|
|
</button>
|
|
|
|
<!-- Left sidebar - Main Navigation -->
|
|
<aside class="sidebar">
|
|
<div class="table-of-contents">
|
|
<nav>
|
|
<ul>
|
|
<li><a href="/">Home</a></li>
|
|
<li><a href="/c-examples.html">C Examples</a></li>
|
|
<li><a href="/csharp-examples.html">C# Examples</a></li>
|
|
<li><a href="/dart-examples.html">Dart Examples</a></li>
|
|
<li><a href="/elixir-examples.html">Elixir Examples</a></li>
|
|
<li><a href="/go-examples.html">Go Examples</a></li>
|
|
<li><a href="/java-examples.html">Java Examples</a></li>
|
|
<li><a href="/kotlin-examples.html">Kotlin Examples</a></li>
|
|
<li><a href="/nodejs-examples.html">Node.js Examples</a></li>
|
|
<li><a href="/php-examples.html">PHP Examples</a></li>
|
|
<li><a href="/python-examples.html">Python Examples</a></li>
|
|
<li><a href="/ruby-examples.html">Ruby Examples</a></li>
|
|
<li><a href="/rust-examples.html">Rust Examples</a></li>
|
|
<li><a href="/swift-examples.html">Swift Examples</a></li>
|
|
<li><a href="/uncloseai-js.html">uncloseai.js Docs</a></li>
|
|
<li><a href="/uncloseai-js-styleguide.html" class="active">Styleguide</a></li>
|
|
<li><a href="/cli.html">uncloseai-cli</a></li>
|
|
<li><a href="/browser-toys.html">Browser Toys</a></li>
|
|
<li><a href="/inference.html">Inference Setup</a></li>
|
|
<li><a href="/text-to-speech.html">Text-to-Speech</a></li>
|
|
<li><a href="/crawler.html">Our Crawler</a></li>
|
|
<li><a href="/reverse-retrieval-augmented-generations-rag.html">Reverse RAG</a></li>
|
|
<li><a href="/languages" target="_blank">🔗 All Languages</a></li>
|
|
<li><a href="https://shop.unturf.com/p/8486f492-a93e-11f0-b477-02dfe05770ee/uncloseai-machine-learning-reference-guide-to-inference-clients" target="_blank">📚 Book</a></li>
|
|
</ul>
|
|
</nav>
|
|
</div>
|
|
</aside>
|
|
|
|
<!-- Main content -->
|
|
<main>
|
|
<header>
|
|
<hgroup>
|
|
<a href="https://uncloseai.com"><h1 class="unturf" style="font-family: 'ChunkFiveRegular';">uncloseai.</h1></a>
|
|
<p>Styleguide: Component Reference for uncloseai.js</p>
|
|
</hgroup>
|
|
<nav>
|
|
<ul>
|
|
<li><a href="#" onclick="switchTheme('auto')">Auto</a></li>
|
|
<li><a href="#" onclick="switchTheme('light')">Light</a></li>
|
|
<li><a href="#" onclick="switchTheme('dark')">Dark</a></li>
|
|
</ul>
|
|
</nav>
|
|
</header>
|
|
|
|
<h2 id="intro">Styleguide</h2>
|
|
<p>Visual reference for every component in the <strong>uncloseai.js</strong> embed system. This page documents the design tokens, vault onboarding flow, chat interface, and controls. The floating button at the bottom right is the live embed: click it to test the real modal.</p>
|
|
|
|
<!-- ============================================ -->
|
|
<!-- COLOR PALETTE -->
|
|
<!-- ============================================ -->
|
|
<h2 id="colors">Color Palette</h2>
|
|
<p>Core colors used across the modal system. The purple gradient anchors the header, send button, and vault submit. All other colors adapt to light and dark themes via CSS custom properties.</p>
|
|
|
|
<h3 id="brand-colors">Brand Gradient</h3>
|
|
<div class="sg-swatch-grid">
|
|
<div class="sg-swatch">
|
|
<div class="sg-swatch-color" style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);"></div>
|
|
<div class="sg-swatch-label">Gradient<br>#667eea → #764ba2</div>
|
|
</div>
|
|
<div class="sg-swatch">
|
|
<div class="sg-swatch-color" style="background: #667eea;"></div>
|
|
<div class="sg-swatch-label">Primary<br>#667eea</div>
|
|
</div>
|
|
<div class="sg-swatch">
|
|
<div class="sg-swatch-color" style="background: #764ba2;"></div>
|
|
<div class="sg-swatch-label">Secondary<br>#764ba2</div>
|
|
</div>
|
|
</div>
|
|
|
|
<h3 id="ui-colors">Interface Colors</h3>
|
|
<div class="sg-swatch-grid">
|
|
<div class="sg-swatch">
|
|
<div class="sg-swatch-color" style="background: #1a1a2e;"></div>
|
|
<div class="sg-swatch-label" style="color: #666;">Dark BG<br>#1a1a2e</div>
|
|
</div>
|
|
<div class="sg-swatch">
|
|
<div class="sg-swatch-color" style="background: rgb(26, 26, 26);"></div>
|
|
<div class="sg-swatch-label" style="color: #666;">Chat Dark<br>rgb(26,26,26)</div>
|
|
</div>
|
|
<div class="sg-swatch">
|
|
<div class="sg-swatch-color" style="background: #f8f9fa;"></div>
|
|
<div class="sg-swatch-label">Light BG<br>#f8f9fa</div>
|
|
</div>
|
|
<div class="sg-swatch">
|
|
<div class="sg-swatch-color" style="background: #007bff;"></div>
|
|
<div class="sg-swatch-label" style="color: #666;">User Msg<br>#007bff</div>
|
|
</div>
|
|
<div class="sg-swatch">
|
|
<div class="sg-swatch-color" style="background: #2d3748;"></div>
|
|
<div class="sg-swatch-label" style="color: #666;">AI Msg Dark<br>#2d3748</div>
|
|
</div>
|
|
<div class="sg-swatch">
|
|
<div class="sg-swatch-color" style="background: #28a745;"></div>
|
|
<div class="sg-swatch-label" style="color: #666;">Success<br>#28a745</div>
|
|
</div>
|
|
<div class="sg-swatch">
|
|
<div class="sg-swatch-color" style="background: #dc3545;"></div>
|
|
<div class="sg-swatch-label" style="color: #666;">Error<br>#dc3545</div>
|
|
</div>
|
|
<div class="sg-swatch">
|
|
<div class="sg-swatch-color" style="background: #dee2e6;"></div>
|
|
<div class="sg-swatch-label">Border<br>#dee2e6</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- ============================================ -->
|
|
<!-- TYPOGRAPHY -->
|
|
<!-- ============================================ -->
|
|
<h2 id="typography">Typography</h2>
|
|
|
|
<h3 id="type-brand">Brand Font</h3>
|
|
<p style="font-family: 'ChunkFiveRegular', monospace; font-size: 2em;">uncloseai.</p>
|
|
<p><code>font-family: 'ChunkFiveRegular', monospace</code> — used for the h1 branding, vault gate title, and floating button.</p>
|
|
|
|
<h3 id="type-body">Body Text</h3>
|
|
<p>Body text inherits from PicoCSS system font stack. Base size: <code>16px</code>, line-height: <code>1.6</code>.</p>
|
|
<p>Heading scale factor: <code>1.125</code> (major second). h1 through h6 computed via <code>calc(1rem * var(--heading-scale)^n)</code>.</p>
|
|
|
|
<h3 id="type-code">Code</h3>
|
|
<p>Code blocks use <code>highlight.js</code> v11.10.0 with the <code>a11y-dark</code> theme. The modal auto-loads this stylesheet on any host page. Inline code uses PicoCSS monospace styling.</p>
|
|
|
|
<pre><code class="language-javascript">// JavaScript: one-line installation
|
|
const script = document.createElement("script");
|
|
script.src = "https://uncloseai.com/uncloseai.js";
|
|
script.type = "module";
|
|
document.head.appendChild(script);</code></pre>
|
|
|
|
<pre><code class="language-python"># Python: streaming chat with uncloseai
|
|
class UncloseAI:
|
|
def __init__(self):
|
|
self.endpoints = []
|
|
|
|
def chat_stream(self, model, messages):
|
|
for chunk in self._sse_stream(model, messages):
|
|
yield chunk["choices"][0]["delta"]["content"]</code></pre>
|
|
|
|
<pre><code class="language-bash"># Bash: test the TTS endpoint
|
|
curl -X POST https://speech.ai.unturf.com/v1/audio/speech \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"model":"tts-1","voice":"alloy","input":"Hello world"}'</code></pre>
|
|
|
|
<!-- ============================================ -->
|
|
<!-- VAULT GATE -->
|
|
<!-- ============================================ -->
|
|
<h2 id="vault-gate">Vault Gate</h2>
|
|
<p>The vault gate is the first thing every user sees when opening the modal. It encrypts chat history, API keys, and settings behind a password using AES-256 with a device-specific salt. Each website gets its own vault.</p>
|
|
|
|
<h3 id="vault-new-user">New User (Create Vault)</h3>
|
|
<div class="sg-side-by-side">
|
|
<div>
|
|
<div class="sg-label">Dark Theme</div>
|
|
<div class="sg-vault-demo sg-vault-demo-dark">
|
|
<div class="sg-vault-card sg-vault-card-dark">
|
|
<div class="sg-vault-icon">🔐</div>
|
|
<div class="sg-vault-title" style="color: rgba(255,255,255,0.95);">uncloseai.</div>
|
|
<div class="sg-vault-explanation sg-vault-explanation-dark">Your chat history, API keys, and settings are encrypted with AES-256 using a password you choose and a device-specific salt. Each website has its own vault. Choose a password to get started.</div>
|
|
<input type="text" class="sg-vault-input sg-vault-input-dark" placeholder="Choose a password..." disabled>
|
|
<button class="sg-vault-submit" disabled>Create Vault</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<div class="sg-label">Light Theme</div>
|
|
<div class="sg-vault-demo sg-vault-demo-light">
|
|
<div class="sg-vault-card sg-vault-card-light">
|
|
<div class="sg-vault-icon">🔐</div>
|
|
<div class="sg-vault-title" style="color: #1a1a2e;">uncloseai.</div>
|
|
<div class="sg-vault-explanation sg-vault-explanation-light">Your chat history, API keys, and settings are encrypted with AES-256 using a password you choose and a device-specific salt. Each website has its own vault. Choose a password to get started.</div>
|
|
<input type="text" class="sg-vault-input sg-vault-input-light" placeholder="Choose a password..." disabled>
|
|
<button class="sg-vault-submit" disabled>Create Vault</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<h3 id="vault-returning">Returning User (Unlock)</h3>
|
|
<div class="sg-side-by-side">
|
|
<div>
|
|
<div class="sg-label">Dark Theme</div>
|
|
<div class="sg-vault-demo sg-vault-demo-dark">
|
|
<div class="sg-vault-card sg-vault-card-dark">
|
|
<div class="sg-vault-icon">🔓</div>
|
|
<div class="sg-vault-title" style="color: rgba(255,255,255,0.95);">uncloseai.</div>
|
|
<div class="sg-vault-explanation sg-vault-explanation-dark">Your encrypted chat history, API keys, and settings are waiting. Enter your password to unlock this site's vault.</div>
|
|
<input type="text" class="sg-vault-input sg-vault-input-dark" placeholder="Choose a password..." disabled>
|
|
<button class="sg-vault-submit" disabled>Unlock</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<div class="sg-label">Light Theme</div>
|
|
<div class="sg-vault-demo sg-vault-demo-light">
|
|
<div class="sg-vault-card sg-vault-card-light">
|
|
<div class="sg-vault-icon">🔓</div>
|
|
<div class="sg-vault-title" style="color: #1a1a2e;">uncloseai.</div>
|
|
<div class="sg-vault-explanation sg-vault-explanation-light">Your encrypted chat history, API keys, and settings are waiting. Enter your password to unlock this site's vault.</div>
|
|
<input type="text" class="sg-vault-input sg-vault-input-light" placeholder="Choose a password..." disabled>
|
|
<button class="sg-vault-submit" disabled>Unlock</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<h3 id="vault-error">Error State</h3>
|
|
<div class="sg-vault-demo sg-vault-demo-dark" style="min-height: 320px;">
|
|
<div class="sg-vault-card sg-vault-card-dark">
|
|
<div class="sg-vault-icon">🔓</div>
|
|
<div class="sg-vault-title" style="color: rgba(255,255,255,0.95);">uncloseai.</div>
|
|
<div class="sg-vault-explanation sg-vault-explanation-dark">Your encrypted chat history, API keys, and settings are waiting. Enter your password to unlock this site's vault.</div>
|
|
<input type="text" class="sg-vault-input sg-vault-input-dark" placeholder="Choose a password..." disabled>
|
|
<button class="sg-vault-submit" disabled>Unlock</button>
|
|
<div class="sg-vault-error">That password didn't work. Please try again.</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- ============================================ -->
|
|
<!-- MODAL HEADER -->
|
|
<!-- ============================================ -->
|
|
<h2 id="modal-header">Modal Headers</h2>
|
|
<p>All three modals share the same header structure: gradient background, title, and action buttons. The purple gradient anchors the chat and TTS modals, while translate uses green.</p>
|
|
|
|
<h3 id="header-chat">Chat Modal</h3>
|
|
<p>Purple gradient with brand title, page context subtitle, settings gear, and close button.</p>
|
|
<div class="sg-header-demo sg-header-demo-purple">
|
|
<div>
|
|
<div class="sg-header-title sg-header-title-brand">uncloseai.</div>
|
|
<div class="sg-header-subtitle">discussing: uncloseai.js Styleguide</div>
|
|
</div>
|
|
<div class="sg-header-btn-row">
|
|
<button class="sg-header-btn">⚙️</button>
|
|
<button class="sg-header-btn">✕</button>
|
|
</div>
|
|
</div>
|
|
|
|
<h3 id="header-tts">TTS Modal</h3>
|
|
<p>Purple gradient with "Text to Speech" title and close button.</p>
|
|
<div class="sg-header-demo sg-header-demo-purple">
|
|
<div>
|
|
<div class="sg-header-title">Text to Speech</div>
|
|
</div>
|
|
<button class="sg-header-btn">✕</button>
|
|
</div>
|
|
|
|
<h3 id="header-translate">Translate Modal</h3>
|
|
<p>Green gradient (<code>#4CAF50 → #45a049</code>) with "Translate" title and close button.</p>
|
|
<div class="sg-header-demo sg-header-demo-green">
|
|
<div>
|
|
<div class="sg-header-title">Translate</div>
|
|
</div>
|
|
<button class="sg-header-btn">✕</button>
|
|
</div>
|
|
|
|
<!-- ============================================ -->
|
|
<!-- CHAT MESSAGES -->
|
|
<!-- ============================================ -->
|
|
<h2 id="chat">Chat Messages</h2>
|
|
<p>User messages are right-aligned with a blue background. Responses are left-aligned and themed for dark/light. Both use asymmetric border-radius for a conversational feel.</p>
|
|
|
|
<div class="sg-side-by-side">
|
|
<div>
|
|
<div class="sg-label">Dark Theme</div>
|
|
<div class="sg-chat-demo sg-chat-demo-dark">
|
|
<div class="sg-msg-user sg-msg-user-dark">What can you help me with on this page?</div>
|
|
<div class="sg-msg-ai sg-msg-ai-dark">
|
|
I can see this is the uncloseai.js styleguide. I can help you understand the component system, color palette, vault encryption, or any of the UI patterns documented here. What interests you?
|
|
</div>
|
|
<div class="sg-msg-user sg-msg-user-dark">Tell me about the vault encryption</div>
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<div class="sg-label">Light Theme</div>
|
|
<div class="sg-chat-demo sg-chat-demo-light">
|
|
<div class="sg-msg-user">What can you help me with on this page?</div>
|
|
<div class="sg-msg-ai sg-msg-ai-light">
|
|
I can see this is the uncloseai.js styleguide. I can help you understand the component system, color palette, vault encryption, or any of the UI patterns documented here. What interests you?
|
|
</div>
|
|
<div class="sg-msg-user">Tell me about the vault encryption</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<h3 id="message-actions">Message Actions</h3>
|
|
<p>Each message has action buttons that appear on hover: copy as Markdown, copy as HTML, text-to-speech download, and delete.</p>
|
|
<div class="sg-msg-actions">
|
|
<button class="sg-msg-action-btn">📋 Copy raw (Markdown)</button>
|
|
<button class="sg-msg-action-btn">📄 Copy HTML</button>
|
|
<button class="sg-msg-action-btn">🔊 Download .mp3</button>
|
|
<button class="sg-msg-action-btn">🗑 Delete message</button>
|
|
</div>
|
|
|
|
<!-- ============================================ -->
|
|
<!-- CONTROLS -->
|
|
<!-- ============================================ -->
|
|
<h2 id="controls">Controls</h2>
|
|
<p>The control strip sits between the chat area and input field. Horizontally scrollable on mobile. Each button triggers a modal feature.</p>
|
|
|
|
<div class="sg-controls-demo">
|
|
<button class="sg-btn-control">📖 Read Page</button>
|
|
<button class="sg-btn-control">🔊 TTS Anything</button>
|
|
<button class="sg-btn-control">🌐 Translate</button>
|
|
<button class="sg-btn-control">🤖 Smart Translate</button>
|
|
<button class="sg-btn-control">📁 Upload File</button>
|
|
</div>
|
|
|
|
<!-- ============================================ -->
|
|
<!-- BUTTONS -->
|
|
<!-- ============================================ -->
|
|
<h2 id="buttons">Buttons</h2>
|
|
|
|
<h3 id="btn-gradient">Gradient Buttons</h3>
|
|
<p>Used for primary actions: vault submit, send message, and modal CTA buttons.</p>
|
|
<div class="sg-btn-grid">
|
|
<button class="sg-gradient-btn">Create Vault</button>
|
|
<button class="sg-gradient-btn">Unlock</button>
|
|
<button class="sg-gradient-btn">🌐 Translate</button>
|
|
<button class="sg-send-btn">➤</button>
|
|
</div>
|
|
|
|
<h3 id="btn-control">Control Buttons</h3>
|
|
<p>Used for secondary actions in the control strip and settings panel.</p>
|
|
<div class="sg-btn-grid">
|
|
<button class="sg-btn-control">🔄 Refresh Models</button>
|
|
<button class="sg-btn-control">🗑 Clear Chat</button>
|
|
<button class="sg-btn-control">📋 Full Chat Raw</button>
|
|
<button class="sg-btn-control">📄 Full Chat HTML</button>
|
|
<button class="sg-btn-control">📝 Full Page Raw</button>
|
|
<button class="sg-btn-control">💾 Download Chat</button>
|
|
</div>
|
|
|
|
<h3 id="btn-floating">Floating Button</h3>
|
|
<p>The entry point. Fixed position, bottom-right. Uses ChunkFive font. Colors adapt to the host page's theme.</p>
|
|
<div class="sg-floating-demo">
|
|
<div class="sg-floating-btn">uncloseai.</div>
|
|
</div>
|
|
|
|
<!-- ============================================ -->
|
|
<!-- INPUTS -->
|
|
<!-- ============================================ -->
|
|
<h2 id="inputs">Inputs</h2>
|
|
|
|
<h3 id="input-chat">Chat Input (Rounded)</h3>
|
|
<p>The main message input. Rounded <code>border-radius: 24px</code>, auto-grows up to 120px height, focus ring uses the brand blue <code>#667eea</code>.</p>
|
|
<div class="sg-input-demo">
|
|
<input type="text" class="sg-input" placeholder="Type your message...">
|
|
<input type="text" class="sg-input" placeholder="Ask about this page...">
|
|
</div>
|
|
|
|
<h3 id="input-vault">Vault Input (Rectangular)</h3>
|
|
<p>Used in the vault gate and settings forms. <code>border-radius: 10px</code> with a subtle focus ring.</p>
|
|
<div class="sg-input-demo">
|
|
<input type="text" class="sg-input-rect" placeholder="Choose a password...">
|
|
<input type="text" class="sg-input-rect" placeholder="https://api.example.com/v1">
|
|
</div>
|
|
|
|
<!-- ============================================ -->
|
|
<!-- LIVE DEMO -->
|
|
<!-- ============================================ -->
|
|
<h2 id="live-demo">Live Demo</h2>
|
|
<p>The <strong>uncloseai.</strong> floating button in the bottom-right corner of this page is the real embed. Click it to interact with the full modal, including vault creation, chat, TTS, translation, and settings. Everything documented above is rendered live inside that modal.</p>
|
|
|
|
<h3 id="embed-code">Embed Code</h3>
|
|
<pre><code class="language-html"><!-- Add to any HTML page -->
|
|
<script src="https://uncloseai.com/uncloseai.js" type="module"></script></code></pre>
|
|
<p>That single line loads the entire modal system: vault encryption, chat with Reverse RAG (live page content injected into every conversation), TTS, translation, file upload, and settings. Zero configuration required. See the <a href="/uncloseai-js.html">full documentation</a> for customization options.</p>
|
|
|
|
<footer>
|
|
<small>© uncloseai. 2026</small>
|
|
<br>
|
|
<small>Stylesheets by <a href="https://picocss.com" target="_blank">PicoCSS</a></small>
|
|
<small>& <a href="https://highlightjs.org/" target="_blank">highlight.js</a></small>
|
|
<br>
|
|
<small><a href="/privacy-policy.html">Privacy Policy</a> | <a href="/terms-of-use.html">Terms of Use</a></small>
|
|
</footer>
|
|
|
|
<script>hljs.highlightAll();</script>
|
|
<script>
|
|
// Simple active link highlighting
|
|
document.querySelectorAll('.table-of-contents a').forEach(link => {
|
|
link.addEventListener('click', function() {
|
|
document.querySelectorAll('.table-of-contents a').forEach(a => a.classList.remove('active'));
|
|
this.classList.add('active');
|
|
});
|
|
});
|
|
</script>
|
|
</main>
|
|
|
|
<!-- Right sidebar - Page TOC -->
|
|
<aside class="sidebar-right">
|
|
<div class="table-of-contents">
|
|
<nav>
|
|
<ul>
|
|
<li><a href="#intro" class="active">Overview</a></li>
|
|
<li><a href="#colors">Color Palette</a>
|
|
<ul>
|
|
<li><a href="#brand-colors">Brand Gradient</a></li>
|
|
<li><a href="#ui-colors">Interface Colors</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#typography">Typography</a>
|
|
<ul>
|
|
<li><a href="#type-brand">Brand Font</a></li>
|
|
<li><a href="#type-body">Body Text</a></li>
|
|
<li><a href="#type-code">Code</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#vault-gate">Vault Gate</a>
|
|
<ul>
|
|
<li><a href="#vault-new-user">New User</a></li>
|
|
<li><a href="#vault-returning">Returning User</a></li>
|
|
<li><a href="#vault-error">Error State</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#modal-header">Modal Headers</a>
|
|
<ul>
|
|
<li><a href="#header-chat">Chat</a></li>
|
|
<li><a href="#header-tts">TTS</a></li>
|
|
<li><a href="#header-translate">Translate</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#chat">Chat Messages</a>
|
|
<ul>
|
|
<li><a href="#message-actions">Message Actions</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#controls">Controls</a></li>
|
|
<li><a href="#buttons">Buttons</a>
|
|
<ul>
|
|
<li><a href="#btn-gradient">Gradient</a></li>
|
|
<li><a href="#btn-control">Control</a></li>
|
|
<li><a href="#btn-floating">Floating</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#inputs">Inputs</a>
|
|
<ul>
|
|
<li><a href="#input-chat">Chat Input</a></li>
|
|
<li><a href="#input-vault">Vault Input</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#live-demo">Live Demo</a></li>
|
|
</ul>
|
|
</nav>
|
|
</div>
|
|
</aside>
|
|
</body>
|
|
|
|
</html>
|