95 lines
4.0 KiB
HTML
95 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">
|
||
|
|
<title>Translation — Poster</title>
|
||
|
|
<style>
|
||
|
|
:root { --ink: #10131a; --muted: #5b6478; }
|
||
|
|
* { box-sizing: border-box; }
|
||
|
|
body {
|
||
|
|
margin: 0; background: #f4f5f8; color: var(--ink);
|
||
|
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
|
||
|
|
display: grid; place-items: center; min-height: 100vh; padding: 1.5rem;
|
||
|
|
}
|
||
|
|
.sheet {
|
||
|
|
width: 100%; max-width: 46rem; aspect-ratio: 8.5 / 11;
|
||
|
|
background: #fff; border-radius: 12px; box-shadow: 0 1.5rem 3rem rgba(0,0,0,.12);
|
||
|
|
padding: 3.5rem 3rem; display: flex; flex-direction: column; align-items: center;
|
||
|
|
text-align: center; gap: 1.25rem;
|
||
|
|
}
|
||
|
|
.church { font-size: .875rem; letter-spacing: .18em; text-transform: uppercase; color: var(--muted); }
|
||
|
|
h1 { font-size: 2.75rem; line-height: 1.1; margin: 0; font-weight: 750; letter-spacing: -.01em; }
|
||
|
|
.sub { font-size: 1.25rem; color: var(--muted); margin: 0; }
|
||
|
|
.qr { width: 17rem; height: 17rem; margin: .5rem 0; }
|
||
|
|
.url { font-size: 1.125rem; font-weight: 600; letter-spacing: .01em; word-break: break-all; }
|
||
|
|
.langs {
|
||
|
|
display: flex; flex-wrap: wrap; justify-content: center; gap: .5rem .875rem;
|
||
|
|
font-size: 1.0625rem; color: var(--ink); margin-top: auto; padding-top: 1.25rem;
|
||
|
|
border-top: 1px solid #e3e6ec; width: 100%;
|
||
|
|
}
|
||
|
|
.langs span { white-space: nowrap; }
|
||
|
|
.foot { font-size: .8125rem; color: var(--muted); }
|
||
|
|
.bar { max-width: 46rem; width: 100%; display: flex; gap: .5rem; justify-content: flex-end; margin-bottom: .75rem; }
|
||
|
|
.bar button {
|
||
|
|
border: 1px solid #d3d8e2; background: #fff; color: var(--ink);
|
||
|
|
padding: .5rem 1rem; border-radius: 8px; font: inherit; font-size: .875rem; cursor: pointer;
|
||
|
|
}
|
||
|
|
@media print {
|
||
|
|
body { background: #fff; padding: 0; display: block; }
|
||
|
|
.bar { display: none; }
|
||
|
|
.sheet { box-shadow: none; border-radius: 0; max-width: none; width: 100%; aspect-ratio: auto; min-height: 100vh; }
|
||
|
|
}
|
||
|
|
</style>
|
||
|
|
</head>
|
||
|
|
<body>
|
||
|
|
<div class="bar"><button onclick="window.print()">Print</button></div>
|
||
|
|
<div class="sheet">
|
||
|
|
<div class="church" id="church">—</div>
|
||
|
|
<h1 id="head">Listen in your language</h1>
|
||
|
|
<p class="sub" id="sub">Scan with your phone camera</p>
|
||
|
|
<img class="qr" id="qr" alt="QR code">
|
||
|
|
<div class="url" id="url">—</div>
|
||
|
|
<div class="langs" id="langs"></div>
|
||
|
|
<div class="foot">Free · No app to download · Works on any phone</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<script src="/languages.js"></script>
|
||
|
|
<script>
|
||
|
|
(function () {
|
||
|
|
var params = new URLSearchParams(location.search);
|
||
|
|
var pin = params.get('pin');
|
||
|
|
|
||
|
|
/* "Listen in your language" written in the languages most likely to be in the
|
||
|
|
room — a poster nobody can read is just decoration. */
|
||
|
|
var INVITES = ['Escucha en tu idioma', '用您的语言收听', 'Écoutez dans votre langue',
|
||
|
|
'Ouça no seu idioma', '당신의 언어로 들으세요', 'Nghe bằng ngôn ngữ của bạn',
|
||
|
|
'Koute nan lang ou', 'استمع بلغتك', 'Слухайте своєю мовою', 'Sikiliza kwa lugha yako'];
|
||
|
|
|
||
|
|
function render(cfg, base) {
|
||
|
|
document.getElementById('church').textContent = cfg.serviceName || '';
|
||
|
|
document.getElementById('url').textContent = base.replace(/^https?:\/\//, '');
|
||
|
|
document.getElementById('qr').src = '/qr.svg?url=' + encodeURIComponent(base + '/');
|
||
|
|
var box = document.getElementById('langs');
|
||
|
|
box.textContent = '';
|
||
|
|
INVITES.forEach(function (t) {
|
||
|
|
var s = document.createElement('span');
|
||
|
|
s.textContent = t;
|
||
|
|
box.appendChild(s);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
var url = pin ? '/api/config' : '/api/languages';
|
||
|
|
var opts = pin ? { headers: { 'X-Operator-Pin': pin } } : {};
|
||
|
|
fetch(url, opts).then(function (r) { return r.json(); }).then(function (j) {
|
||
|
|
var cfg = j.config || j;
|
||
|
|
var base = (cfg.publicUrl || j.publicBase || location.origin).replace(/\/+$/, '');
|
||
|
|
render(cfg, base);
|
||
|
|
}).catch(function () {
|
||
|
|
render({ serviceName: '' }, location.origin);
|
||
|
|
});
|
||
|
|
})();
|
||
|
|
</script>
|
||
|
|
</body>
|
||
|
|
</html>
|