124 lines
4.9 KiB
HTML
124 lines
4.9 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Add 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; }
|
|
|
|
.form { max-width: 520px; margin: 2rem auto; padding: 0 1.5rem; }
|
|
|
|
label { display: block; font-size: 0.8rem; color: #666; margin-bottom: 0.3rem; margin-top: 1.25rem; }
|
|
label:first-child { margin-top: 0; }
|
|
input[type=text] { display: block; width: 100%; padding: 0.6rem 0.75rem; background: #1c1c1c; border: 1px solid #2a2a2a; border-radius: 4px; color: #eee; font-size: 0.95rem; }
|
|
input[type=text]:focus { outline: none; border-color: #555; }
|
|
|
|
.hint { font-size: 0.75rem; color: #444; margin-top: 0.3rem; }
|
|
|
|
button { margin-top: 1.75rem; width: 100%; padding: 0.65rem; background: #2563eb; border: none; border-radius: 4px; color: #fff; font-size: 0.95rem; cursor: pointer; }
|
|
button:hover:not(:disabled) { background: #1d4ed8; }
|
|
button:disabled { opacity: 0.5; cursor: default; }
|
|
|
|
.status { margin-top: 1.25rem; font-size: 0.85rem; padding: 0.75rem 1rem; border-radius: 4px; display: none; }
|
|
.status.ok { background: #14532d; color: #86efac; display: block; }
|
|
.status.err { background: #450a0a; color: #fca5a5; display: block; }
|
|
|
|
.preview { margin-top: 2rem; padding-top: 1.5rem; border-top: 1px solid #1e1e1e; display: none; }
|
|
.preview p.label { font-size: 0.75rem; color: #555; letter-spacing: 0.08em; text-transform: uppercase; margin-bottom: 0.75rem; }
|
|
.preview-sentence { font-size: clamp(1.5rem, 4vw, 3rem); color: #eee; line-height: 1.3; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
|
|
<div class="topbar">
|
|
<a href="/">← Styles</a>
|
|
<h1>Add fonts</h1>
|
|
</div>
|
|
|
|
<div class="form">
|
|
|
|
<label for="family">Font family name</label>
|
|
<input type="text" id="family" placeholder="e.g. Barlow" autocomplete="off">
|
|
|
|
<label for="weights">Weights (optional)</label>
|
|
<input type="text" id="weights" placeholder="e.g. 400,700,900 — leave blank for all">
|
|
<p class="hint">Comma-separated numeric weights. If blank, all available weights are downloaded.</p>
|
|
|
|
<label for="sentence">Preview sentence</label>
|
|
<input type="text" id="sentence" value="The quick brown fox jumps over the lazy dog">
|
|
|
|
<button id="btn">Download from Google Fonts</button>
|
|
|
|
<div class="status" id="status"></div>
|
|
|
|
<div class="preview" id="preview">
|
|
<p class="label">Preview</p>
|
|
<p class="preview-sentence" id="preview-text"></p>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<script>
|
|
const btn = document.getElementById('btn');
|
|
const statusEl = document.getElementById('status');
|
|
const preview = document.getElementById('preview');
|
|
const previewText = document.getElementById('preview-text');
|
|
|
|
function showStatus(msg, ok) {
|
|
statusEl.textContent = msg;
|
|
statusEl.className = 'status ' + (ok ? 'ok' : 'err');
|
|
}
|
|
|
|
btn.addEventListener('click', async () => {
|
|
const family = document.getElementById('family').value.trim();
|
|
const wRaw = document.getElementById('weights').value.trim();
|
|
const sentence = document.getElementById('sentence').value || 'The quick brown fox';
|
|
|
|
if (!family) { showStatus('Enter a font family name.', false); return; }
|
|
|
|
const weights = wRaw
|
|
? wRaw.split(',').map(w => parseInt(w.trim(), 10)).filter(n => !isNaN(n))
|
|
: [];
|
|
|
|
btn.disabled = true;
|
|
btn.textContent = 'Downloading…';
|
|
statusEl.className = 'status';
|
|
|
|
try {
|
|
const res = await fetch('/api/fonts/download', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ family, weights }),
|
|
});
|
|
const data = await res.json();
|
|
|
|
if (res.ok) {
|
|
showStatus(`Downloaded ${data.downloaded.length} file(s): ${data.downloaded.join(', ')}`, true);
|
|
const link = document.createElement('link');
|
|
link.rel = 'stylesheet';
|
|
link.href = `/get-font?family=${encodeURIComponent(family)}`;
|
|
document.head.appendChild(link);
|
|
previewText.style.fontFamily = `'${family}', sans-serif`;
|
|
previewText.textContent = sentence;
|
|
preview.style.display = 'block';
|
|
} else {
|
|
showStatus(data.error ?? 'Download failed.', false);
|
|
}
|
|
} catch {
|
|
showStatus('Network error.', false);
|
|
} finally {
|
|
btn.disabled = false;
|
|
btn.textContent = 'Download from Google Fonts';
|
|
}
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|