speechify-clone/static/index.html

181 lines
8.1 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Speechify</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=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="/static/style.css" />
</head>
<body>
<div class="app">
<!-- Top Bar -->
<header class="topbar">
<div class="topbar-left">
<div class="logo">
<svg width="30" height="30" viewBox="0 0 30 30" fill="none">
<rect width="30" height="30" rx="9" fill="#7c3aed"/>
<polygon points="11,8 23,15 11,22" fill="white"/>
</svg>
<span>Speechify</span>
</div>
</div>
<div class="topbar-right">
<button class="btn-icon" id="btn-sidebar-toggle" title="Toggle Input Panel">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
<rect x="3" y="3" width="18" height="18" rx="2"/>
<line x1="9" y1="3" x2="9" y2="21"/>
</svg>
</button>
<button class="btn-icon" id="btn-settings-toggle" title="Voice Settings">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
<circle cx="12" cy="12" r="3"/>
<path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/>
</svg>
</button>
</div>
</header>
<div class="main-layout">
<!-- Left Sidebar: Input -->
<aside class="sidebar-left" id="sidebar-left">
<div class="sidebar-header"><h3>Add Content</h3></div>
<div class="tabs">
<button class="tab active" data-tab="text">Text</button>
<button class="tab" data-tab="pdf">PDF</button>
<button class="tab" data-tab="url">URL</button>
</div>
<!-- Text Tab -->
<div class="tab-content active" id="tab-text">
<textarea id="text-input" placeholder="Paste your text here..."></textarea>
<button class="btn-primary" id="btn-load-text">Load Text</button>
</div>
<!-- PDF Tab -->
<div class="tab-content" id="tab-pdf">
<div class="upload-area" id="upload-area">
<svg width="44" height="44" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round">
<path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/>
<polyline points="14 2 14 8 20 8"/>
<line x1="12" y1="18" x2="12" y2="12"/>
<line x1="9" y1="15" x2="15" y2="15"/>
</svg>
<p>Drop PDF here or<br><strong>click to upload</strong></p>
<input type="file" id="pdf-input" accept=".pdf" hidden />
</div>
<div id="pdf-status" class="status-text"></div>
</div>
<!-- URL Tab -->
<div class="tab-content" id="tab-url">
<input type="url" id="url-input" class="text-field" placeholder="https://example.com/article" />
<button class="btn-primary" id="btn-load-url">Fetch Article</button>
<div id="url-status" class="status-text"></div>
</div>
</aside>
<!-- Main Content -->
<main class="content-area" id="content-area">
<div id="document-header" class="document-header" style="display:none">
<h1 class="document-title" id="document-title"></h1>
<p class="document-meta" id="document-meta"></p>
</div>
<div class="text-viewer" id="text-viewer">
<div class="empty-state">
<svg width="60" height="60" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1">
<path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/>
<polyline points="14 2 14 8 20 8"/>
<line x1="16" y1="13" x2="8" y2="13"/>
<line x1="16" y1="17" x2="8" y2="17"/>
</svg>
<p>Load a document to get started</p>
<span>Paste text, upload a PDF, or enter a URL</span>
</div>
</div>
</main>
<!-- Right Sidebar: Voice Settings -->
<aside class="sidebar-right" id="sidebar-right">
<div class="sidebar-header"><h3>Voice Settings</h3></div>
<div class="setting-group">
<label class="setting-label">TTS Model</label>
<select id="model-select" class="select"></select>
</div>
<div class="setting-group">
<label class="setting-label">Voice</label>
<select id="voice-select" class="select"></select>
</div>
<div class="setting-group">
<label class="setting-label">Speed — <span id="speed-label">1x</span></label>
<input type="range" id="speed-slider" min="0.5" max="3" step="0.25" value="1" class="slider" />
<div class="speed-presets">
<button class="speed-btn" data-speed="0.75">0.75×</button>
<button class="speed-btn active" data-speed="1">1×</button>
<button class="speed-btn" data-speed="1.25">1.25×</button>
<button class="speed-btn" data-speed="1.5">1.5×</button>
<button class="speed-btn" data-speed="2">2×</button>
<button class="speed-btn" data-speed="3">3×</button>
</div>
</div>
<div class="setting-group">
<label class="setting-label">Font Size</label>
<div class="font-size-row">
<button class="btn-sz" id="font-decrease">A</button>
<span id="font-size-label">18px</span>
<button class="btn-sz" id="font-increase">A+</button>
</div>
</div>
<div class="setting-group">
<button class="btn-secondary" id="btn-preview">▶ Preview Voice</button>
</div>
</aside>
</div><!-- /main-layout -->
<!-- Player Bar -->
<div class="player-bar">
<div class="player-left">
<p class="now-playing" id="now-playing">No document loaded</p>
</div>
<div class="player-center">
<button class="ctrl-btn" id="btn-prev" title="Previous sentence (←)">
<svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor"><path d="M6 6h2v12H6zm3.5 6 8.5 6V6z"/></svg>
</button>
<button class="play-btn" id="btn-play" title="Play / Pause (Space)">
<svg class="icon-play" width="26" height="26" viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg>
<svg class="icon-pause" width="26" height="26" viewBox="0 0 24 24" fill="currentColor" style="display:none"><path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"/></svg>
</button>
<button class="ctrl-btn" id="btn-next" title="Next sentence (→)">
<svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor"><path d="M6 18l8.5-6L6 6v12zm2.5-6 5.5 4V8l-5.5 4zM16 6h2v12h-2z"/></svg>
</button>
</div>
<div class="player-right">
<span class="progress-text"><span id="cur-sent">0</span> / <span id="tot-sent">0</span></span>
<div class="progress-track" id="progress-track">
<div class="progress-fill" id="progress-fill"></div>
</div>
</div>
</div>
</div><!-- /app -->
<!-- Loading overlay -->
<div class="loading-overlay" id="loading-overlay">
<div class="spinner"></div>
<p id="loading-text">Loading…</p>
</div>
<script src="/static/app.js"></script>
</body>
</html>