|
30 | 30 | --smoke:rgba(11,114,133,.18); --lossbar:rgba(209,67,63,.5); --glow:0; |
31 | 31 | --smoke-hot:#064a57; --smoke-mid:#1596ad; --smoke-cool:#b3722f; |
32 | 32 | } |
33 | | - /* Nord — the arctic palette that ships in half the terminals on earth. |
34 | | - Desaturated blue-greys with a single frost accent; nothing shouts. */ |
35 | | - html[data-theme="nord"] { |
36 | | - --bg:#2e3440; --panel:#3b4252; --screen:#292e39; --line:#434c5e; |
37 | | - --phos:#88c0d0; --amber:#ebcb8b; --alert:#bf616a; --ink:#e5e9f0; --dim:#7b88a1; |
38 | | - --grid-axis:#4c566a; --grid-split:#373e4c; |
39 | | - --smoke:rgba(136,192,208,.18); --lossbar:rgba(191,97,106,.55); --glow:5; |
40 | | - --smoke-hot:#eceff4; --smoke-mid:#88c0d0; --smoke-cool:#5e81ac; |
41 | | - --shadow:0 1px 2px rgba(0,0,0,.35); --shadow-lg:0 10px 30px rgba(0,0,0,.30); |
42 | | - } |
43 | 33 | /* Solarized Light — Ethan Schoonover's palette, tuned for long reading sessions. |
44 | 34 | Warm paper base, muted cyan trace, red reserved strictly for loss. */ |
45 | 35 | html[data-theme="solarized"] { |
|
94 | 84 | footer { margin-top:12px; color:var(--dim); font-size:12px; display:flex; gap:10px; flex-wrap:wrap; } |
95 | 85 | #conclusion { color:var(--ink); } |
96 | 86 | .legend { color:var(--dim); } |
97 | | - .promos { display:grid; grid-template-columns:1fr 1fr; gap:14px; margin-top:16px; } |
98 | | - @media (max-width:720px) { .promos { grid-template-columns:1fr; } } |
| 87 | + .promos { margin-top:16px; } |
99 | 88 | .promo { background:var(--panel); border:1px solid var(--line); border-radius:12px; padding:14px 16px; |
100 | 89 | box-shadow:var(--shadow); text-decoration:none; display:block; } |
101 | 90 | .promo.sponsor { border-style:dashed; } |
102 | 91 | .promo.sponsor:hover { border-color:var(--phos); } |
103 | 92 | .promo-h { font-family:var(--mono); font-size:10px; letter-spacing:.16em; color:var(--dim); margin-bottom:6px; } |
104 | | - .promo-b { color:var(--ink); font-size:13px; } |
| 93 | + .promo-b { color:var(--ink); font-size:13px; display:flex; gap:16px; |
| 94 | + align-items:center; justify-content:space-between; flex-wrap:wrap; } |
| 95 | + .promo-b a { color:var(--phos); text-decoration:none; font-weight:600; white-space:nowrap; } |
| 96 | + .promo-b a:hover { text-decoration:underline; } |
| 97 | + .promo-h #ver { color:var(--phos); letter-spacing:0; } |
105 | 98 | .share .promo-b { display:flex; gap:14px; align-items:center; flex-wrap:wrap; } |
106 | 99 | .share a { color:var(--phos); text-decoration:none; font-weight:600; } |
107 | 100 | .share a:hover { text-decoration:underline; } |
|
164 | 157 | </footer> |
165 | 158 |
|
166 | 159 | <div class="promos"> |
167 | | - <a class="promo sponsor" id="sponsorSlot" href="https://github.com/githubflyideas/pingping#sponsor" target="_blank" rel="noopener"> |
168 | | - <div class="promo-h">SPONSOR</div> |
169 | | - <div class="promo-b">This slot is for one VPS / IDC / network sponsor. Your GIF here — reach out on GitHub.</div> |
170 | | - </a> |
171 | | - <div class="promo share"> |
172 | | - <div class="promo-h">LIKE PINGPING? <span id="ver" style="color:var(--phos)"></span></div> |
| 160 | + <div class="promo sponsor" id="sponsorSlot"> |
| 161 | + <div class="promo-h">SPONSOR <span id="ver"></span></div> |
173 | 162 | <div class="promo-b"> |
| 163 | + <span>This slot is for one VPS / IDC / network sponsor — your GIF here.</span> |
174 | 164 | <a href="https://github.com/githubflyideas/pingping" target="_blank" rel="noopener">★ Star on GitHub</a> |
175 | | - <span class="share-links" id="shareLinks"></span> |
176 | 165 | </div> |
177 | 166 | </div> |
178 | 167 | </div> |
|
181 | 170 | <script> |
182 | 171 | const $ = id => document.getElementById(id); |
183 | 172 | const cssv = n => getComputedStyle(document.documentElement).getPropertyValue(n).trim(); |
184 | | -const THEMES = ['dark', 'daylight', 'arctic', 'nord', 'solarized', 'amber']; |
| 173 | +const THEMES = ['dark', 'daylight', 'arctic', 'solarized', 'amber']; |
185 | 174 | let theme = localStorage.getItem('pp_theme') || 'dark'; |
186 | 175 | if (!THEMES.includes(theme)) theme = 'dark'; |
187 | 176 | function applyTheme() { |
|
388 | 377 | render(); |
389 | 378 | }); |
390 | 379 |
|
391 | | -// 分享的是公开项目主页,不是本地私有面板 |
| 380 | +// 版本号显示在赞助栏标题;保留期决定哪些时间窗有意义 |
392 | 381 | fetch('/api/version').then(r => r.json()).then(d => { |
393 | | - const el = document.getElementById('ver'); |
394 | | - if (el && d.version) el.textContent = 'v' + d.version.replace(/^v/, ''); |
395 | | - // 超出保留期的窗口按钮没有意义,直接藏起来 —— 用 --days 决定看得到多久 |
| 382 | + const el = $('ver'); |
| 383 | + if (el && d.version) el.textContent = 'v' + String(d.version).replace(/^v/, ''); |
396 | 384 | const keep = (d.retention_days || 0) * 1440; |
397 | 385 | if (keep > 0) { |
398 | 386 | document.querySelectorAll('.rng button[data-m]').forEach(b => { |
|
401 | 389 | } |
402 | 390 | }).catch(() => {}); |
403 | 391 |
|
404 | | -(function buildShare() { |
405 | | - const url = 'https://github.com/githubflyideas/pingping'; |
406 | | - const text = 'pingping — a single-binary link quality oscilloscope. One binary. One graph. Zero guesswork.'; |
407 | | - const links = { |
408 | | - X: `https://twitter.com/intent/tweet?text=${encodeURIComponent(text)}&url=${encodeURIComponent(url)}`, |
409 | | - Facebook: `https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(url)}`, |
410 | | - Reddit: `https://www.reddit.com/submit?url=${encodeURIComponent(url)}&title=${encodeURIComponent('pingping — modern SmokePing alternative')}`, |
411 | | - HN: `https://news.ycombinator.com/submitlink?u=${encodeURIComponent(url)}&t=${encodeURIComponent('pingping — single-binary link quality oscilloscope')}` |
412 | | - }; |
413 | | - const box = document.getElementById('shareLinks'); |
414 | | - Object.entries(links).forEach(([k, href]) => { |
415 | | - const a = document.createElement('a'); |
416 | | - a.href = href; a.target = '_blank'; a.rel = 'noopener'; a.textContent = k; |
417 | | - box.appendChild(a); |
418 | | - }); |
419 | | - const ig = document.createElement('a'); |
420 | | - ig.href = '#'; ig.textContent = 'Instagram (copy link)'; |
421 | | - ig.onclick = e => { e.preventDefault(); navigator.clipboard && navigator.clipboard.writeText(url); |
422 | | - ig.textContent = 'link copied ✓'; setTimeout(() => ig.textContent = 'Instagram (copy link)', 1500); }; |
423 | | - box.appendChild(ig); |
424 | | -})(); |
425 | | - |
426 | 392 | render(); |
427 | 393 | setInterval(() => { if (!rendering) render(); }, 60000); // 慢查询进行中时跳过本次自动刷新 |
428 | 394 | // Long windows: smoke is a hot-data privilege — beyond 24h you get the |
|
0 commit comments