<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Promptheus Web UI Guide - Transform Your Prompts with AI</title>
<meta name="description" content="Complete guide to using the Promptheus Web UI. Learn how to optimize prompts, configure AI providers, and get better results from language models.">
<!-- Favicon Implementation -->
<link rel="apple-touch-icon" sizes="180x180" href="apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="favicon-16x16.png">
<link rel="manifest" href="site.webmanifest">
<meta name="theme-color" content="#1a1a1a">
<style>
/* Import distinctive fonts */
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Serif:wght@400;600;700&family=Fira+Code:wght@400;600&display=swap');
/* CSS Reset & Base Styles */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
/* Alchemical Dark Theme - matches main app */
--bg-primary: #0a0e1a;
--bg-secondary: #111827;
--bg-tertiary: #1a2332;
--surface-elevated: #151f2e;
/* Alchemical Gradients - Gold, Copper, Teal */
--accent-gold: #d4a574;
--accent-gold-light: #e5b885;
--accent-gold-dark: #b8935f;
--accent-emerald: #2dd4bf;
--accent-cyan: #06b6d4;
--accent-rose: #f43f5e;
/* Text Colors - Luminous */
--text-primary: #f1f5f9;
--text-secondary: #cbd5e1;
--text-muted: #94a3b8;
/* Gradients and Effects */
--gradient-primary: linear-gradient(135deg, #d4a574 0%, #8b6914 100%);
--gradient-gold: linear-gradient(135deg, #d4a574 0%, #e5b885 100%);
--shadow-gold: 0 0 30px rgba(212, 165, 116, 0.4), 0 0 60px rgba(212, 165, 116, 0.2);
/* Layout */
--sidebar-width: 280px;
}
body {
font-family: 'IBM Plex Serif', Georgia, serif;
line-height: 1.7;
color: var(--text-primary);
background: var(--bg-primary);
overflow-x: hidden;
}
/* Layout */
.docs-container {
display: flex;
min-height: 100vh;
}
/* Sidebar */
.sidebar {
position: fixed;
left: 0;
top: 0;
width: var(--sidebar-width);
height: 100vh;
background: var(--bg-secondary);
border-right: 1px solid rgba(212, 165, 116, 0.2);
overflow-y: auto;
z-index: 100;
padding: 2rem 0;
}
.sidebar-header {
padding: 0 1.5rem 1.5rem;
border-bottom: 1px solid rgba(212, 165, 116, 0.2);
margin-bottom: 1.5rem;
}
.sidebar-header h1 {
font-size: 1.5rem;
background: var(--gradient-gold);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
margin-bottom: 0.5rem;
}
.sidebar-header p {
color: var(--text-secondary);
font-size: 0.875rem;
}
.sidebar-nav {
padding: 0 1rem;
}
.nav-section {
margin-bottom: 1.5rem;
}
.nav-section-title {
color: var(--accent-gold);
font-size: 0.75rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.05em;
padding: 0.5rem 0.5rem;
margin-bottom: 0.5rem;
}
.nav-links {
list-style: none;
}
.nav-links li {
margin-bottom: 0.25rem;
}
.nav-links a {
display: block;
padding: 0.5rem 0.75rem;
color: var(--text-secondary);
text-decoration: none;
border-radius: 6px;
transition: all 0.2s ease;
font-size: 0.9rem;
}
.nav-links a:hover {
color: var(--text-primary);
background: var(--bg-tertiary);
}
.nav-links a.active {
color: var(--accent-gold);
background: var(--bg-tertiary);
font-weight: 600;
}
/* Main Content */
.main-content {
margin-left: var(--sidebar-width);
flex: 1;
padding: 3rem;
max-width: 1200px;
}
/* Typography */
h1, h2, h3, h4, h5, h6 {
font-family: 'IBM Plex Serif', Georgia, serif;
font-weight: 700;
line-height: 1.2;
margin-bottom: 1rem;
margin-top: 2rem;
}
h1 {
font-size: clamp(2rem, 4vw, 2.5rem);
background: var(--gradient-gold);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
letter-spacing: -0.5px;
margin-top: 0;
}
h2 {
font-size: clamp(1.5rem, 3vw, 2rem);
color: var(--accent-gold);
padding-bottom: 0.75rem;
padding-left: 1rem;
border-left: 4px solid var(--accent-gold);
position: relative;
}
h2::before {
content: '⚗️';
margin-right: 0.5rem;
opacity: 0.7;
}
h3 {
font-size: clamp(1.25rem, 2.5vw, 1.5rem);
color: var(--accent-gold-light);
padding-left: 0.75rem;
border-left: 3px solid var(--accent-emerald);
transition: border-color 0.3s ease;
}
h3:hover {
border-left-color: var(--accent-cyan);
}
h4 {
font-size: 1.125rem;
color: var(--text-primary);
font-weight: 600;
}
p {
margin-bottom: 1rem;
color: var(--text-secondary);
line-height: 1.7;
}
/* Lists */
ul, ol {
margin-bottom: 1.5rem;
padding-left: 2rem;
color: var(--text-secondary);
}
li {
margin-bottom: 0.5rem;
line-height: 1.6;
}
li strong {
color: var(--accent-gold);
}
/* Screenshots - Enhanced styling with different sizes and effects */
.screenshot {
margin: 2rem 0;
text-align: center;
padding: 0;
border-radius: 12px;
overflow: hidden;
}
.screenshot img {
display: block;
border-radius: 12px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
transition: all 0.3s ease;
cursor: default;
border: 2px solid rgba(212, 165, 116, 0.2);
}
/* Hover effects */
.screenshot:hover img {
transform: translateY(-3px);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
border-color: var(--accent-gold);
}
/* Screenshot caption - dark theme matching */
.screenshot-caption {
margin-top: 10px;
padding: 12px 16px;
background: rgba(26, 35, 50, 0.95);
border-left: 3px solid var(--accent-gold);
border-radius: 0 0 8px 8px;
font-size: 0.85em;
line-height: 1.5;
color: var(--text-secondary);
box-shadow: 0 1px 6px rgba(0, 0, 0, 0.3);
backdrop-filter: blur(5px);
transition: all 0.2s ease;
font-style: normal;
}
/* Add click event to images */
.screenshot img {
pointer-events: auto;
}
.screenshot:hover .screenshot-caption {
background: rgba(26, 35, 50, 1);
border-left-color: var(--accent-gold-light);
}
/* UI screenshot styling - larger, more prominent */
.screenshot.ui-screenshot img {
width: min(90vw, 800px);
max-width: 800px;
}
/* Process flow screenshot styling - full width for comprehensive view */
.screenshot.process-screenshot img {
width: min(95vw, 900px);
max-width: 900px;
}
/* Full-width screenshot for special cases */
.screenshot.full-width img {
width: min(98vw, 100%);
max-width: 100%;
}
/* For smaller UI components - still substantial */
.screenshot.small-ui img {
width: min(85vw, 600px);
max-width: 600px;
}
/* Lightbox styles - Enhanced with immersive animations */
.lightbox {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.92);
backdrop-filter: blur(4px);
z-index: 1000;
opacity: 0;
transition: opacity 0.4s cubic-bezier(0.4, 0, 0.2, 1);
}
.lightbox.active {
display: flex;
align-items: center;
justify-content: center;
opacity: 1;
}
.lightbox img {
max-width: 90vw;
max-height: 85vh;
object-fit: contain;
border: 3px solid var(--accent-gold);
border-radius: 12px;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.6), 0 0 40px rgba(212, 165, 116, 0.15);
transform: scale(0.9) translateY(20px);
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
animation: lightbox-entrance 0.5s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
}
@keyframes lightbox-entrance {
from {
opacity: 0;
transform: scale(0.7) translateY(40px);
}
to {
opacity: 1;
transform: scale(1) translateY(0);
}
}
.lightbox.active img {
transform: scale(1) translateY(0);
}
.lightbox img:hover {
box-shadow: 0 30px 80px rgba(0, 0, 0, 0.7), 0 0 50px rgba(212, 165, 116, 0.25);
}
.lightbox-close {
position: absolute;
top: 20px;
right: 40px;
font-size: 40px;
color: var(--text-primary);
cursor: pointer;
transition: all 0.3s ease;
background: rgba(0, 0, 0, 0.6);
backdrop-filter: blur(8px);
width: 60px;
height: 60px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
border: 2px solid var(--accent-gold);
opacity: 0;
animation: button-entrance 0.5s ease 0.1s forwards;
}
@keyframes button-entrance {
from {
opacity: 0;
transform: scale(0.8) translateY(-20px);
}
to {
opacity: 1;
transform: scale(1) translateY(0);
}
}
.lightbox-close:hover {
color: var(--accent-gold);
background: rgba(0, 0, 0, 0.8);
transform: scale(1.1);
box-shadow: 0 0 20px rgba(212, 165, 116, 0.4);
}
.lightbox-caption {
position: absolute;
bottom: 30px;
left: 50%;
transform: translateX(-50%) translateY(20px);
background: rgba(10, 14, 26, 0.97);
color: var(--text-secondary);
padding: 15px 25px;
border-radius: 8px;
border-left: 4px solid var(--accent-gold);
font-size: 0.9em;
line-height: 1.5;
max-width: 80%;
text-align: center;
backdrop-filter: blur(10px);
opacity: 0;
animation: caption-entrance 0.5s ease 0.2s forwards;
}
@keyframes caption-entrance {
from {
opacity: 0;
transform: translateX(-50%) translateY(30px);
}
to {
opacity: 1;
transform: translateX(-50%) translateY(0);
}
}
/* Lightbox cursor */
.screenshot img {
cursor: zoom-in;
}
.lightbox.active .lightbox-close {
cursor: pointer;
}
/* Responsive adjustments */
@media (max-width: 768px) {
.screenshot.ui-screenshot img,
.screenshot.process-screenshot img,
.screenshot.small-ui img {
width: 95%;
max-width: none;
min-width: auto;
}
.screenshot-caption {
font-size: 0.8em;
padding: 10px;
}
.lightbox-close {
top: 10px;
right: 20px;
font-size: 30px;
width: 45px;
height: 45px;
}
.lightbox-caption {
font-size: 0.8em;
padding: 10px 20px;
max-width: 90%;
}
}
/* Callout Boxes */
.callout {
padding: 1.5rem;
border-radius: 8px;
margin: 1.5rem 0;
border-left: 4px solid;
position: relative;
overflow: hidden;
backdrop-filter: blur(10px);
}
.callout::before {
content: '';
position: absolute;
top: 0;
right: 0;
width: 100px;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.02));
pointer-events: none;
}
.callout-info {
background: rgba(6, 182, 212, 0.1);
border-color: var(--accent-cyan);
box-shadow: 0 0 20px rgba(6, 182, 212, 0.1);
}
.callout-success {
background: rgba(74, 222, 128, 0.1);
border-color: var(--accent-emerald);
box-shadow: 0 0 20px rgba(74, 222, 128, 0.1);
}
.callout-warning {
background: rgba(212, 165, 116, 0.1);
border-color: var(--accent-gold);
box-shadow: 0 0 20px rgba(212, 165, 116, 0.1);
}
.callout-title {
font-weight: 700;
color: var(--text-primary);
margin-bottom: 0.5rem;
display: flex;
align-items: center;
gap: 0.5rem;
font-size: 1.05rem;
}
.callout p:last-child {
margin-bottom: 0;
}
/* Steps */
.steps {
counter-reset: step-counter;
list-style: none;
padding-left: 0;
}
.steps li {
counter-increment: step-counter;
position: relative;
padding-left: 3.5rem;
margin-bottom: 2rem;
}
.steps li::before {
content: counter(step-counter);
position: absolute;
left: 0;
top: 0;
width: 2.5rem;
height: 2.5rem;
background: var(--gradient-gold);
color: var(--bg-primary);
font-weight: 700;
font-size: 1.125rem;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
box-shadow: var(--shadow-gold);
}
/* Feature Grid */
.feature-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 1.5rem;
margin: 2rem 0;
}
.feature-card {
background: linear-gradient(135deg, var(--bg-secondary) 0%, var(--bg-tertiary) 100%);
padding: 1.5rem;
border-radius: 8px;
border: 1px solid rgba(212, 165, 116, 0.2);
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
position: relative;
overflow: hidden;
}
.feature-card::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 3px;
background: var(--gradient-gold);
transform: scaleX(0);
transform-origin: left;
transition: transform 0.3s ease;
}
.feature-card:hover {
transform: translateY(-4px);
box-shadow: 0 8px 24px rgba(212, 165, 116, 0.2);
border-color: var(--accent-gold);
}
.feature-card:hover::before {
transform: scaleX(1);
}
.feature-card h4 {
color: var(--accent-gold);
margin-top: 0;
margin-bottom: 0.75rem;
font-size: 1.125rem;
transition: color 0.2s ease;
}
.feature-card:hover h4 {
color: var(--accent-gold-light);
}
.feature-card p {
margin-bottom: 0;
font-size: 0.9rem;
}
/* FAQ */
.faq-item {
background: var(--bg-secondary);
padding: 1.5rem;
border-radius: 8px;
margin-bottom: 1rem;
border-left: 4px solid var(--accent-gold);
transition: all 0.2s ease;
}
.faq-item:hover {
background: var(--bg-tertiary);
border-left-color: var(--accent-gold-light);
transform: translateX(4px);
}
.faq-question {
font-weight: 700;
color: var(--text-primary);
margin-bottom: 0.75rem;
font-size: 1.125rem;
display: flex;
align-items: flex-start;
gap: 0.5rem;
}
.faq-question::before {
content: '⚗️';
font-size: 1rem;
opacity: 0.6;
flex-shrink: 0;
}
.faq-answer {
color: var(--text-secondary);
line-height: 1.6;
}
.faq-answer strong {
color: var(--accent-gold);
}
/* Code */
code {
font-family: 'Fira Code', monospace;
background: rgba(45, 212, 191, 0.15);
padding: 0.2rem 0.5rem;
border-radius: 4px;
font-size: 0.875em;
color: var(--accent-emerald);
border: 1px solid rgba(45, 212, 191, 0.2);
}
pre {
background: linear-gradient(135deg, var(--bg-tertiary) 0%, var(--bg-secondary) 100%);
padding: 1.5rem;
border-radius: 8px;
overflow-x: auto;
margin: 1.5rem 0;
border: 1px solid rgba(212, 165, 116, 0.2);
box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.2);
position: relative;
}
pre::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 4px;
height: 100%;
background: var(--gradient-gold);
border-radius: 8px 0 0 8px;
}
pre code {
background: none;
padding: 0;
color: var(--text-secondary);
border: none;
}
/* Links */
a {
color: var(--accent-cyan);
text-decoration: none;
transition: all 0.2s ease;
position: relative;
}
a:hover {
color: var(--accent-emerald);
}
.main-content a:not(.nav-links a) {
border-bottom: 1px solid rgba(6, 182, 212, 0.3);
}
.main-content a:not(.nav-links a):hover {
border-bottom-color: var(--accent-emerald);
text-shadow: 0 0 8px rgba(45, 212, 191, 0.3);
}
/* Mobile Menu Toggle */
.mobile-menu-toggle {
display: none;
position: fixed;
top: 1rem;
left: 1rem;
z-index: 1001;
background: var(--bg-secondary);
border: 1px solid var(--accent-gold);
border-radius: 8px;
padding: 0.75rem;
cursor: pointer;
transition: all 0.3s ease;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
}
/* Mobile Backdrop */
.mobile-backdrop {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.7);
z-index: 99;
opacity: 0;
transition: opacity 0.3s ease;
}
.mobile-backdrop.active {
opacity: 1;
}
.mobile-menu-toggle:hover {
background: var(--bg-tertiary);
box-shadow: 0 0 15px rgba(212, 165, 116, 0.3);
}
.mobile-menu-toggle span {
display: block;
width: 24px;
height: 2px;
background: var(--accent-gold);
margin: 5px 0;
transition: all 0.3s ease;
}
.mobile-menu-toggle.active span:nth-child(1) {
transform: rotate(45deg) translate(7px, 7px);
}
.mobile-menu-toggle.active span:nth-child(2) {
opacity: 0;
}
.mobile-menu-toggle.active span:nth-child(3) {
transform: rotate(-45deg) translate(7px, -7px);
}
/* Responsive */
@media (max-width: 768px) {
.mobile-menu-toggle {
display: block;
}
.mobile-backdrop {
display: block;
}
.sidebar {
position: fixed;
transform: translateX(-100%);
transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
width: 280px;
height: 100vh;
top: 0;
left: 0;
z-index: 1000;
}
.sidebar.active {
transform: translateX(0);
box-shadow: 4px 0 20px rgba(0, 0, 0, 0.8);
}
.main-content {
margin-left: 0;
padding: 4rem 1.5rem 2rem;
width: 100%;
}
.feature-grid {
grid-template-columns: 1fr;
}
.screenshot.ui-screenshot img,
.screenshot.process-screenshot img,
.screenshot.small-ui img {
width: 100%;
max-width: none;
}
h1 {
font-size: 1.75rem;
}
h2 {
font-size: 1.5rem;
}
h3 {
font-size: 1.25rem;
}
}
/* Scroll behavior */
html {
scroll-behavior: smooth;
}
/* Section anchors */
section {
scroll-margin-top: 2rem;
}
/* Page load animations */
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.main-content > section {
animation: fadeInUp 0.6s ease-out backwards;
}
.main-content > section:nth-child(1) { animation-delay: 0.1s; }
.main-content > section:nth-child(2) { animation-delay: 0.15s; }
.main-content > section:nth-child(3) { animation-delay: 0.2s; }
/* Sidebar fade in */
@keyframes slideInLeft {
from {
opacity: 0;
transform: translateX(-20px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
.sidebar {
animation: slideInLeft 0.5s ease-out;
}
.nav-section {
animation: fadeInUp 0.5s ease-out backwards;
}
.nav-section:nth-child(1) { animation-delay: 0.1s; }
.nav-section:nth-child(2) { animation-delay: 0.2s; }
.nav-section:nth-child(3) { animation-delay: 0.3s; }
.nav-section:nth-child(4) { animation-delay: 0.4s; }
</style>
</head>
<body>
<!-- Mobile Menu Toggle -->
<button class="mobile-menu-toggle" id="mobileMenuToggle" aria-label="Toggle navigation">
<span></span>
<span></span>
<span></span>
</button>
<!-- Mobile Backdrop -->
<div class="mobile-backdrop" id="mobileBackdrop"></div>
<div class="docs-container">
<!-- Sidebar Navigation -->
<aside class="sidebar" id="sidebar">
<div class="sidebar-header">
<h1>⚗️ Promptheus</h1>
<p>Web UI Guide</p>
</div>
<nav class="sidebar-nav">
<div class="nav-section">
<div class="nav-section-title">Getting Started</div>
<ul class="nav-links">
<li><a href="#introduction">Introduction</a></li>
<li><a href="#quick-start">Quick Start</a></li>
<li><a href="#first-prompt">Your First Prompt</a></li>
</ul>
</div>
<div class="nav-section">
<div class="nav-section-title">Configuration</div>
<ul class="nav-links">
<li><a href="#setup">Initial Setup</a></li>
<li><a href="#general-settings">General Settings</a></li>
<li><a href="#api-keys">API Keys</a></li>
<li><a href="#system-status">System Status</a></li>
<li><a href="#providers">Provider Selection</a></li>
</ul>
</div>
<div class="nav-section">
<div class="nav-section-title">Features</div>
<ul class="nav-links">
<li><a href="#optimization-modes">Optimization Modes</a></li>
<li><a href="#question-flow">Question Flow</a></li>
<li><a href="#results">Working with Results</a></li>
<li><a href="#history">History Management</a></li>
</ul>
</div>
<div class="nav-section">
<div class="nav-section-title">Help</div>
<ul class="nav-links">
<li><a href="#use-cases">Use Cases</a></li>
<li><a href="#faq">FAQ</a></li>
<li><a href="#troubleshooting">Troubleshooting</a></li>
</ul>
</div>
</nav>
</aside>
<!-- Main Content -->
<main class="main-content">
<!-- Introduction -->
<section id="introduction">
<h1>Promptheus Web UI Guide</h1>
<p>Welcome to Promptheus, your AI-powered prompt optimization tool. The web interface makes it easy to transform basic prompts into detailed, effective instructions for language models.</p>
<div class="callout callout-info">
<div class="callout-title">💡 What is Promptheus?</div>
<p>Promptheus analyzes your prompts and intelligently asks clarifying questions to help you create better, more precise instructions for AI models. It supports multiple AI providers including Google Gemini, Anthropic Claude, OpenAI GPT, Groq, Alibaba Qwen, and Zhipu GLM.</p>
</div>
<div class="callout info">
<div class="callout-title">🔌 MCP Server Available</div>
<p>Promptheus includes a built-in <strong>Model Context Protocol (MCP) server</strong> for integration with AI toolchains. Start it with <code>promptheus mcp</code> and connect with MCP-compatible clients. <a href="https://abhichandra21.github.io/Promptheus/documentation.html#mcp-server" target="_blank">Learn more in the documentation</a>.</p>
</div>
</div>
</section>
<!-- Quick Start -->
<section id="quick-start">
<h2>Quick Start</h2>
<h3>Launching the Web UI</h3>
<p>Start the Promptheus web interface by running:</p>
<pre><code>promptheus web</code></pre>
<p>This will:</p>
<ul>
<li>Start a local web server (typically on port 8000)</li>
<li>Automatically open your default browser</li>
<li>Display the Promptheus interface</li>
</ul>
<div class="callout callout-success">
<div class="callout-title">✅ System Requirements</div>
<p>Promptheus works on Windows, macOS, and Linux. You need Python 3.10 or higher and at least one AI provider API key.</p>
</div>
</section>
<!-- First Prompt -->
<section id="first-prompt">
<h2>Your First Prompt</h2>
<div class="screenshot ui-screenshot">
<img src="/assets/web-ui-result-5.png" alt="Promptheus home screen with blank prompt input">
<div class="screenshot-caption">Main interface with provider/model selectors, mode and style controls, and an empty prompt/optimized result panel</div>
</div>
<p>When you first open Promptheus, you'll see a clean interface with:</p>
<div class="feature-grid">
<div class="feature-card">
<h4>📝 Input Area</h4>
<p>Large text field where you enter your initial prompt</p>
</div>
<div class="feature-card">
<h4>⚙️ Mode Selector</h4>
<p>Choose how Promptheus processes your input (Auto, Always Ask, or Skip Questions)</p>
</div>
<div class="feature-card">
<h4>🔧 Provider Controls</h4>
<p>Select your AI provider and model from the top navigation</p>
</div>
<div class="feature-card">
<h4>📊 Output Panel</h4>
<p>View your optimized prompt with options to tweak or copy</p>
</div>
</div>
</section>
<!-- Setup -->
<section id="setup">
<h2>Initial Setup</h2>
<p>Before optimizing prompts, you need to configure at least one AI provider with an API key.</p>
<h3>Accessing Settings</h3>
<ol class="steps">
<li>
<strong>Click the Settings button</strong> in the top-right corner of the interface
</li>
<li>
<strong>Navigate to the API Keys section</strong> where you can configure your provider credentials
</li>
<li>
<strong>Enter your API key</strong> for at least one provider
</li>
<li>
<strong>Click Save</strong> to store your configuration
</li>
</ol>
</section>
<section id="general-settings">
<h2>General Settings</h2>
<div class="screenshot small-ui">
<img src="/assets/web-ui-result-4.png" alt="General settings with history toggle">
<div class="screenshot-caption">Settings panel showing the global history toggle and API key section entry point</div>
</div>
<p>Use General settings to control app-wide behaviors:</p>
<ul>
<li><strong>History toggle:</strong> Enable or disable saving prompt refinements locally</li>
<li><strong>Privacy:</strong> Turn history off when working with sensitive content</li>
<li><strong>Settings access:</strong> Jump directly to provider-specific configurations from here</li>
</ul>
</section>
<!-- API Keys -->
<section id="api-keys">
<h2>API Keys Configuration</h2>
<div class="screenshot small-ui">
<img src="/assets/web-ui-result-3.png" alt="API key entry fields for Google Gemini and OpenAI">
<div class="screenshot-caption">API key form with masked inputs and dedicated save actions for Google Gemini and OpenAI credentials</div>
</div>
<p>The settings panel allows you to configure API keys for all supported providers. You can:</p>
<ul>
<li><strong>Add multiple providers:</strong> Configure keys for Google Gemini, OpenAI, Anthropic Claude, Groq, Qwen, and GLM</li>
<li><strong>View saved keys:</strong> Previously configured keys are displayed (masked for security)</li>
<li><strong>Update keys:</strong> Easily replace or update existing API keys</li>
<li><strong>Test connection:</strong> The interface shows which provider is currently active</li>
</ul>
<h3>Getting API Keys</h3>
<p>Here's where to obtain API keys for each provider:</p>
<div class="feature-grid">
<div class="feature-card">
<h4>Google Gemini</h4>
<p><a href="https://aistudio.google.com" target="_blank">AI Studio</a> - Free tier available with generous limits</p>
</div>
<div class="feature-card">
<h4>Anthropic Claude</h4>
<p><a href="https://console.anthropic.com" target="_blank">Anthropic Console</a> - Advanced reasoning capabilities</p>
</div>
<div class="feature-card">
<h4>OpenAI</h4>
<p><a href="https://platform.openai.com/api-keys" target="_blank">OpenAI Platform</a> - GPT-4 and other models</p>
</div>
<div class="feature-card">
<h4>Groq</h4>
<p><a href="https://console.groq.com" target="_blank">Groq Console</a> - Ultra-fast inference speeds</p>
</div>
<div class="feature-card">
<h4>Alibaba Qwen</h4>
<p><a href="https://dashscope.aliyun.com" target="_blank">DashScope</a> - Chinese language expertise</p>
</div>
<div class="feature-card">
<h4>Zhipu GLM</h4>
<p><a href="https://open.bigmodel.cn" target="_blank">GLM Console</a> - Alternative Chinese models</p>
</div>
</div>
<div class="callout callout-warning">
<div class="callout-title">🔒 Security Note</div>
<p>API keys are stored locally on your machine. Promptheus never sends your keys to external servers except to the provider's own API endpoints.</p>
</div>
</section>
<section id="system-status">
<h2>System Status</h2>
<div class="screenshot small-ui">
<img src="/assets/web-ui-result-2.png" alt="Provider readiness and model counts">
<div class="screenshot-caption">Validation view listing provider readiness, available model counts, and cache refresh controls</div>
</div>
<p>The System Status tab summarizes your configured providers:</p>
<ul>
<li><strong>Readiness:</strong> Confirms whether each provider key is valid</li>
<li><strong>Model counts:</strong> Shows how many models are available for each provider</li>
<li><strong>Latency hints:</strong> Displays the last validation time in milliseconds</li>
<li><strong>Cache controls:</strong> Refresh the cached model list or validate all providers at once</li>
</ul>
</section>
<!-- Providers -->
<section id="providers">
<h2>Provider Selection</h2>
<p>Use the dropdown menus in the top navigation bar to select your AI provider and model:</p>
<ul>
<li><strong>Provider dropdown:</strong> Choose from configured providers (Anthropic, OpenAI, Google, etc.)</li>
<li><strong>Model dropdown:</strong> Select a specific model (e.g., claude-opus-4-0, gpt-4o, gemini-2.0-flash)</li>
</ul>
<div class="callout callout-info">
<div class="callout-title">💡 Choosing a Provider</div>
<p>Different providers excel at different tasks. Google Gemini offers excellent free tier limits, Anthropic Claude provides superior reasoning, and OpenAI GPT is well-balanced for most use cases.</p>
</div>
<!-- Provider Dropdown Expanded -->
<h3>Provider Dropdown Interface</h3>
<div class="screenshot small-ui">
<img src="/assets/web-ui-result-7.png" alt="Provider and model selector bar">
<div class="screenshot-caption">Top bar selectors for provider, model, connection status, and quick access to settings</div>
</div>
<p>The provider dropdown interface shows all configured providers:</p>
<div class="feature-grid">
<div class="feature-card">
<h4>🤖 Google Gemini</h4>
<p>Models: gemini-2.0-flash, gemini-1.5-pro, gemini-1.5-flash</p>
</div>
<div class="feature-card">
<h4>🧠 Anthropic Claude</h4>
<p>Models: claude-3-5-sonnet, claude-3-opus, claude-3-5-haiku</p>
</div>
<div class="feature-card">
<h4>⚡ OpenAI GPT</h4>
<p>Models: gpt-4o, gpt-4-turbo, gpt-3.5-turbo</p>
</div>
<div class="feature-card">
<h4>🚀 Groq</h4>
<p>Models: llama-3.3-70b, mixtral-8x7b, llama-3.1-8b</p>
</div>
<div class="feature-card">
<h4>🌟 Qwen</h4>
<p>Models: qwen-max, qwen-plus, qwen-turbo</p>
</div>
<div class="feature-card">
<h4>🔥 GLM</h4>
<p>Models: glm-4-plus, glm-4-air, glm-4v</p>
</div>
</div>
</section>
<!-- Optimization Modes -->
<section id="optimization-modes">
<h2>Optimization Modes</h2>
<p>Promptheus offers three optimization modes to control how your prompts are processed:</p>
<div class="feature-card" style="margin-bottom: 1rem;">
<h4>🤖 Auto Mode (Recommended)</h4>
<p>Intelligently detects your task type and decides whether to ask clarifying questions. For analysis tasks (research, explanation), it skips questions and directly optimizes. For generation tasks (writing, creation), it asks relevant questions to improve quality.</p>
</div>
<div class="feature-card" style="margin-bottom: 1rem;">
<h4>❓ Always Ask Mode</h4>
<p>Forces Promptheus to generate and ask clarifying questions regardless of task type. Useful when you want maximum refinement and are willing to answer detailed questions.</p>
</div>
<div class="feature-card" style="margin-bottom: 1rem;">
<h4>⚡ Skip Questions Mode</h4>
<p>Bypasses the question-asking phase and directly optimizes your prompt. Best for quick optimizations or when you've already provided detailed requirements.</p>
</div>
</section>
<!-- Question Flow -->
<section id="question-flow">
<h2>Question Flow</h2>
<div class="screenshot process-screenshot">
<img src="/assets/web-ui-result-1.png" alt="Questionnaire overlay during prompt optimization">
<div class="screenshot-caption">Interactive questionnaire guiding prompt refinement with progress tracking and required fields</div>
</div>
<p>When Promptheus determines that questions would improve your prompt, it presents an interactive questionnaire:</p>
<h3>Question Types</h3>
<ul>
<li><strong>Multiple Choice:</strong> Select from predefined options (e.g., target age range, tone, format)</li>
<li><strong>Text Input:</strong> Provide free-form answers for open-ended questions</li>
<li><strong>Checkbox Lists:</strong> Select multiple applicable options</li>
</ul>
<h3>Answering Questions</h3>
<ol class="steps">
<li>
<strong>Review the question</strong> displayed at the top of the panel (e.g., "Question 1 of 5")
</li>
<li>
<strong>Select your answer</strong> by clicking the appropriate option or typing your response
</li>
<li>
<strong>Navigate questions</strong> - some questions may influence which follow-up questions appear
</li>
<li>
<strong>Submit answers</strong> - once complete, Promptheus processes your responses
</li>
</ol>
<div class="callout callout-info">
<div class="callout-title">💡 Question Quality</div>
<p>Promptheus uses AI to generate contextual questions specific to your prompt. Questions for a "write a story" prompt will be completely different from a "explain a concept" prompt.</p>
</div>
<p>The interface shows:</p>
<ul>
<li>Progress indicator (Question X of Y)</li>
<li>Current question text with required field markers (*)</li>
<li>Cancel button to abort the process</li>
<li>Processing status while the AI generates your optimized prompt</li>
</ul>
</section>
<!-- Results -->
<section id="results">
<h2>Working with Results</h2>
<p>After processing, Promptheus displays your optimized prompt in the output panel. The result includes:</p>
<h3>Output Features</h3>
<ul>
<li><strong>Enhanced Prompt:</strong> Your original prompt transformed into a detailed, effective instruction</li>
<li><strong>Structured Requirements:</strong> Clear sections outlining requirements, constraints, and expectations</li>
<li><strong>Context Integration:</strong> Answers from clarifying questions seamlessly incorporated</li>
</ul>
<h3>Available Actions</h3>
<div class="feature-grid">
<div class="feature-card">
<h4>📋 Copy Button</h4>
<p>Instantly copy the optimized prompt to your clipboard for use in other applications or AI tools</p>
</div>
<div class="feature-card">
<h4>✏️ Tweak Button</h4>
<p>Refine the result further by asking additional questions or providing more context</p>
</div>
<div class="feature-card">
<h4>🔄 Start Over</h4>
<p>Clear everything and begin with a fresh prompt</p>
</div>
<div class="feature-card">
<h4>🚀 Optimize Prompt</h4>
<p>Run the optimization again with different settings or modes</p>
</div>
</div>
<div class="callout callout-success">
<div class="callout-title">✅ What Makes a Good Optimized Prompt?</div>
<p>A well-optimized prompt is specific, includes relevant context, sets clear expectations, defines the desired format, and specifies any constraints or requirements.</p>
</div>
</section>
<!-- History -->
<section id="history">
<h2>History Management</h2>
<p>Promptheus automatically saves all your prompt optimizations, making it easy to revisit and reuse previous work.</p>
<div class="screenshot process-screenshot">
<img src="/assets/web-ui-result-6.png" alt="History page with pagination controls">
<div class="screenshot-caption">History view showing saved prompts, provider/model details, and clear history plus pagination controls</div>
</div>
<h3>Accessing History</h3>
<p>History functionality allows you to:</p>
<ul>
<li>View all previously optimized prompts</li>
<li>See both original and refined versions</li>
<li>Review which provider and model was used</li>
<li>Track when each optimization was created</li>
<li>Load past prompts for further refinement</li>
</ul>
<h3>History Features</h3>
<ul>
<li><strong>Pagination:</strong> Navigate through history with customizable items per page (10, 20, or 50)</li>
<li><strong>Timestamp:</strong> Each entry shows when it was created</li>
<li><strong>Task Type:</strong> Identifies whether it was an analysis or generation task</li>
<li><strong>Provider Info:</strong> Records which AI provider and model generated the optimization</li>
</ul>
<div class="callout callout-info">
<div class="callout-title">💾 Local Storage</div>
<p>History is stored locally on your machine in platform-specific directories (~/.promptheus on Unix-like systems, %APPDATA%/promptheus on Windows).</p>
</div>
<h3>History Interface</h3>
<p>The history interface provides easy access to your previous work:</p>
<div class="feature-grid">
<div class="feature-card">
<h4>🔍 Quick Access</h4>
<p>Located in the navigation for instant access to your prompt library</p>
</div>
<div class="feature-card">
<h4>📋 Detailed View</h4>
<p>See original prompts alongside their optimized versions</p>
</div>
<div class="feature-card">
<h4>🗂️ Smart Organization</h4>
<p>Chronological ordering with filtering options</p>
</div>
<div class="feature-card">
<h4>🔄 One-Click Load</h4>
<p>Quickly load any previous prompt for re-optimization</p>
</div>
</div>
</section>
<!-- Use Cases -->
<section id="use-cases">
<h2>Use Cases & Examples</h2>
<p>Promptheus excels at various prompt optimization scenarios:</p>
<h3>Content Creation</h3>
<div class="faq-item">
<div class="faq-question">Scenario: Writing a Blog Post</div>
<div class="faq-answer">
<p><strong>Basic prompt:</strong> "Write a blog post about cloud computing"</p>
<p><strong>Promptheus asks:</strong> Target audience? Technical level? Preferred length? Key topics? Tone?</p>
<p><strong>Result:</strong> "Write a 1500-word blog post for IT professionals (intermediate level) explaining cloud computing fundamentals. Cover IaaS, PaaS, and SaaS with practical examples. Use a professional but accessible tone. Include an introduction hook, 3-4 main sections, and a conclusion with actionable takeaways."</p>
</div>
</div>
<h3>Technical Documentation</h3>
<div class="faq-item">
<div class="faq-question">Scenario: API Documentation</div>
<div class="faq-answer">
<p><strong>Basic prompt:</strong> "Document this API"</p>
<p><strong>Promptheus asks:</strong> Target readers? Required sections? Code examples? Authentication details?</p>
<p><strong>Result:</strong> "Create comprehensive API documentation for backend developers. Include: endpoint descriptions, request/response schemas with examples, authentication flow, error codes with explanations, rate limiting details, and working code samples in Python and JavaScript."</p>
</div>
</div>
<h3>Data Analysis</h3>
<div class="faq-item">
<div class="faq-question">Scenario: Code Review</div>
<div class="faq-answer">
<p><strong>Basic prompt:</strong> "Review this code for security issues"</p>
<p><strong>Mode:</strong> Skip Questions (analysis task)</p>
<p><strong>Result:</strong> "Conduct a comprehensive security review of the provided code focusing on: SQL injection vulnerabilities, XSS risks, authentication/authorization flaws, sensitive data exposure, input validation issues. For each finding, provide severity rating, location, explanation, and remediation guidance."</p>
</div>
</div>
<h3>Creative Writing</h3>
<div class="faq-item">
<div class="faq-question">Scenario: Short Story (from screenshots)</div>
<div class="faq-answer">
<p><strong>Basic prompt:</strong> "Write a short, futuristic story for a young adult audience about a teenager who discovers an AI that can dream. The story should have a hopeful tone and be around 500 words."</p>
<p><strong>Promptheus asks:</strong> Age range? Narrative perspective? Character traits? Story elements?</p>
<p><strong>Result:</strong> Detailed specifications including first-person narrative, 13-15 year old target readers, AI personality traits, philosophical themes, romance subplot, and specific story requirements.</p>
</div>
</div>
</section>
<!-- FAQ -->
<section id="faq">
<h2>Frequently Asked Questions</h2>
<div class="faq-item">
<div class="faq-question">How do I switch between providers?</div>
<div class="faq-answer">
<p>Use the Provider dropdown in the top navigation bar. You can switch at any time, even between optimizations. Make sure you have configured an API key for the provider you want to use.</p>
</div>
</div>
<div class="faq-item">
<div class="faq-question">What happens if I don't answer all the questions?</div>
<div class="faq-answer">
<p>Required questions (marked with *) must be answered. Optional questions can be skipped. The optimization quality improves with more complete answers, but Promptheus will work with whatever information you provide.</p>
</div>
</div>
<div class="faq-item">
<div class="faq-question">Can I use the optimized prompt with a different AI model?</div>
<div class="faq-answer">
<p>Absolutely! Optimized prompts work with any language model. Copy the result and use it with ChatGPT, Claude, Gemini, or any other AI assistant. The optimization focuses on clarity and structure, which benefits all models.</p>
</div>
</div>
<div class="faq-item">
<div class="faq-question">How is my data stored?</div>
<div class="faq-answer">
<p>All data (API keys, prompt history) is stored locally on your machine. Promptheus only communicates with AI provider APIs to process your prompts. No data is sent to Promptheus servers (there are none!).</p>
</div>
</div>
<div class="faq-item">
<div class="faq-question">Which mode should I use?</div>
<div class="faq-answer">
<p><strong>Auto Mode</strong> is recommended for most users. It intelligently decides when questions are helpful. Use <strong>Always Ask</strong> when you want maximum refinement, and <strong>Skip Questions</strong> when you need quick optimizations or your prompt is already detailed.</p>
</div>
</div>
<div class="faq-item">
<div class="faq-question">Can I edit the optimized prompt?</div>
<div class="faq-answer">
<p>Yes! After copying the optimized prompt, you can edit it in any text editor or AI interface. You can also use the "Tweak" button to refine it further within Promptheus.</p>
</div>
</div>
<div class="faq-item">
<div class="faq-question">What's the difference between providers?</div>
<div class="faq-answer">
<p>Each provider has unique strengths: <strong>Google Gemini</strong> offers excellent free tier; <strong>Claude</strong> excels at reasoning and following instructions; <strong>OpenAI GPT</strong> is well-balanced; <strong>Groq</strong> provides fastest responses; <strong>Qwen/GLM</strong> are optimized for Chinese language.</p>
</div>
</div>
<div class="faq-item">
<div class="faq-question">How do I clear my history?</div>
<div class="faq-answer">
<p>History can be cleared using the CLI command <code>promptheus history --clear</code> or by accessing the history management features in the web interface (if implemented).</p>
</div>
</div>
</section>
<!-- Troubleshooting -->
<section id="troubleshooting">
<h2>Troubleshooting</h2>
<h3>Common Issues</h3>
<div class="faq-item">
<div class="faq-question">Web UI won't start</div>
<div class="faq-answer">
<p><strong>Solution:</strong></p>
<ul>
<li>Check if port 8000 is already in use: <code>lsof -i :8000</code> (Unix) or <code>netstat -ano | findstr :8000</code> (Windows)</li>
<li>Try specifying a different port: <code>promptheus web --port 8080</code></li>
<li>Ensure Promptheus is properly installed: <code>pip install --upgrade promptheus</code></li>
</ul>
</div>
</div>
<div class="faq-item">
<div class="faq-question">API key not working</div>
<div class="faq-answer">
<p><strong>Solution:</strong></p>
<ul>
<li>Verify the key is copied correctly without extra spaces</li>
<li>Check if the key is active in your provider's console</li>
<li>Ensure you have sufficient credits/quota with the provider</li>
<li>Try testing with a different provider to isolate the issue</li>
</ul>
</div>
</div>
<div class="faq-item">
<div class="faq-question">Optimization fails or times out</div>
<div class="faq-answer">
<p><strong>Solution:</strong></p>
<ul>
<li>Check your internet connection</li>
<li>Verify provider API status (check provider's status page)</li>
<li>Try a different provider or model</li>
<li>Reduce prompt complexity if it's very long</li>
<li>Check rate limits on your API key</li>
</ul>
</div>
</div>
<div class="faq-item">
<div class="faq-question">Questions not appearing</div>
<div class="faq-answer">
<p><strong>Possible reasons:</strong></p>
<ul>
<li>Mode is set to "Skip Questions" - change to "Auto" or "Always Ask"</li>
<li>Your prompt type was detected as analysis (Auto mode) - try "Always Ask" mode</li>
<li>The AI determined no questions were needed - this is normal for some prompts</li>
</ul>
</div>
</div>
<div class="faq-item">
<div class="faq-question">Browser doesn't open automatically</div>
<div class="faq-answer">
<p><strong>Solution:</strong></p>
<ul>
<li>Manually navigate to the URL shown in terminal (usually http://127.0.0.1:8000)</li>
<li>Use <code>promptheus web --no-browser</code> flag to suppress automatic opening</li>
<li>Check if your default browser is set correctly</li>
</ul>
</div>
</div>
<h3>Getting Help</h3>
<div class="callout callout-info">
<div class="callout-title">📞 Support Resources</div>
<ul style="margin-bottom: 0;">
<li><strong>GitHub Issues:</strong> <a href="https://github.com/abhichandra21/Promptheus/issues" target="_blank">Report bugs or request features</a></li>
<li><strong>Documentation:</strong> <a href="https://abhichandra21.github.io/Promptheus/documentation.html" target="_blank">Full CLI and technical docs</a></li>
<li><strong>CLI Help:</strong> Run <code>promptheus --help</code> for command reference</li>
</ul>
</div>
</section>
<!-- Footer -->
<section style="margin-top: 4rem; padding-top: 2rem; border-top: 1px solid rgba(212, 165, 116, 0.2);">
<p style="text-align: center; color: var(--text-muted);">
Made with ⚗️ by the Promptheus team |
<a href="https://github.com/abhichandra21/Promptheus" target="_blank">GitHub</a> |
<a href="https://abhichandra21.github.io/Promptheus/documentation.html" target="_blank">Full Documentation</a>
</p>
</section>
</main>
</div>
<!-- Lightbox HTML -->
<div id="lightbox" class="lightbox">
<div class="lightbox-close" onclick="closeLightbox()">×</div>
<img id="lightbox-image" src="" alt="">
<div id="lightbox-caption" class="lightbox-caption"></div>
</div>
<script>
// Smooth scrolling for navigation links
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function (e) {
e.preventDefault();
const target = document.querySelector(this.getAttribute('href'));
if (target) {
target.scrollIntoView({
behavior: 'smooth',
block: 'start'
});
// Update active state
document.querySelectorAll('.nav-links a').forEach(link => {
link.classList.remove('active');
});
this.classList.add('active');
}
});
});
// Highlight active section on scroll
const sections = document.querySelectorAll('section[id]');
const navLinks = document.querySelectorAll('.nav-links a');
function highlightNavigation() {
let scrollY = window.pageYOffset;
sections.forEach(section => {
const sectionHeight = section.offsetHeight;
const sectionTop = section.offsetTop - 100;
const sectionId = section.getAttribute('id');
if (scrollY > sectionTop && scrollY <= sectionTop + sectionHeight) {
navLinks.forEach(link => {
link.classList.remove('active');
if (link.getAttribute('href') === `#${sectionId}`) {
link.classList.add('active');
}
});
}
});
}
window.addEventListener('scroll', highlightNavigation);
// Mobile menu toggle
const mobileMenuToggle = document.getElementById('mobileMenuToggle');
const sidebar = document.getElementById('sidebar');
const mobileBackdrop = document.getElementById('mobileBackdrop');
function toggleMobileMenu() {
mobileMenuToggle.classList.toggle('active');
sidebar.classList.toggle('active');
mobileBackdrop.classList.toggle('active');
// Prevent body scroll when menu is open
if (sidebar.classList.contains('active')) {
document.body.style.overflow = 'hidden';
} else {
document.body.style.overflow = '';
}
}
function closeMobileMenu() {
mobileMenuToggle.classList.remove('active');
sidebar.classList.remove('active');
mobileBackdrop.classList.remove('active');
document.body.style.overflow = '';
}
mobileMenuToggle.addEventListener('click', toggleMobileMenu);
mobileBackdrop.addEventListener('click', closeMobileMenu);
// Close sidebar when clicking on a nav link (mobile)
document.querySelectorAll('.nav-links a').forEach(link => {
link.addEventListener('click', function() {
if (window.innerWidth <= 768) {
closeMobileMenu();
}
});
});
// Lightbox functionality
function openLightbox(img) {
const lightbox = document.getElementById('lightbox');
const lightboxImage = document.getElementById('lightbox-image');
const lightboxCaption = document.getElementById('lightbox-caption');
// Set the image and caption
lightboxImage.src = img.src;
lightboxImage.alt = img.alt;
lightboxCaption.textContent = img.parentElement.querySelector('.screenshot-caption').textContent;
// Show lightbox
lightbox.classList.add('active');
document.body.style.overflow = 'hidden';
}
function closeLightbox() {
const lightbox = document.getElementById('lightbox');
lightbox.classList.remove('active');
document.body.style.overflow = '';
}
// Add click events to all images
document.addEventListener('DOMContentLoaded', function() {
const images = document.querySelectorAll('.screenshot img');
images.forEach(img => {
img.addEventListener('click', function() {
openLightbox(this);
});
});
// Close lightbox on background click
document.getElementById('lightbox').addEventListener('click', function(e) {
if (e.target === this) {
closeLightbox();
}
});
// Close lightbox on ESC key
document.addEventListener('keydown', function(e) {
if (e.key === 'Escape') {
closeLightbox();
}
});
});
</script>
</body>
</html>