99 lines
4.0 KiB
HTML
99 lines
4.0 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>List fonts — Styles</title>
|
|
<style>
|
|
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
|
body { font-family: system-ui, sans-serif; background: #111; color: #eee; min-height: 100vh; }
|
|
|
|
.topbar { display: flex; align-items: center; gap: 1rem; padding: 1rem 1.5rem; border-bottom: 1px solid #1e1e1e; }
|
|
.topbar a { color: #555; text-decoration: none; font-size: 0.85rem; }
|
|
.topbar a:hover { color: #aaa; }
|
|
.topbar h1 { font-size: 1rem; font-weight: 600; color: #eee; }
|
|
|
|
.preview-bar { padding: 1rem 1.5rem; border-bottom: 1px solid #1e1e1e; display: flex; gap: 0.75rem; align-items: center; }
|
|
.preview-bar label { font-size: 0.8rem; color: #666; white-space: nowrap; }
|
|
.preview-bar input { flex: 1; background: #1c1c1c; border: 1px solid #2a2a2a; border-radius: 4px; color: #eee; padding: 0.5rem 0.75rem; font-size: 0.95rem; }
|
|
.preview-bar input:focus { outline: none; border-color: #555; }
|
|
|
|
.families { padding: 1.5rem; display: flex; flex-direction: column; gap: 2.5rem; }
|
|
.family-block .family-name { font-size: 0.75rem; letter-spacing: 0.1em; text-transform: uppercase; color: #555; margin-bottom: 1rem; }
|
|
.weight-row { margin-bottom: 0.5rem; display: flex; align-items: baseline; gap: 1rem; }
|
|
.weight-label { font-size: 0.7rem; color: #444; width: 3.5rem; flex-shrink: 0; }
|
|
.weight-sample { color: #eee; line-height: 1.2; }
|
|
.weight-sample.italic { font-style: italic; }
|
|
|
|
.empty { padding: 3rem 1.5rem; text-align: center; color: #444; font-size: 0.9rem; }
|
|
.loading { padding: 3rem 1.5rem; text-align: center; color: #444; font-size: 0.9rem; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
|
|
<div class="topbar">
|
|
<a href="/">← Styles</a>
|
|
<h1>List fonts</h1>
|
|
</div>
|
|
|
|
<div class="preview-bar">
|
|
<label for="sentence">Preview</label>
|
|
<input type="text" id="sentence" value="The quick brown fox jumps over the lazy dog">
|
|
</div>
|
|
|
|
<div id="content">
|
|
<p class="loading">Loading…</p>
|
|
</div>
|
|
|
|
<script>
|
|
const sentenceInput = document.getElementById('sentence');
|
|
const content = document.getElementById('content');
|
|
let families = [];
|
|
|
|
function renderSize(weight, sentence) {
|
|
const size = Math.max(1.2, Math.min(4, window.innerWidth / (sentence.length * 0.6 + 4)));
|
|
return `${size.toFixed(2)}rem`;
|
|
}
|
|
|
|
function render() {
|
|
const sentence = sentenceInput.value || 'The quick brown fox';
|
|
if (families.length === 0) {
|
|
content.innerHTML = '<p class="empty">No fonts downloaded yet. <a href="/add-fonts" style="color:#2563eb;text-decoration:none">Add one →</a></p>';
|
|
return;
|
|
}
|
|
|
|
content.className = 'families';
|
|
content.innerHTML = families.map(f => {
|
|
const rows = [
|
|
...f.weights.map(w => `
|
|
<div class="weight-row">
|
|
<span class="weight-label">${w}</span>
|
|
<span class="weight-sample" style="font-family:'${f.family}';font-weight:${w};font-size:clamp(1rem,3vw,2.5rem)">${sentence}</span>
|
|
</div>`),
|
|
...f.italics.map(w => `
|
|
<div class="weight-row">
|
|
<span class="weight-label">${w}i</span>
|
|
<span class="weight-sample italic" style="font-family:'${f.family}';font-weight:${w};font-size:clamp(1rem,3vw,2.5rem)">${sentence}</span>
|
|
</div>`),
|
|
].join('');
|
|
|
|
const cssUrl = `/get-font?family=${encodeURIComponent(f.family)}`;
|
|
return `
|
|
<div class="family-block">
|
|
<link rel="stylesheet" href="${cssUrl}">
|
|
<p class="family-name">${f.family}</p>
|
|
${rows}
|
|
</div>`;
|
|
}).join('');
|
|
}
|
|
|
|
sentenceInput.addEventListener('input', render);
|
|
|
|
fetch('/api/fonts')
|
|
.then(r => r.json())
|
|
.then(data => { families = data; render(); })
|
|
.catch(() => { content.innerHTML = '<p class="empty">Failed to load fonts.</p>'; });
|
|
</script>
|
|
</body>
|
|
</html>
|