diff --git a/web/navi.css b/web/navi.css index 6afbf29..010cfd1 100644 --- a/web/navi.css +++ b/web/navi.css @@ -2053,3 +2053,64 @@ html.navi-dark body .navi-ws-open:hover { background-color: rgba(51, 65, 85, .95) !important; color: #e8eefc !important; } + +/* ── 备案号:压成一行小字贴底 + 每日一言 ── + 用户反馈:原来是个大胶囊、区域太大"喧宾夺主",且位置不贴底。 + 目标:小小一行,安静地待在底部,旁边点缀一句每日一言。 */ +html[data-theme] .navi-footer-host { + min-height: 0 !important; + padding: 0 !important; + margin: 0 !important; + background: transparent !important; + border: 0 !important; + box-shadow: none !important; + backdrop-filter: none !important; + -webkit-backdrop-filter: none !important; +} +html[data-theme] .navi-footer { + display: flex !important; + align-items: center !important; + justify-content: center !important; + gap: 6px !important; + flex-wrap: nowrap !important; + max-width: 100% !important; + padding: 2px 10px !important; + margin: 0 auto !important; + border: 0 !important; + border-radius: 0 !important; + background: transparent !important; + box-shadow: none !important; + backdrop-filter: none !important; + -webkit-backdrop-filter: none !important; + font-size: 11px !important; + line-height: 1.5 !important; + color: #94a3b8 !important; + opacity: .92; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} +html[data-theme] .navi-footer a, +html[data-theme] .navi-footer .navi-footer-sep { + font-size: 11px !important; + color: #94a3b8 !important; +} +html[data-theme] .navi-footer a:hover { color: #475569 !important; } +html.navi-dark[data-theme] .navi-footer, +html.navi-dark[data-theme] .navi-footer a, +html.navi-dark[data-theme] .navi-footer .navi-footer-sep { color: #7c8ea6 !important; } +html.navi-dark[data-theme] .navi-footer a:hover { color: #cbd5e1 !important; } + +/* 每日一言:更淡一档,作为点缀 */ +html[data-theme] .navi-footer .navi-quote { + color: #b6c2d2 !important; + font-style: italic; + max-width: 46vw; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +html.navi-dark[data-theme] .navi-footer .navi-quote { color: #6b7d95 !important; } +@media (max-width: 520px) { + html[data-theme] .navi-footer .navi-quote { max-width: 38vw; } +} diff --git a/web/navi.js b/web/navi.js index c49a240..3421b91 100644 --- a/web/navi.js +++ b/web/navi.js @@ -711,3 +711,52 @@ document.addEventListener('click', function (e) { } } catch (_) {} }, true); + +/* 每日一言:作为备案号旁的小点缀。按天缓存(localStorage), + 接口不可用时用内置句子兜底——装饰性内容不该影响页面可用性。 */ +(function installDailyQuote() { + var FALLBACK = [ + '保持热爱,奔赴山海。', + '慢慢来,比较快。', + '今天也要好好吃饭。', + '把复杂的事做简单。', + '不着急,一切都会好起来。', + '少即是多。', + '做难而正确的事。' + ]; + function key() { var d = new Date(); return 'navi-quote-' + d.getFullYear() + '-' + (d.getMonth() + 1) + '-' + d.getDate(); } + function pickFallback() { return FALLBACK[Math.floor(Math.random() * FALLBACK.length)]; } + function render(text) { + var footer = document.querySelector('.navi-footer'); + if (!footer) return false; + if (footer.querySelector('.navi-quote')) return true; + var sep = document.createElement('span'); + sep.className = 'navi-footer-sep'; + sep.textContent = '·'; + var q = document.createElement('span'); + q.className = 'navi-quote'; + q.textContent = text; + footer.appendChild(sep); + footer.appendChild(q); + return true; + } + function cached() { try { return localStorage.getItem(key()); } catch (e) { return null; } } + function store(t) { try { localStorage.setItem(key(), t); } catch (e) {} } + var text = cached(); + if (text) { if (!render(text)) waitAndRender(text); return; } + var done = false; + var ctl = (typeof AbortController !== 'undefined') ? new AbortController() : null; + var timer = setTimeout(function () { if (!done && ctl) { try { ctl.abort(); } catch (e) {} } }, 3000); + fetch('https://v1.hitokoto.cn/?encode=text&charset=utf-8', ctl ? { signal: ctl.signal } : {}) + .then(function (r) { return r.ok ? r.text() : ''; }) + .then(function (t) { + done = true; clearTimeout(timer); + var v = (t || '').trim().slice(0, 40) || pickFallback(); + store(v); if (!render(v)) waitAndRender(v); + }) + .catch(function () { done = true; clearTimeout(timer); var v = pickFallback(); if (!render(v)) waitAndRender(v); }); + function waitAndRender(v) { + var n = 0; + var iv = setInterval(function () { n++; if (render(v) || n > 20) clearInterval(iv); }, 500); + } +})();