PageSourceSearch

https://github.nb-channel.top/Beta/product-Beta.html

html nb-channel.top collected 2026-10-06 13:15:37 UTC 73,020 bytes, 1,392 lines download raw bytes

1<!DOCTYPE html>
2<html lang="zh-CN">
3<head>
4<meta charset="UTF-8">
5<script>
6/* ===== 跨子域名登录态同步(github. / cloudflare. / pythonanywhere. 之间互通)=====
7   localStorage 是按 origin 隔离的,两个子域名各存各的,所以要借 Cookie 中转。
8   Cookie 设 Domain=.nb-channel.top,所有子域名都能读到。
9
10   这里不改页面原本的任何代码 —— 而是劫持 localStorage 的读写:
11     · 页面登录时 setItem('nb_session', ...)  → 顺手写一份到 Cookie
12     · 页面登出时 removeItem('nb_session')    → 顺手把 Cookie 清掉
13     · 页面加载时 Cookie 有、本地没有          → 自动注入进 localStorage
14   所以那 57 处登录/登出代码一行都不用动。
15
16   ⚠️ 这意味着 *.nb-channel.top 下任何一个子域名都能读到这个令牌,
17      包括 product-storage 那个 Workers。将来新增子域名前先想清楚这件事。 */
18(function () {
19    try {
20        var KEY_S = 'nb_session', KEY_U = 'nb_user';
21        var DOMAIN = '.nb-channel.top';
22        var MAXAGE = 30 * 86400;
23
24        // 只在 .nb-channel.top 域下才启用(本地开文件、或别的域名访问时保持原样)
25        if (location.hostname.indexOf('nb-channel.top') < 0) return;
26
27        function readCookie(n) {
28            var m = document.cookie.match(new RegExp('(?:^|;\\s*)' + n + '=([^;]*)'));
29            return m ? decodeURIComponent(m[1]) : null;
30        }
31        function writeCookie(n, v) {
32            document.cookie = n + '=' + encodeURIComponent(v) + ';path=/;domain=' + DOMAIN +
33                              ';max-age=' + MAXAGE + ';SameSite=Lax' +
34                              (location.protocol === 'https:' ? ';Secure' : '');
35        }
36        function dropCookie(n) {
37            document.cookie = n + '=;path=/;domain=' + DOMAIN + ';max-age=0;SameSite=Lax' +
38                              (location.protocol === 'https:' ? ';Secure' : '');
39        }
40
41        // ---- ① 页面加载时双向对齐 ----
42        [KEY_S, KEY_U].forEach(function (k) {
43            var c = readCookie(k), l = null;
44            try { l = localStorage.getItem(k); } catch (e) {}
45            if (l) {
46                if (l !== c) writeCookie(k, l);            // 本地有 → 同步出去
47            } else if (c) {
48                try { localStorage.setItem(k, c); } catch (e) {}   // 本地没有 → 采用 Cookie
49            }
50        });
51
52        // ---- ② 劫持写入:登录时同步到 Cookie ----
53        var _set = localStorage.setItem;
54        localStorage.setItem = function (k, v) {
55            try { if ((k === KEY_S || k === KEY_U) && v) writeCookie(k, v); } catch (e) {}
56            return _set.call(localStorage, k, v);
57        };
58
59        // ---- ③ 劫持删除:登出时同步清 Cookie ----
60        var _rm = localStorage.removeItem;
61        localStorage.removeItem = function (k) {
62            try { if (k === KEY_S || k === KEY_U) dropCookie(k); } catch (e) {}
63            return _rm.call(localStorage, k);
64        };
65
66        // ---- ④ 万一有人用 clear() ----
67        var _cl = localStorage.clear;
68        localStorage.clear = function () {
69            try { dropCookie(KEY_S); dropCookie(KEY_U); } catch (e) {}
70            return _cl.call(localStorage);
71        };
72    } catch (e) {}
73})();
74</script>
74
75<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
76<!-- 不发送 referer:图床防盗链 -->
77<meta name="referrer" content="no-referrer">
78<meta name="description" content="NB频道产品——镀铜液、炸不了溶液、化钉液、炸弹:把化学做成可以玩的东西。在线体验、演示视频与文件下载。">
79<meta property="og:title" content="我的产品 · NB频道官网">
80<meta property="og:description" content="把化学,做成可以玩的东西。">
81<meta name="theme-color" content="#0f172a">
82<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Cdefs%3E%3ClinearGradient id='g' x1='0' y1='0' x2='1' y2='1'%3E%3Cstop offset='0' stop-color='%233b82f6'/%3E%3Cstop offset='1' stop-color='%238b5cf6'/%3E%3C/linearGradient%3E%3C/defs%3E%3Crect width='64' height='64' rx='14' fill='url(%23g)'/%3E%3Ctext x='32' y='43' font-family='Arial,sans-serif' font-size='26' font-weight='800' fill='%23fff' text-anchor='middle'%3ENB%3C/text%3E%3C/svg%3E">
83<title>我的产品 - NB频道官网</title>
84<script>
85    (function () {
86        try {
87            var t = localStorage.getItem('theme');
88            if (t === 'dark' || (!t && window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
89                document.documentElement.classList.add('dark');
90            }
91        } catch (e) {}
92    })();
93</script>
93
94<style>
95* { margin: 0; padding: 0; box-sizing: border-box; }
96:root {
97    --bg: #f7f8fa;
98    --ink: #1a1d23;
99    --ink-soft: #5a6270;
100    --ink-faint: #8b93a3;
101    --line: #e8eaee;
102    --brand: #3b82f6;
103    --brand-deep: #2563eb;
104    --card: #ffffff;
105    --radius-lg: 20px;
106    --radius-md: 14px;
107    --shadow-1: 0 1px 2px rgba(16,24,40,.04), 0 4px 12px rgba(16,24,40,.06);
108    --shadow-2: 0 2px 4px rgba(16,24,40,.05), 0 24px 48px -20px rgba(16,24,40,.18);
109}
110html.dark { color-scheme: dark; }
111html.dark {
112    --bg: #0a101f;
113    --ink: #e5eaf3;
114    --ink-soft: #9aa7bd;
115    --ink-faint: #64748b;
116    --line: rgba(148,163,184,.16);
117    --card: #101a2e;
118    --shadow-1: 0 1px 2px rgba(0,0,0,.3), 0 6px 18px rgba(0,0,0,.28);
119    --shadow-2: 0 2px 6px rgba(0,0,0,.35), 0 28px 60px -24px rgba(0,0,0,.6);
120}
121html.dark .nav { background: rgba(10,16,31,.72); border-bottom-color: rgba(148,163,184,.12); }
122html.dark .nav.scrolled { background: rgba(10,16,31,.9); }
123html.dark .logo-img { filter: brightness(1.4) saturate(1.15); }
124html.dark .drawer { background: #0f1a30; }
125html.dark .drawer .d-close { background: rgba(255,255,255,.06); color: var(--ink); }
126html.dark .drawer a.d-item { color: var(--ink-soft); }
127html.dark .drawer a.d-item:hover, html.dark .drawer a.d-item.active { background: rgba(59,130,246,.14); color: #fff; }
128html.dark .drawer .d-brand { color: var(--ink); }
129html.dark .backtop { background: rgba(15,23,42,.85); color: #cbd5e1; border-color: rgba(148,163,184,.25); }
130html.dark .backtop:hover { background: var(--brand); color: #fff; }
131html.dark .footer-bottom { border-color: rgba(255,255,255,.06); }
132
133body {
134    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif;
135    background: var(--bg);
136    color: var(--ink);
137    line-height: 1.6;
138    -webkit-font-smoothing: antialiased;
139}
140a { text-decoration: none; color: inherit; }
141::selection { background: rgba(59,130,246,.22); }
142
143/* ============ 导航 ============ */
144.nav {
145    position: sticky; top: 0; z-index: 100;
146    display: flex; align-items: center; justify-content: space-between;
147    padding: 0 48px; height: 64px;
148    background: rgba(255,255,255,.72);
149    -webkit-backdrop-filter: blur(20px) saturate(1.5);
150    backdrop-filter: blur(20px) saturate(1.5);
151    border-bottom: 1px solid var(--line);
152}
153.nav-logo { display: flex; align-items: center; gap: 10px; font-size: 1.15rem; font-weight: 800; letter-spacing: .3px; margin-left: 12px; }
154.logo-img { display: block; height: 32px; width: auto; }
155.logo-text { color: var(--ink); }
156.nav-menu { display: flex; gap: 2px; }
157.nav-menu a {
158    position: relative; padding: 10px 14px;
159    font-size: .92rem; font-weight: 500; letter-spacing: .4px;
160    color: var(--ink-soft); white-space: nowrap; transition: color .3s ease;
161}
162.nav-menu a:hover { color: var(--ink); }
163.nav-menu a.active { color: var(--brand); font-weight: 600; }
164.nav-menu a::after {
165    content: ''; position: absolute; left: 14px; right: 14px; bottom: 4px;
166    height: 1px; background: var(--brand);
167    transform: scaleX(0); transform-origin: left;
168    transition: transform .35s cubic-bezier(.16,1,.3,1);
169}
170.nav-menu a:hover::after { transform: scaleX(1); }
171.nav-menu a.active::after { transform: scaleX(1); }
172.nav-menu a.nav-api { color: var(--brand); font-weight: 600; font-size: .86rem; }
173.nav-right-group { display: flex; align-items: center; gap: 10px; }
174.nav-auth-group { display: flex; gap: 8px; align-items: center; }
175.nav-clock {
176    display: flex; flex-direction: column; align-items: flex-end;
177    margin-right: 8px; flex-shrink: 0; user-select: none; line-height: 1.35;
178}
179.nav-clock .nc-time { font-size: 15.5px; font-weight: 800; letter-spacing: 1.5px; color: var(--ink); font-variant-numeric: tabular-nums; }
180.nav-clock .nc-row { display: flex; align-items: baseline; gap: 6px; font-style: normal; }
181.nav-clock .nc-date { font-size: 10.5px; font-weight: 600; letter-spacing: .4px; color: var(--ink-soft); font-variant-numeric: tabular-nums; }
182.nav-clock .nc-label { font-size: 8.5px; font-weight: 600; letter-spacing: 2px; color: var(--ink-faint); }
183.nav-auth {
184    padding: 8px 18px; border-radius: 999px;
185    background: rgba(255,255,255,.6); color: var(--ink);
186    border: 1px solid var(--line);
187    font-size: .88rem; font-weight: 600; cursor: pointer;
188    transition: all .25s ease; white-space: nowrap;
189}
190.nav-auth:hover { background: #fff; border-color: rgba(59,130,246,.4); }
191.nav-auth.primary {
192    background: linear-gradient(135deg, var(--brand), #6366f1);
193    border-color: transparent; color: #fff;
194    box-shadow: 0 8px 20px -8px rgba(59,130,246,.5);
195}
196.nav-auth.primary:hover { background: linear-gradient(135deg, #2563eb, #4f46e5); color: #fff; }
197html.dark .nav-auth { background: rgba(255,255,255,.05); color: var(--ink); border-color: rgba(148,163,184,.25); }
198html.dark .nav-auth:hover { background: rgba(255,255,255,.1); border-color: rgba(59,130,246,.5); }
199.theme-btn {
200    width: 38px; height: 38px; border-radius: 50%; border: 1px solid var(--line);
201    background: var(--bg); cursor: pointer; font-size: .95rem;
202    display: flex; align-items: center; justify-content: center; transition: all .25s ease;
203}
204.theme-btn:hover { border-color: rgba(59,130,246,.4); transform: translateY(-1px); }
205.nav-burger {
206    display: none; width: 38px; height: 38px; border-radius: 10px;
207    border: 1px solid var(--line); background: var(--bg);
208    font-size: .95rem; cursor: pointer; color: var(--ink);
209    align-items: center; justify-content: center;
210}
211@media (max-width: 900px) { .nav-menu { display: none; } .nav-burger { display: flex; } .nav-clock, .nav-auth-group { display: none; } }
212
213/* ============ Hero(产品) ============ */
214.vhero {
215    position: relative; color: #fff; overflow: hidden;
216    padding: 110px 48px 150px;
217    background:
218        radial-gradient(760px 460px at 12% 4%, rgba(59,130,246,.16), transparent 62%),
219        radial-gradient(640px 420px at 96% 60%, rgba(139,92,246,.12), transparent 60%),
220        linear-gradient(168deg, #0b1220 0%, #101c33 58%, #1c1745 100%);
221}
222.vhero::before {
223    content: ''; position: absolute; inset: 0; pointer-events: none; opacity: .5;
224    background-image: radial-gradient(rgba(255,255,255,.045) 1px, transparent 1px);
225    background-size: 34px 34px;
226    mask-image: linear-gradient(to bottom, rgba(0,0,0,.5), transparent 72%);
227    -webkit-mask-image: linear-gradient(to bottom, rgba(0,0,0,.5), transparent 72%);
228}
229.vhero-inner {
230    position: relative; z-index: 2; max-width: 1180px; margin: 0 auto;
231    display: grid; grid-template-columns: 1.05fr .95fr; gap: 70px; align-items: center;
232}
233.hero-eyebrow {
234    display: block; font-size: 11px; font-weight: 400;
235    letter-spacing: 8px; color: rgba(255,255,255,.42); margin-bottom: 40px;
236}
237.vhero h1 { font-size: clamp(2.7rem, 5.2vw, 4.6rem); font-weight: 800; letter-spacing: 8px; color: #fff; line-height: 1.12; }
238.vhero h1 .light { font-weight: 200; letter-spacing: 4px; color: #9cc0ff; }
239.vhero-sub {
240    margin: 34px 0 0; max-width: 470px;
241    font-size: .98rem; font-weight: 300; line-height: 2.15;
242    letter-spacing: .6px; color: rgba(255,255,255,.6);
243}
244.vhero-actions { margin-top: 48px; display: flex; gap: 44px; align-items: center; flex-wrap: wrap; }
245.hero-link {
246    font-size: .9rem; letter-spacing: 3px; font-weight: 600; color: #fff;
247    padding: 12px 2px; border-bottom: 1px solid rgba(255,255,255,.32);
248    transition: border-color .35s ease, color .35s ease;
249}
250.hero-link:hover { border-color: #7cb4ff; color: #7cb4ff; }
251/* 右侧统计卡 */
252.pd-stats {
253    background: rgba(255,255,255,.045);
254    border: 1px solid rgba(255,255,255,.1);
255    border-radius: 24px; padding: 10px 26px;
256    -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
257}
258.pd-row {
259    display: flex; align-items: baseline; justify-content: space-between;
260    padding: 13px 0; border-bottom: 1px dashed rgba(255,255,255,.1);
261}
262.pd-row:last-child { border-bottom: none; }
263.pd-row .k { font-size: .72rem; letter-spacing: 2.5px; color: rgba(255,255,255,.5); }
264.pd-row b { font-size: 1.12rem; font-weight: 700; color: #fff; letter-spacing: .5px; }
265.pd-row b small { font-size: .72rem; font-weight: 400; color: rgba(255,255,255,.55); letter-spacing: 1px; }
266.pd-tip { margin-top: 14px; font-size: .74rem; color: rgba(255,255,255,.4); letter-spacing: 1.2px; text-align: center; }
267.vhero-fade {
268    position: absolute; left: 0; right: 0; bottom: 0; height: 130px; z-index: 1;
269    background: linear-gradient(to bottom, transparent, var(--bg));
270    pointer-events: none;
271}
272
273/* ============ 正文 ============ */
274.vwrap { max-width: 1080px; margin: 0 auto; padding: 70px 48px 60px; }
275.leadq { text-align: center; max-width: 760px; margin: 0 auto 80px; }
276.leadq h2 { font-size: clamp(1.5rem, 2.8vw, 2.1rem); font-weight: 800; line-height: 1.6; letter-spacing: 1px; }
277.leadq h2 em { font-style: normal; color: var(--brand); }
278.leadq h2 .thin { font-weight: 200; color: var(--ink-soft); }
279.leadq .sig { margin-top: 26px; font-size: .9rem; color: var(--ink-faint); letter-spacing: 3px; }
280.leadq .sig b { color: var(--ink); font-weight: 700; letter-spacing: 1px; }
281
282/* 产品网格 */
283.pd-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; }
284.p-card {
285    background: var(--card); border-radius: var(--radius-lg); overflow: hidden;
286    border: 1px solid var(--line); box-shadow: var(--shadow-1);
287    display: flex; flex-direction: column;
288    transition: transform .35s cubic-bezier(.16,1,.3,1), box-shadow .35s ease;
289}
290.p-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-2); }
291.p-media {
292    position: relative; aspect-ratio: 16 / 9.4; overflow: hidden;
293    background: linear-gradient(140deg, rgba(59,130,246,.12), rgba(139,92,246,.12));
294}
295.p-media img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; transition: transform .9s cubic-bezier(.16,1,.3,1); }
296.p-card:hover .p-media img { transform: scale(1.045); }
297.p-media .p-no {
298    position: absolute; top: 14px; left: 16px; z-index: 2;
299    font-size: 11px; font-weight: 700; letter-spacing: 3px; color: #fff;
300    background: rgba(10,16,31,.55); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
301    padding: 5px 12px; border-radius: 999px; border: 1px solid rgba(255,255,255,.2);
302}
303.p-body { padding: 22px 24px 24px; display: flex; flex-direction: column; flex: 1; }
304.p-body h3 { font-size: 1.25rem; font-weight: 800; letter-spacing: 1px; margin-bottom: 9px; }
305.p-body .p-sub { font-size: .92rem; color: var(--ink-soft); line-height: 1.85; flex: 1; }
306.p-links { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 18px; }
307.p-link {
308    display: inline-flex; align-items: center; gap: 6px;
309    padding: 9px 18px; border-radius: 999px;
310    font-size: .84rem; font-weight: 700; letter-spacing: .8px;
311    border: 1px solid var(--line); background: var(--bg); color: var(--ink-soft);
312    transition: all .25s ease;
313}
314.p-link:hover { border-color: var(--brand); color: var(--brand); transform: translateY(-1px); }
315.p-link.go { background: linear-gradient(135deg, var(--brand), #6366f1); color: #fff; border-color: transparent; box-shadow: 0 8px 20px -8px rgba(59,130,246,.55); }
316.p-link.go:hover { color: #fff; box-shadow: 0 12px 26px -8px rgba(59,130,246,.6); }
317
318.p-note { text-align: center; color: var(--ink-faint); font-size: .82rem; letter-spacing: 1px; line-height: 2; padding: 26px 20px 0; }
319
320/* CTA */
321.cta {
322    text-align: center; padding: 84px 24px;
323    background: linear-gradient(170deg, #101c33 0%, #1c1745 100%);
324    color: #fff; margin-top: 70px;
325}
326.cta h2 { font-size: 1.7rem; font-weight: 800; letter-spacing: .5px; margin-bottom: 13px; }
327.cta p { color: rgba(255,255,255,.55); font-size: .93rem; font-weight: 300; margin-bottom: 32px; }
328.cta .cta-actions { display: flex; gap: 44px; justify-content: center; align-items: center; flex-wrap: wrap; }
329
330/* 页脚 */
331.footer { background: linear-gradient(180deg, #0f172a 0%, #0a0f1e 100%); color: #94a3b8; padding: 64px 48px 30px; }
332.footer-grid { max-width: 1180px; margin: 0 auto; display: grid; grid-template-columns: 2fr 1fr 1fr 1fr; gap: 44px; }
333.footer .brand { font-size: 1.1rem; font-weight: 800; color: #fff; margin-bottom: 14px; display: flex; align-items: center; gap: 10px; letter-spacing: .5px; }
334.footer .desc { font-size: .85rem; font-weight: 300; line-height: 2; margin-bottom: 20px; color: #7c8ba5; }
335.footer h5 { color: #e2e8f0; font-size: .88rem; font-weight: 700; margin-bottom: 18px; letter-spacing: 2px; }
336.footer a { display: block; color: #8fa0b8; font-size: .86rem; margin-bottom: 12px; transition: color .3s ease; }
337.footer a:hover { color: #fff; }
338.footer-bottom {
339    max-width: 1180px; margin: 44px auto 0; padding-top: 22px;
340    border-top: 1px solid rgba(255,255,255,.07);
341    font-size: .76rem; letter-spacing: 1px;
341 color: #5b6a85; text-align: center;
342}
343
344/* 抽屉 */
345.drawer-mask { display: none; position: fixed; inset: 0; z-index: 9000; background: rgba(10,15,28,.5); }
346.drawer {
347    position: fixed; top: 0; right: 0; bottom: 0; z-index: 9001;
348    width: 300px; max-width: 84vw; background: #fff;
349    box-shadow: -20px 0 60px -30px rgba(0,0,0,.4);
350    transform: translateX(105%); transition: transform .35s cubic-bezier(.16,1,.3,1);
351    padding: 22px 20px; overflow-y: auto;
352}
353.drawer.open { transform: none; }
354.drawer .d-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 14px; }
355.drawer .d-brand { font-weight: 800; font-size: 1.05rem; display: flex; align-items: center; gap: 8px; color: var(--ink); }
356.drawer .d-close { width: 36px; height: 36px; border-radius: 10px; border: none; background: var(--bg); font-size: .95rem; cursor: pointer; color: var(--ink); }
357.drawer a.d-item { display: block; padding: 12px 16px; border-radius: 12px; color: var(--ink-soft); font-size: .98rem; font-weight: 600; }
358.drawer a.d-item:hover, .drawer a.d-item.active { background: rgba(59,130,246,.1); color: var(--brand); }
359.drawer .d-auth { margin-top: 14px; padding-top: 16px; border-top: 1px solid var(--line); display: flex; gap: 10px; }
360.drawer .d-auth a { flex: 1; text-align: center; padding: 11px; border-radius: 999px; font-size: .9rem; font-weight: 600; }
361.drawer .d-auth .ga { background: var(--bg); color: var(--ink); border: 1px solid var(--line); }
362.drawer .d-auth .gab { background: linear-gradient(135deg, var(--brand), #6366f1); color: #fff; }
363
364/* 回到顶部 */
365.backtop {
366    position: fixed; right: 26px; bottom: 26px; z-index: 5000;
367    width: 46px; height: 46px; border-radius: 50%;
368    background: rgba(255,255,255,.92); color: var(--brand);
369    border: 1px solid var(--line); cursor: pointer; font-size: 1.05rem;
370    opacity: 0; transform: translateY(12px); transition: all .3s ease;
371    box-shadow: var(--shadow-1);
372}
373.backtop.show { opacity: 1; transform: none; }
374.backtop:hover { background: var(--brand); color: #fff; }
375
376/* 入场 */
377.reveal { opacity: 0; transform: translateY(16px); transition: opacity .7s cubic-bezier(.16,1,.3,1), transform .7s cubic-bezier(.16,1,.3,1); }
378.reveal.in { opacity: 1; transform: none; }
379@media (prefers-reduced-motion: reduce) { .reveal { opacity: 1; transform: none; transition: none; } }
380
381/* 响应式 */
382@media (max-width: 900px) {
383    .vhero { padding: 84px 24px 120px; }
384    .vwrap { padding: 56px 24px 40px; }
385    .footer { padding: 48px 24px 26px; }
386}
387@media (max-width: 760px) {
388    .nav { padding: 0 20px; }
389    .vhero { padding: 72px 20px 110px; }
390    .vhero-inner { grid-template-columns: 1fr; gap: 40px; }
391    .vhero h1 { font-size: 2.4rem; letter-spacing: 5px; }
392    .pd-stats { display: none; }
393    .vwrap { padding: 40px 20px 30px; }
394    .leadq { margin-bottom: 54px; }
395    .pd-grid { grid-template-columns: 1fr; }
396    .p-body { padding: 17px 18px 19px; }
397    .cta { margin-top: 50px; padding: 60px 20px; }
398    .footer-grid { grid-template-columns: 1fr; gap: 26px; }
399    .backtop { right: 18px; bottom: 18px; width: 42px; height: 42px; }
400}
401        .ui-fx-glow {
402            position: fixed; left: -999px; top: -999px; width: 240px; height: 240px;
403            border-radius: 50%; pointer-events: none; z-index: 9997;
404            transform: translate(-50%, -50%);
405            background: radial-gradient(circle, rgba(59,130,246,.18), rgba(139,92,246,.10) 45%, transparent 65%);
406            opacity: 0;
407        }
408
409
410        /* ===== Hero 入场动画(全站统一,与首页一致的错峰淡入) ===== */
411        @keyframes heroFadeUp { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: none; } }
412        .vhero .hero-eyebrow, .vhero h1, .vhero .vhero-sub, .vhero .vhero-actions,
413        .vhero .pd-stats, .vhero .cl-stats, .vhero .acard, .vhero .vhcard, .vhero .com-rules {
414            animation: heroFadeUp .95s cubic-bezier(.16,1,.3,1) both;
415        }
416        .vhero .hero-eyebrow { animation-delay: .08s; }
417        .vhero h1 { animation-delay: .2s; }
418        .vhero .vhero-sub { animation-delay: .34s; }
419        .vhero .vhero-actions { animation-delay: .48s; }
420        .vhero .pd-stats, .vhero .cl-stats, .vhero .acard, .vhero .vhcard, .vhero .com-rules { animation-delay: .32s; }
421        @media (prefers-reduced-motion: reduce) {
422            .vhero .hero-eyebrow, .vhero h1, .vhero .vhero-sub, .vhero .vhero-actions,
423            .vhero .pd-stats, .vhero .cl-stats, .vhero .acard, .vhero .vhcard, .vhero .com-rules { animation: none; }
424        }
425
426        /* ===== 全站公告条(与首页一致) ===== */
427        .beta-announce {
428            display: flex; align-items: center; gap: 14px;
429            max-width: 1080px; margin: 34px auto 0; padding: 15px 24px;
430            background: var(--card);
431            border-radius: var(--radius-md);
432            box-shadow: var(--shadow-1);
433            position: relative;
434        }
435        .beta-announce::before {
436            content: ''; position: absolute; left: 0; top: 18px; bottom: 18px; width: 3px;
437            border-radius: 3px; background: var(--brand);
438        }
439        .beta-announce .ba-title {
440            flex-shrink: 0; font-size: .82rem; font-weight: 700; color: var(--brand);
441            background: rgba(59,130,246,.08); border-radius: 999px; padding: 4px 12px;
442        }
443        .beta-announce .ba-track-wrap { flex: 1; overflow: hidden; min-width: 0; }
444        .beta-announce .ba-track { display: inline-block; white-space: nowrap; will-change: transform; }
445        .beta-announce .ba-item {
446            display: inline-block; white-space: nowrap; padding-right: 80px;
447            font-size: .92rem; color: var(--ink-soft);
448        }
449        .beta-announce a { color: var(--brand); text-decoration: underline; }
450        .beta-announce a:hover { color: var(--brand-deep); }
451        html.dark .beta-announce { background: var(--card); }
452        html.dark .beta-announce .ba-item { color: var(--ink-soft); }
453        @media (max-width: 760px) { .beta-announce { align-items: flex-start; flex-wrap: wrap; } }
454        html { scroll-behavior: smooth; }
455        [id] { scroll-margin-top: 86px; }
456
457
458/* ===== 「更多功能」下拉(动画与原菜单项完全一致) ===== */
459.nav-more { position: relative; display: flex; align-items: center; }
460.nav-more-btn {
461    position: relative; padding: 10px 14px;
462    font-size: .92rem; font-weight: 500; letter-spacing: .4px;
463    color: var(--ink-soft); background: none; border: none; cursor: pointer;
464    font-family: inherit; white-space: nowrap;
465    transition: color .3s ease;
466}
467.nav-more-btn::after {
468    content: ''; position: absolute; left: 14px; right: 14px; bottom: 2px;
469    height: 1px; background: var(--brand);
470    transform: scaleX(0); transform-origin: left;
471    transition: transform .35s cubic-bezier(.16,1,.3,1);
472}
473.nav-more-btn:hover { color: var(--ink); }
474.nav-more-btn:hover::after { transform: scaleX(1); }
475.nav-more.open .nav-more-btn { color: var(--ink); }
476.nav-more.open .nav-more-btn::after { transform: scaleX(1); }
477.nav-more-btn.active { color: var(--brand); font-weight: 600; }
478.nav-more-btn.active::after { transform: scaleX(1); }
479.nav-more-panel {
480    display: none; position: absolute; top: calc(100% + 12px); right: 0;
481    min-width: 178px; padding: 8px;
482    background: var(--card); border: 1px solid var(--line);
483    border-radius: 14px; box-shadow: 0 18px 44px -20px rgba(15,23,42,.42);
484    z-index: 300;
485}
486.nav-more.open .nav-more-panel { display: block; }
487.nav-more-panel a {
488    display: block; padding: 9px 12px; border-radius: 9px;
489    font-size: .88rem; color: var(--ink-soft); text-decoration: none; white-space: nowrap;
490    transition: background .18s ease, color .18s ease;
491}
492.nav-more-panel a:hover { background: rgba(59,130,246,.1); color: var(--brand); }
493html.dark .nav-more-panel { background: #0f1a30; border-color: rgba(148,163,184,.22); }
494html.dark .nav-more-panel a:hover { background: rgba(59,130,246,.2); color: #fff; }
495
496/* ===== 移动端:也显示这条菜单栏(左右滑动看全部),不再只靠汉堡 ===== */
497@media (max-width: 900px) {
498    .nav { padding: 0 12px; gap: 6px; }
499    .nav-logo { flex: 0 0 auto; margin-left: 0; }
500    .nav-menu {
501        display: flex;
502        flex: 1 1 auto;
503        min-width: 0;
504        justify-content: flex-start;
505        gap: 0;
506        overflow-x: auto;
507        overflow-y: hidden;
508        scrollbar-width: none;
509        -ms-overflow-style: none;
510        -webkit-overflow-scrolling: touch;
511        /* 右侧渐隐,提示还能往右滑 */
512        -webkit-mask-image: linear-gradient(90deg, #000 0, #000 88%, transparent 100%);
513        mask-image: linear-gradient(90deg, #000 0, #000 88%, transparent 100%);
514    }
515    .nav-menu::-webkit-scrollbar { display: none; }
516    .nav-menu > a, .nav-menu .nav-more-btn { padding: 9px 11px; font-size: .86rem; letter-spacing: .2px; }
517    .nav-menu > a::after, .nav-menu .nav-more-btn::after { left: 11px; right: 11px; }
518    .nav-right-group { flex: 0 0 auto; gap: 6px; }
519    .theme-btn { width: 38px; height: 38px; border-radius: 11px; font-size: 1rem; }
520    .nav-burger { flex: 0 0 auto; }
521    /* 下拉面板在手机上居中一点,避免贴边被裁 */
522    .nav-more-panel { right: auto; left: 0; }
523}
524@media (max-width: 420px) {
525    .nav-menu > a, .nav-menu .nav-more-btn { padding: 9px 9px; font-size: .82rem; }
526    .nav-logo .logo-img { height: 28px; }
527}
528
529/* ===== 移动端 / APP 适配增强 ===== */
530/* 1) 安全区:APP 全屏运行时,刘海屏/底部横条不再压住内容 */
531body {
532    padding-left: env(safe-area-inset-left, 0);
533    padding-right: env(safe-area-inset-right, 0);
534}
535.nav { padding-top: env(safe-area-inset-top, 0); }
536.footer { padding-bottom: calc(24px + env(safe-area-inset-bottom, 0px)); }
537.backtop { bottom: calc(18px + env(safe-area-inset-bottom, 0px)); }
538.drawer { padding-top: calc(18px + env(safe-area-inset-top, 0px)); padding-bottom: calc(18px + env(safe-area-inset-bottom, 0px)); }
539.nav-more-panel { max-height: 70vh; overflow-y: auto; }
540.d-modal, .modal-content, .cam-modal > div, .custom-modal > div {
541    max-height: 86vh; overflow-y: auto;
542}
543
544/* 2) 触摸体验 */
545a, button, [onclick], .sort-btn, .d-item {
546    -webkit-tap-highlight-color: transparent;
547    touch-action: manipulation;
548}
549html { -webkit-text-size-adjust: 100%; }
550
551/* 3) 手机上输入框字号统一 16px:
552      小于 16px 时 iOS/部分安卓 WebView 聚焦会自动放大整页(最常见的不适配感来源) */
553@media (max-width: 900px) {
554    input:not([type=checkbox]):not([type=radio]), textarea, select {
555        font-size: 16px !important;
556    }
557    /* 关键操作按钮的最小可点区域(不影响小图标按钮) */
558    button:not(.d-close):not(.nav-burger):not(.theme-btn):not(.backtop):not(.react-btn):not(.reply-btn):not(.edit-btn):not(.delete-btn):not(.report-btn):not(.sort-btn),
559    .btn, .hero-btn, .vhero-actions a {
560        min-height: 38px;
561    }
562    /* 表格:已有横向滚动容器的保持,没有的自动兜底 */
563    .table-wrap, .scroll-x, .stock-table-wrap { -webkit-overflow-scrolling: touch; }
564    /* 长文本防溢出 */
565    .comment-content, .bn-reason, .d-item, .pd-tip { word-break: break-word;
565 overflow-wrap: anywhere; }
566}
567
568/* 4) APP(独立窗口)下:去掉选中高亮与长按菜单的干扰,正文更接近原生 */
569@media (display-mode: standalone) {
570    a, button { -webkit-user-select: none; user-select: none; }
571    .comment-content { -webkit-user-select: text; user-select: text; }
572    .backtop { display: none; }   /* APP 里用系统返回键更自然 */
573}
574
575/* ===== 手机上「更多功能」下拉的处理 =====
576   原因:窄屏导航菜单是横向滚动的,而「更多功能」排在菜单最右端,
577        初始位置在屏幕外;且菜单的 overflow 会把弹出面板裁掉。
578   处理:手机上隐藏这个下拉(核心功能在 ☰ 抽屉里都有),平板/桌面保持可用。 */
579@media (max-width: 900px) {
580    .nav-more { display: none !important; }
581    .nav-more-panel { display: none !important; }
582}
583/* 平板/桌面:面板靠右弹出时留出边距,避免贴边 */
584@media (min-width: 901px) {
585    .nav-more-panel { max-width: calc(100vw - 24px); }
586}
587
588
589/* ===== 评论富文本:粗体 / 斜体 / 行内代码(不动链接颜色) ===== */
590.comment-content b, .comment-content strong { font-weight: 800; }
591.comment-content i, .comment-content em { font-style: italic; opacity: .95; }
592.comment-content code {
593    padding: 1px 6px; border-radius: 6px;
594    background: rgba(120,120,120,.14);
595    font-family: ui-monospace, Consolas, monospace; font-size: .92em;
596}
597.md-tip { font-size: .74rem; color: var(--ink-soft, #5a6270); opacity: .7; margin-top: 6px; }
598.md-tip code { padding: 1px 4px; border-radius: 4px; background: rgba(120,120,120,.14); font-size: .95em; }
599</style>
600<link rel="manifest" href="/manifest.json">
601<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32.png">
602<link rel="apple-touch-icon" sizes="180x180" href="/images/app-icon-180.png">
603<meta name="apple-mobile-web-app-capable" content="yes">
604<meta name="mobile-web-app-capable" content="yes">
605<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
606<meta name="apple-mobile-web-app-title" content="NB频道">
607<meta name="application-name" content="NB频道">
608<!-- nb-theme: 主题包(国庆 / 科技)—— 必须在页面样式之后加载 -->
609<link rel="stylesheet" href="../css/themes.css?v=35">
610<script src="../js/theme.js?v=9"></script>
610
611</head>
612<body>
613
614<!-- 导航 -->
615<nav class="nav">
616    <a class="nav-logo" href="index-Beta.html"><img class="logo-img" src="/images/NB频道LOGO.png" alt="NB频道"></a>
617    <div class="nav-menu">
618        <a href="index-Beta.html">首页</a>
619        <a href="videos-Beta.html">视频</a>
620        <a href="about-Beta.html">关于</a>
621        <a href="rules-Beta.html">用户守则</a>
622        <a href="changelog-Beta.html">更新日志</a>
623        <a href="product-Beta.html" class="active">我的产品</a>
624        <a href="APP-Beta.html">软件/APP</a>
625        <a href="index-Beta.html#friends">友商</a>
626        <a class="nav-api" href="/api-sdk/" target="_blank" rel="noopener noreferrer" title="NB频道 API 文档">API<i>↗</i></a>
627        <div class="nav-more">
628            <button class="nav-more-btn" type="button">更多功能 ▾</button>
629            <div class="nav-more-panel">
630                <a href="stock-Beta.html">📈 虚拟股票</a>
631                <a href="messages-Beta.html">🔔 消息中心</a>
632                <a href="chat-Beta.html">👥 好友 / 私信</a>
633                <a href="bank-Beta.html">🏦 NB银行</a>
634                <a href="shop-Beta.html">🛍️ NB商店</a>
635                <a href="backpack-Beta.html">🎒 我的背包</a>
636                <a href="titles-Beta.html">🏅 称号大全</a>
637                <a href="achievements-Beta.html">🏆 成就墙</a>
638                <a href="lottery-Beta.html">📅 签到 · 转盘</a>
639                <a href="lottery_records-Beta.html">🎰 抽奖记录</a>
640                <a href="tools-Beta.html">🔧 工具</a>
641                <a href="product_share-Beta.html">📦 作品分享</a>
642                <a href="comments-Beta.html">💬 评论区</a>
643                <a href="ban-Beta.html">🚫 小黑屋</a>
644                <a href="feedback-Beta.html">🐞 漏洞/建议反馈</a>
645                <a href="vote-Beta.html">🗳️ 投票中心</a>
646            </div>
647        </div>
648    </div>
649    <div class="nav-right-group">
650        <div class="nav-clock" id="navClock" title="北京时间(UTC+8)">
651            <span class="nc-time" id="bjTime">--:--:--</span>
652            <span class="nc-row"><i class="nc-date" id="bjDate">----.--.--</i><em class="nc-label">北京时间</em></span>
653        </div>
654        <button class="theme-btn" id="themeBtn" aria-label="切换夜间模式">🌙</button>
655        <div class="nav-auth-group" id="betaAuthGroup">
656            <a class="nav-auth" id="betaProfileBtn" href="#">👤 个人中心</a>
657            <a class="nav-auth primary" id="betaAuthBtn" href="#">登录 / 注册</a>
658        </div>
659    </div>
660    <button class="nav-burger" id="navBurger" aria-label="打开菜单">☰</button>
661    <!-- 扫码:手机端右上角,在汉堡(☰)的右边。只在 APP 里显示 —— 网页端调不动摄像头。
662         整段自包含(自带样式/脚本),不依赖本页既有的 CSS 变量和导航结构。 -->
663    <a class="nav-scan" id="navScanBtn" href="scan-Beta.html" aria-label="扫一扫" title="扫一扫"><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 8.5V6a3 3 0 0 1 3-3h2.5"/><path d="M15.5 3H18a3 3 0 0 1 3 3v2.5"/><path d="M21 15.5V18a3 3 0 0 1-3 3h-2.5"/><path d="M8.5 21H6a3 3 0 0 1-3-3v-2.5"/><path d="M3.2 12h17.6"/></svg></a>
664    <style>
665      .nav-scan{display:none;width:42px;height:42px;border-radius:12px;cursor:pointer;background:rgba(255,255,255,.7);border:1px solid var(--line,#e2e8f0);color:var(--ink,#0f172a);align-items:center;justify-content:center;text-decoration:none;-webkit-tap-highlight-color:transparent}
666      .nav-scan svg{width:21px;height:21px;display:block}
667      .nav-scan:hover{border-color:rgba(59,130,246,.5);color:var(--brand,#3b82f6)}
668      html.dark .nav-scan{background:rgba(255,255,255,.06);border-color:rgba(148,163,184,.25);color:var(--ink,#e2e8f0)}
669      @media (max-width:900px){.nav-scan{display:flex}}
670    </style>
671    
671<script>/* 扫码入口只在 APP 里显示。旧版 APP 也显示 —— 点进去 scan-Beta.html 会提示他更新 */
672    (function(){try{if(!/NBChannelApp/i.test(navigator.userAgent||"")){var b=document.getElementById("navScanBtn");if(b)b.style.display="none";}}catch(e){}})();</script>
672
673
674</nav>
675<script>
676// ===== 在 APP 里隐藏导航菜单的 emoji =====
677// 站长要求:APP 的「更多功能」下拉菜单不要 emoji,网页端保留原样。
678//
679// APP 是 Capacitor 套壳,加载的就是本站 —— 改 HTML 会两边一起改,
680// 所以只能按 UA 区分(APP 在 UA 里注入了 NBChannelApp)。
681// 判断写法与上面「扫一扫」那段保持一致。
682(function () {
683    var isApp = false;
684    try { isApp = /NBChannelApp/i.test(navigator.userAgent || ''); } catch (e) {}
685    if (!isApp) return;              // 浏览器里 —— emoji 保持原样
686
687    // 代理对(U+1F000 以上)+ BMP 符号区 + 变体选择符 + 零宽连接符,连同后面的空格一起剥掉
688    var LEAD = /^(?:[\u2190-\u21FF\u2300-\u23FF\u2600-\u27BF\u2B00-\u2BFF\uFE0F\u200D]|[\uD83C-\uDBFF][\uDC00-\uDFFF])+\s*/;
689
690    function strip() {
691        try {
692            var as = document.querySelectorAll('.nav-more-panel a, .drawer a');
693            // ⚠️ 桌面下拉(.nav-more-panel)在手机上被 CSS 藏了,手机走的是
694            //    汉堡抽屉(.drawer)。两个都要处理,否则 APP 里会漏。
695            for (var i = 0; i < as.length; i++) {
696                var t = as[i].textContent || '';
697                var n = t.replace(LEAD, '');
698                if (n !== t) as[i].textContent = n;
699            }
700        } catch (e) {}
701    }
702    strip();
703    setTimeout(strip, 400);    // 导航若是后渲染的,补两次
704    setTimeout(strip, 1500);
705})();
706
707// ===== 导航「更多功能」下拉 =====
708(function () {
709    var box = document.querySelector('.nav-more');
710    if (!box) return;
711    var btn = box.querySelector('.nav-more-btn');
712    btn.addEventListener('click', function (e) { e.stopPropagation(); box.classList.toggle('open'); });
713    document.addEventListener('click', function () { box.classList.remove('open'); });
714    document.addEventListener('keydown', function (e) { if (e.key === 'Escape') box.classList.remove('open'); });
715    var here = (location.pathname.split('/').pop() || '').toLowerCase();
716    if (here && box.querySelector('.nav-more-panel a[href="' + here + '"]')) btn.classList.add('active');
717})();
718</script>
718
719
720
721<!-- Hero -->
722<header class="vhero">
723    <div class="vhero-inner">
724        <div class="hero-copy">
725            <span class="hero-eyebrow">PRODUCTS · FROM THE LAB</span>
726            <h1>我的<span class="light">产品</span></h1>
727            <p class="vhero-sub">把化学做成可以玩的东西——四种溶液系列互动产品,均可在 NoBook 平台在线体验,也可下载研究</p>
728            <div class="vhero-actions">
729                <a class="hero-link" href="#products">开始体验 ↓</a>
730                <a class="hero-link" href="videos-Beta.html?cat=产品">产品视频档案 ↗</a>
731            </div>
732        </div>
733        <div class="pd-stats">
734            <div class="pd-row"><span class="k">在售产品</span><b>4 款</b></div>
735            <div class="pd-row"><span class="k">体验平台</span><b>NoBook <small>s.nobook.com</small></b></div>
736            <div class="pd-row"><span class="k">下载通道</span><b>蓝奏云</b></div>
737            <div class="pd-row"><span class="k">演示视频</span><b>B站 · 产品合集</b></div>
738            <div class="pd-tip">全部为虚拟互动产品</div>
739        </div>
740    </div>
741    <div class="vhero-fade"></div>
742</header>
743
744<!-- 产品 -->
745<!-- 全站公告(与首页一致;admin_config key=announcement) -->
746<div class="beta-announce" id="betaAnnounce" style="display:none;">
747    <div class="ba-title">公告</div>
748    <div class="ba-track-wrap"><div class="ba-track" id="baTrack"></div></div>
749</div>
750<main class="vwrap" id="products">
751    <section class="leadq reveal">
752        <h2>化学不只是<em>看</em>的<br><span class="thin">还可以上手玩</span></h2>
753        <p class="sig">—— <b>NB搞事局</b> · 溶液系列产品部</p>
754    </section>
755
756    <div class="pd-grid">
757        <article class="p-card reveal">
758            <div class="p-media"><span class="p-no">01 · SOLUTION</span><img loading="lazy" decoding="async" src="https://s41.ax1x.com/2026/02/20/pZXtHZn.png" alt="镀铜液" onerror="this.style.display='none'"></div>
759            <div class="p-body">
760                <h3>镀铜液</h3>
761                <p class="p-sub">4-5 秒,给铁钉镀上一层铜——最快见效的入门产品</p>
762                <div class="p-links">
763                    <a class="p-link go" href="https://s.nobook.com/index.html#/?id=382924" target="_blank" rel="noopener noreferrer">在线体验 ↗</a>
764                    <a class="p-link" href="https://www.bilibili.com/video/BV1HMZYBuEze" target="_blank" rel="noopener noreferrer">演示视频</a>
765                    <a class="p-link" href="https://wwbgs.lanzouq.com/iQaC43vr24ng" target="_blank" rel="noopener noreferrer">文件下载</a>
766                </div>
767            </div>
768        </article>
769
770        <article class="p-card reveal">
771            <div class="p-media"><span class="p-no">02 · SOLUTION</span><img loading="lazy" decoding="async" src="https://s41.ax1x.com/2026/02/24/pZvM2Pe.png" alt="炸不了溶液" onerror="this.style.display='none'"></div>
772            <div class="p-body">
773                <h3>炸不了溶液</h3>
774                <p class="p-sub">无论怎么加钠、钾、钙,都炸不了——实验室的安全感来源</p>
775                <div class="p-links">
776                    <a class="p-link go" href="https://s.nobook.com/index.html#/?id=382926" target="_blank" rel="noopener noreferrer">在线体验 ↗</a>
777                    <a class="p-link" href="https://www.bilibili.com/video/BV1ekfBB5EcZ" target="_blank" rel="noopener noreferrer">演示视频</a>
778                    <a class="p-link" href="https://wwbgs.lanzouq.com/icG353vr4jsd" target="_blank" rel="noopener noreferrer">文件下载</a>
779                </div>
780            </div>
781        </article>
782
783        <article class="p-card reveal">
784            <div class="p-media"><span class="p-no">03 · SOLUTION</span><img loading="lazy" decoding="async" src="https://s41.ax1x.com/2026/07/12/pmsf70f.png" alt="化钉液" onerror="this.style.display='none'"></div>
785            <div class="p-body">
786                <h3>化钉液</h3>
787                <p class="p-sub">把铁钉化掉——比镀铜更进一步的溶蚀之力</p>
788                <div class="p-links">
789                    <a class="p-link go" href="https://s.nobook.com/index.html#/?id=383645" target="_blank" rel="noopener noreferrer">在线体验 ↗</a>
790                    <a class="p-link" href="https://www.bilibili.com/video/BV1diNT6bE2R" target="_blank" rel="noopener noreferrer">演示视频</a>
791                    <a class="p-link" href="https://wwbgs.lanzouq.com/iDA933w08cmd" target="_blank" rel="noopener noreferrer">文件下载</a>
792                </div>
793            </div>
794        </article>
795
796        <article class="p-card reveal">
797            <div class="p-media"><span class="p-no">04 · SOLUTION</span>
797<img loading="lazy" decoding="async" src="https://s41.ax1x.com/2026/07/25/pm2Ixc8.png" alt="炸弹" onerror="this.style.display='none'"></div>
798            <div class="p-body">
799                <h3>炸弹</h3>
800                <p class="p-sub">五种极易爆炸的炸弹,拿去炸别人吧——当然,全都在屏幕里</p>
801                <div class="p-links">
802                    <a class="p-link go" href="https://s.nobook.com/index.html#/?id=388218" target="_blank" rel="noopener noreferrer">在线体验 ↗</a>
803                    <a class="p-link" href="https://www.bilibili.com/video/BV1zJ376kENb" target="_blank" rel="noopener noreferrer">演示视频</a>
804                    <a class="p-link" href="https://wwbgs.lanzouq.com/irohS3ymdf1e" target="_blank" rel="noopener noreferrer">文件下载</a>
805                </div>
806            </div>
807        </article>
808    </div>
809
810    <p class="p-note reveal">以上均为 NoBook 平台的虚拟互动产品,与真实化学品无关<br>演示视频见 B站《产品》合集 · 文件下载走蓝奏云,图片加载慢时刷新即可</p>
811</main>
812
813<!-- CTA -->
814<div class="cta">
815    <h2>先把这瓶 01 号镀铜液端上来</h2>
816    <p>更多溶液正在配方中——或去评论区点菜</p>
817    <div class="cta-actions">
818        <a class="hero-link" href="https://s.nobook.com/index.html#/?id=382924" target="_blank" rel="noopener noreferrer">体验镀铜液 ↗</a>
819        <a class="hero-link" href="videos-Beta.html?cat=产品">产品视频档案 ↓</a>
820        <a class="hero-link" href="comments-Beta.html">评论区报到 ↓</a>
821    </div>
822</div>
823
824<!-- 页脚 -->
825<footer class="footer">
826    <div class="footer-grid">
827        <div>
828            <div class="brand"><img class="logo-img" src="/images/NB频道LOGO.png" alt="NB频道"><span class="logo-text">NB频道</span></div>
829            <p class="desc">NB频道(NoBook频道)——热爱理科(和作死)的 UP主建立的虚拟公司。化学物理实验、日常作死、虚拟经济,一个有趣的数字世界</p>
830        </div>
831        <div>
832            <h5>功能</h5>
833            <a href="stock-Beta.html">虚拟股票</a><a href="bank-Beta.html">NB银行</a><a href="comments-Beta.html">评论区</a><a href="shop-Beta.html">NB商店</a><a href="tools-Beta.html">工具</a><a href="titles-Beta.html">称号系统</a><a href="feedback-Beta.html">漏洞/建议反馈</a>
834        </div>
835        <div>
836            <h5>友商</h5>
837            <a href="https://orgent.pythonanywhere.com/" target="_blank" rel="noopener noreferrer">Orgent(已注销)</a>
838            <a href="https://45d.cn/AWM/" target="_blank" rel="noopener noreferrer">AWM</a>
839            <a href="https://fafat.uuk.pp.ua/" target="_blank" rel="noopener noreferrer">Fafat</a>
840            <a href="https://nb-qx.top/" target="_blank" rel="noopener noreferrer">Lemon(齐喜)</a>
841            <a href="https://gaohantu.cn/" target="_blank" rel="noopener noreferrer">GaoHanTu</a>
842            <a href="https://utw.pages.dev" target="_blank" rel="noopener noreferrer">Utw</a>
843            <a href="https://pipetrainingcamp.github.io/" target="_blank" rel="noopener noreferrer">PTC(GoodPTC)</a>
844            <a href="https://yoyo-user-awa.github.io/UVS/" target="_blank" rel="noopener noreferrer">UVS</a>
845            <a href="https://3f7ceb4e.pinit.eth.limo/" target="_blank" rel="noopener noreferrer">UwLS</a>
846            <a href="https://45d.cn/nb-og.top/" target="_blank" rel="noopener noreferrer">Oganesson</a>
847            <a href="https://78439049.pinit.eth.limo/" target="_blank" rel="noopener noreferrer">SOT</a>
848        </div>
849        <div>
850            <h5>联系</h5>
851            <a href="/cdn-cgi/l/email-protection#3d535f5e555c535358517d0c0b0e135e5250"><span class="__cf_email__" data-cfemail="2c424e4f444d424249406c1d1a1f024f4341">[email&#160;protected]</span></a><a href="https://space.bilibili.com/3493259582114264" target="_blank" rel="noopener noreferrer">B站:NB搞事局</a><a href="https://nb-channel.top" target="_blank" rel="noopener noreferrer">nb-channel.top</a>
852        </div>
853    </div>
854    <div class="footer-bottom">© 2026 NB频道 · 虚拟公司 · 制作:NB搞事局 · 由 GitHub Pages / Cloudflare / PythonAnywhere 提供支持</div><div style="margin-top:8px;font-size:0.78rem;opacity:.72;line-height:1.9;">
854本站所有内容(页面代码 · 图文 · 数据)版权归 <b>NB频道</b> 所有,未经书面授权禁止复制、镜像或部署到其他域名</div>
855</footer>
856
857<!-- 移动端抽屉 -->
858<div class="drawer-mask" id="drawerMask"></div>
859<aside class="drawer" id="drawer">
860    <div class="d-head">
861        <span class="d-brand"><img class="logo-img" src="/images/NB频道LOGO.png" alt="NB频道"><span class="logo-text">NB频道</span></span>
862        <button class="d-close" id="drawerClose" aria-label="关闭菜单">✕</button>
863    </div>
864        <a class="d-item" href="vote-Beta.html">投票中心</a>
865        <a class="d-item" href="stock-Beta.html">虚拟股票</a>
866        <a class="d-item" href="messages-Beta.html">消息中心</a>
867        <a class="d-item" href="chat-Beta.html">好友 / 私信</a>
868        <a class="d-item" href="bank-Beta.html">NB银行</a>
869        <a class="d-item" href="shop-Beta.html">NB商店</a>
870        <a class="d-item" href="backpack-Beta.html">我的背包</a>
871        <a class="d-item" href="titles-Beta.html">称号大全</a>
872        <a class="d-item" href="achievements-Beta.html">成就墙</a>
873        <a class="d-item" href="lottery-Beta.html">签到 · 转盘</a>
874        <a class="d-item" href="lottery_records-Beta.html">抽奖记录</a>
875        <a class="d-item" href="tools-Beta.html">工具</a>
876        <a class="d-item" href="product_share-Beta.html">作品分享</a>
877        <a class="d-item" href="comments-Beta.html">评论区</a>
878        <a class="d-item" href="ban-Beta.html">小黑屋</a>
879        <a class="d-item" href="feedback-Beta.html">漏洞/建议反馈</a>
880    <div class="d-auth">
881        <a class="ga" id="dProfileBtn" href="#">个人中心</a>
882        <a class="gab" id="dAuthBtn" href="#">登录 / 注册</a>
883    </div>
884</aside>
885
886<!-- 回到顶部 -->
887<button class="backtop" id="backTop" aria-label="回到顶部">↑</button>
vendor: 110 bytes, lines 887-889
887
888
889<script data-cfasync="false" src="/cdn-cgi/scripts/5c5dd728/cloudflare-static/email-decode.min.js"></script>
889<script>
890    // ===== 入场渐显 =====
891    (function () {
892        var els = document.querySelectorAll('.reveal');
893        var io = new IntersectionObserver(function (es) {
894            es.forEach(function (e) {
895                if (e.isIntersecting) {
896                    var i = Array.prototype.indexOf.call(e.target.parentNode.children, e.target);
897                    e.target.style.transitionDelay = Math.min(i * 80, 300) + 'ms';
898                    e.target.classList.add('in');
899                    io.unobserve(e.target);
900                }
901            });
902        }, { threshold: 0.12 });
903        els.forEach(function (el, i) {
904            var r = el.getBoundingClientRect();
905            if (r.top < window.innerHeight * 0.9) { el.style.transitionDelay = (i * 90) + 'ms'; el.classList.add('in'); }
906            else io.observe(el);
907        });
908    })();
909
910    // ===== 登录区绑定(与全站一致) =====
911    function bindAuthPair(pbEl, abEl) {
912        if (!pbEl && !abEl) return;
913        var storedU = null;
914        try { storedU = JSON.parse(localStorage.getItem('nb_user')); } catch (e) {}
915        if (storedU && storedU.id) {
916            if (abEl) {
917                abEl.textContent = '登出账号';
918                abEl.onclick = function () { localStorage.removeItem('nb_user'); location.reload(); };
919            }
920            if (pbEl) {
921                pbEl.textContent = '👤 ' + (storedU.username || storedU.name || '个人中心');
922                pbEl.href = 'profile-Beta.html';
923            }
924        } else {
925            var loginHref = 'login-Beta.html?redirect=' + encodeURIComponent(location.href);
926            if (abEl) { abEl.href = loginHref; abEl.textContent = '登录 / 注册'; }
927            if (pbEl) { pbEl.href = loginHref; pbEl.textContent = '👤 个人中心'; }
928        }
929    }
930    bindAuthPair(document.getElementById('betaProfileBtn'), document.getElementById('betaAuthBtn'));
931    bindAuthPair(document.getElementById('dProfileBtn'), document.getElementById('dAuthBtn'));
932
933    // ===== 导航栏北京时间(与全站一致) =====
934    (function () {
935        var tEl = document.getElementById('bjTime');
936        var dEl = document.getElementById('bjDate');
937        if (!tEl) return;
938        var fmtT = new Intl.DateTimeFormat('zh-CN', {
939            timeZone: 'Asia/Shanghai', hour: '2-digit', minute: '2-digit',
940            second: '2-digit', hour12: false, hourCycle: 'h23'
941        });
942        var fmtD = new Intl.DateTimeFormat('zh-CN', {
943            timeZone: 'Asia/Shanghai', year: 'numeric', month: '2-digit',
944            day: '2-digit', weekday: 'short'
945        });
946        function tick() {
947            var now = new Date();
948            tEl.textContent = fmtT.format(now);
949            if (dEl) dEl.textContent = fmtD.format(now).replace(/\//g, '.');
950        }
951        tick();
952        setInterval(tick, 1000);
953    })();
954
955    // ===== 导航滚动态 + 回到顶部 =====
956    (function () {
957        var nav = document.querySelector('.nav');
958        var backTop = document.getElementById('backTop');
959        function onScroll() {
960            var y = window.scrollY || document.documentElement.scrollTop;
961            if (nav) nav.classList.toggle('scrolled', y > 10);
962            if (backTop) backTop.classList.toggle('show', y > 700);
963        }
964        window.addEventListener('scroll', onScroll, { passive: true });
965        onScroll();
966        if (backTop) backTop.addEventListener('click', function () { window.scrollTo({ top: 0, behavior: 'smooth' }); });
967    })();
968
969    // ===== 夜间模式切换 =====
970    (function () {
971        var btn = document.getElementById('themeBtn');
972        var root = document.documentElement;
973        function isDark() { return root.classList.contains('dark'); }
974        function render() {
975            if (btn) { btn.textContent = isDark() ? '☀️' : '🌙'; btn.title = isDark() ? '切换到日间模式' : '切换到夜间模式'; }
976        }
977        function apply(dark) {
978            root.classList.toggle('dark', dark);
979            try { localStorage.setItem('theme', dark ? 'dark' : 'light'); } catch (e) {}
980            render();
981        }
982        if (btn) btn.addEventListener('click', function () {
983            var dark = !isDark();
984            if (document.startViewTransition) {
985                try { document.startViewTransition(function () { apply(dark); }); } catch (e) { apply(dark); }
986            } else apply(dark);
987        });
988        render();
989    })();
990
991    // ===== 移动端抽屉 =====
992    (function () {
993        var burger = document.getElementById('navBurger');
994        var drawer = document.getElementById('drawer');
995        var mask = document.getElementById('drawerMask');
996        var closeBtn = document.getElementById('drawerClose');
997        if (!burger || !drawer || !mask) return;
998        function open() { drawer.classList.add('open'); mask.style.display = 'block'; document.body.classList.add('locked'); }
999        function close() { drawer.classList.remove('open'); mask.style.display = 'none'; document.body.classList.remove('locked'); }
1000        burger.addEventListener('click', open);
1001        closeBtn.addEventListener('click', close);
1002        mask.addEventListener('click', close);
1003        drawer.querySelectorAll('a').forEach(function (a) { a.addEventListener('click', close); });
1004    })();
1005
1006    // ===== 防查看代码(反调试,静默无提示) =====
1007    (function () {
1008        var DEV = window.__allowDevTools ||
1009                  /(?:^|[?&#])dev=1(?=&|#|$)/.test(location.href) ||
1010                  /#dev\b/.test(location.hash);
1011        if (DEV) return;
1012        document.addEventListener('keydown', function (e) {
1013            var k = e.keyCode || e.which;
1014            var ctrl = e.ctrlKey || e.metaKey;
1015            if (k === 123 || e.key === 'F12' ||
1016                (ctrl && e.shiftKey && (k === 73 || k === 74 || k === 67)) ||
1017                (ctrl && k === 85)) {
1018                e.preventDefault();
1019                e.stopPropagation();
1020                return false;
1021            }
1022        });
1023        document.addEventListener('contextmenu', function (e) { e.preventDefault(); return false; });
1024        setInterval(function () { debugger; }, 600);
1025    })();
1026</script>
vendor: 1 bytes, line 1026
1026
1027<script>
1028    // ===== 鼠标/触摸特效:跟随光晕 + 点击波纹与彩色粒子(鼠标 + 触屏都启用) =====
1029    (function () {
1030        var mqFine = window.matchMedia ? window.matchMedia('(pointer: fine)') : null;
1031        var isFine = !!(mqFine && mqFine.matches);
1032        var canTouch = ('ontouchstart' in window) ||
1033            !!(window.matchMedia && window.matchMedia('(pointer: coarse)').matches);
1034        var glow = document.createElement('div');
1035        glow.className = 'ui-fx-glow';
1036        document.body.appendChild(glow);
1037        var gx = -999, gy = -999, tx = -999, ty = -999;
1038        var colors = ['#3b82f6', '#8b5cf6', '#6366f1', '#06b6d4', '#f59e0b'];
1039        var lastTouch = 0, glowTimer = null;
1040
1041        // 光晕跟手:有精确指针(鼠标)就跟鼠标,否则跟手指
1042        if (isFine) {
1043            document.addEventListener('mousemove', function (e) { tx = e.clientX; ty = e.clientY; });
1044            document.addEventListener('mouseenter', function () { glow.style.opacity = '1'; });
1045            document.addEventListener('mouseleave', function () { glow.style.opacity = '0'; });
1046        }
1047        if (canTouch) {
1048            document.addEventListener('touchstart', function (e) {
1049                var t = e.touches[0]; if (!t) return;
1050                tx = t.clientX; ty = t.clientY;
1051                if (gx < -100) { gx = tx; gy = ty; }   // 首次别从屏幕角落滑过来
1052                glow.style.opacity = '1';
1053                if (glowTimer) { clearTimeout(glowTimer); glowTimer = null; }
1054                lastTouch = Date.now();
1055                burst(t.clientX, t.clientY, 6, 0.75);
1056            }, { passive: true });
1057            document.addEventListener('touchmove', function (e) {
1058                var t = e.touches[0]; if (!t) return;
1059                tx = t.clientX; ty = t.clientY;
1060                glow.style.opacity = '1';
1061            }, { passive: true });
1062            document.addEventListener('touchend', function () {
1063                if (glowTimer) clearTimeout(glowTimer);
1064                glowTimer = setTimeout(function () { glow.style.opacity = '0'; }, 380);
1065            }, { passive: true });
1066            document.addEventListener('touchcancel', function () { glow.style.opacity = '0'; }, { passive: true });
1067        }
1068
1069        var lx = -1e9, ly = -1e9;
1070        (function loop() {
1071            var k = isFine ? 0.14 : 0.32;   // 手指跟得紧一些
1072            gx += (tx - gx) * k;
1073            gy += (ty - gy) * k;
1074            // 静止时跳过写入:避免每帧重复改 style 白白触发样式计算
1075            if (Math.abs(gx - lx) > 0.2 || Math.abs(gy - ly) > 0.2) {
1076                glow.style.left = gx + 'px';
1077                glow.style.top = gy + 'px';
1078                lx = gx; ly = gy;
1079            }
1080            requestAnimationFrame(loop);
1081        })();
1082
1083        // ===== 点击波纹 + 彩色粒子 =====
1084        function burst(x, y, count, scale) {
1085            var ring = document.createElement('div');
1086            ring.style.cssText = 'position:fixed; left:' + x + 'px; top:' + y + 'px; width:12px; height:12px; border:2px solid rgba(59,130,246,.75); border-radius:50%; pointer-events:none; z-index:9999; transform:translate(-50%,-50%);';
1087            document.body.appendChild(ring);
1088            setTimeout(function () { if (ring.parentNode) ring.remove(); }, 900);
1089            try {
1090                ring.animate([
1091                    { transform: 'translate(-50%,-50%) scale(1)', opacity: 0.9 },
1092                    { transform: 'translate(-50%,-50%) scale(' + (5.5 * scale) + ')', opacity: 0 }
1093                ], { duration: 600, easing: 'ease-out', fill: 'forwards' });
1094            } catch (err) { ring.remove(); }
1095            for (var i = 0; i < count; i++) {
1096                var p = document.createElement('div');
1097                var size = 4 + Math.random() * 6;
1098                var ang = Math.random() * Math.PI * 2;
1099                var dist = (28 + Math.random() * 52) * scale;
1100                p.style.cssText = 'position:fixed; left:' + x + 'px; top:' + y + 'px; width:' + size + 'px; height:' + size + 'px; border-radius:50%; background:' + colors[i % colors.length] + '; pointer-events:none; z-index:9999;';
1101                document.body.appendChild(p);
1102                var dx = Math.cos(ang) * dist, dy = Math.sin(ang) * dist;
1103                var dur = 500 + Math.random() * 250;
1104                setTimeout(function (el) {
1105                    return function () { if (el.parentNode) el.remove(); };
1106                }(p), dur + 250);
1107                try {
1108                    p.animate([
1109                        { transform: 'translate(0,0) scale(1)', opacity: 1 },
1110                        { transform: 'translate(' + dx + 'px,' + dy + 'px) scale(0.1)', opacity: 0 }
1111                    ], { duration: dur, easing: 'cubic-bezier(0.15,0.8,0.25,1)', fill: 'forwards' });
1112                } catch (err) { p.remove(); }
1113            }
1114        }
1115        // 鼠标点击
1116        document.addEventListener('click', function (e) {
1117            if (Date.now() - lastTouch < 800) return;   // 触摸后浏览器会补发 click,去重
1118            burst(e.clientX, e.clientY, 8, 1);
1119        });
1120    })();
1121</script>
vendor: 1 bytes, line 1121
1121
1122<script>
1123    // ===== 全站公告条:supabase REST 单次拉取(无需加载 SDK),失败静默隐藏 =====
1124    (function () {
1125        var bar = document.getElementById('betaAnnounce');
1126        var track = document.getElementById('baTrack');
1127        if (!bar || !track) return;
1128        function esc(s) {
1129            return String(s).replace(/[&<>"']/g, function (m) {
1130                return { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' }[m];
1131            });
1132        }
1133        function linkify(s) {
1134            return s.replace(/(https?:\/\/[^\s<>"']+)/g, '<a href="$1" target="_blank" rel="noopener noreferrer" style="color:var(--brand); text-decoration:underline;">$1</a>');
1135        }
1136        fetch('https://pbaafgjkwdbwcmsikcmg.supabase.co/rest/v1/admin_config?select=value&key=eq.announcement', {
1137            headers: {
1138                'apikey': 'sb_publishable_tv7YVJEisnvs3hvU8ImYUw_b0p6bmRg',
1139                'Authorization': 'Bearer sb_publishable_tv7YVJEisnvs3hvU8ImYUw_b0p6bmRg'
1140            }
1141        })
1142        .then(function (r) { return r.ok ? r.json() : null; })
1143        .then(function (rows) {
1144            if (!rows || !rows.length) return;
1145            var raw = String(rows[0].value || '').trim();
1146            if (!raw) return;
1147            bar.style.display = 'flex';   // 先显示再测量(display:none 时 offsetWidth 恒为 0)
1148            var one = '<span class="ba-item">' + linkify(esc(raw)) + '</span>';
1149            track.innerHTML = one;
1150            var item = track.querySelector('.ba-item');
1151            var itemW = item ? item.offsetWidth : 0;
1152            if (itemW <= 0) return;
1153            var wrapEl = bar.querySelector('.ba-track-wrap');
1154            var barW = wrapEl ? wrapEl.clientWidth : 0;
1155            var copies = Math.max(2, Math.ceil(barW / itemW) + 1);
1156            var all = '';
1157            for (var ci = 0; ci < copies; ci++) all += '<span class="ba-item">' + linkify(esc(raw)) + '</span>';
1158            track.innerHTML = all;
1159            var dur = Math.max(8, itemW / 45);
1160            if (track.animate) {
1161                track.animate(
1162                    [{ transform: 'translateX(0)' }, { transform: 'translateX(-' + itemW + 'px)' }],
1163                    { duration: dur * 1000, iterations: Infinity, easing: 'linear' }
1164                );
1165            }
1166        })
1167        .catch(function () {});
1168    })();
1169</script>
1169
1170
1171<script>
1172    // ===== 安全强制重登:本地有用户信息但无会话令牌 => 视为未登录 =====
1173    (function () {
1174        try {
1175            var u = localStorage.getItem('nb_user');
1176            var s = localStorage.getItem('nb_session');
1177            if (u && !s) {
1178                localStorage.removeItem('nb_user');
1179                location.reload();
1180            }
1181        } catch (e) {}
1182    })();
1183</script>
1183
1184
1185
1186<script>
1187// ===== APP 自更新(仅 APP 内生效) =====
1188(function () {
1189    var ua = navigator.userAgent || '';
1190    var m = /NBChannelApp\/([0-9.]+)/i.exec(ua);
1191    if (!m) return;                       // 不是 APP 环境,不打扰网页用户
1192    var localVer = m[1];
1193    var APK = '/download/NBChannel.apk';
1194
1195    function cmp(a, b) {
1196        var x = String(a).split('.').map(Number), y = String(b).split('.').map(Number);
1197        for (var i = 0; i < 3; i++) { var p = x[i] || 0, q = y[i] || 0; if (p !== q) return p - q; }
1198        return 0;
1199    }
1200
1201    var checking = false;
1202    function check(manual) {
1203        if (checking) return;
1204        checking = true;
1205        fetch('/download/version.json?t=' + Date.now(), { cache: 'no-store' })
1206            .then(function (r) { if (!r.ok) throw new Error('HTTP ' + r.status); return r.json(); })
1207            .then(function (info) {
1208                checking = false;
1209                if (!info || !info.versionName) throw new Error('版本信息不完整');
1210                if (cmp(info.versionName, localVer) > 0) showBar(info, manual);
1211                else if (manual) toast('✅ 已是最新版 v' + localVer);
1212            })
1213            .catch(function (e) {
1214                checking = false;
1215                if (manual) toast('检查更新失败:' + e.message + '\n请检查网络后重试');
1216            });
1217    }
1218
1219    // ---- 底部更新条 ----
1220    function showBar(info, manual) {
1221        if (document.getElementById('nbUpdateBar')) return;
1222        var bar = document.createElement('div');
1223        bar.id = 'nbUpdateBar';
1224        bar.style.cssText = 'position:fixed;left:0;right:0;bottom:0;z-index:99999;' +
1225            'padding:14px 16px calc(14px + env(safe-area-inset-bottom,0px));' +
1226            'background:linear-gradient(135deg,#3b82f6,#6366f1);color:#fff;' +
1227            'display:flex;align-items:center;gap:10px;font-size:.86rem;' +
1228            'box-shadow:0 -8px 28px rgba(0,0,0,.3);';
1229        bar.innerHTML =
1230            '<div style="flex:1;line-height:1.6;min-width:0;">
1230' +
1231                '<b>发现新版本 v' + info.versionName + '</b><br>' +
1232                '<span style="opacity:.9;font-size:.78rem;">当前 v' + localVer + ' · ' +
1233                (info.note || '修复与优化') + '</span>' +
1234            '</div>' +
1235            '<button id="nbUpdGo" style="background:#fff;color:#3b82f6;border:none;border-radius:999px;' +
1236                'padding:9px 18px;font-weight:800;font-family:inherit;font-size:.86rem;cursor:pointer;white-space:nowrap;">立即更新</button>' +
1237            '<button id="nbUpdNo" style="background:transparent;border:none;color:#fff;opacity:.75;' +
1238                'font-size:1.05rem;cursor:pointer;padding:4px 6px;">✕</button>';
1239        document.body.appendChild(bar);
1240        document.getElementById('nbUpdNo').onclick = function () { bar.remove(); };
1241        document.getElementById('nbUpdGo').onclick = function () {
1242            var b = this;
1243            b.textContent = '下载中…'; b.disabled = true; b.style.opacity = '.8';
1244            location.href = info.url || APK;
1245            setTimeout(function () { b.textContent = '立即更新'; b.disabled = false; b.style.opacity = '1'; }, 12000);
1246        };
1247    }
1248
1249    // ---- 轻提示 ----
1250    function toast(msg) {
1251        var t = document.createElement('div');
1252        t.style.cssText = 'position:fixed;left:50%;top:50%;transform:translate(-50%,-50%);z-index:99999;' +
1253            'background:rgba(15,23,42,.94);color:#fff;padding:14px 20px;border-radius:14px;' +
1254            'font-size:.86rem;line-height:1.7;max-width:80vw;text-align:center;white-space:pre-line;' +
1255            'box-shadow:0 12px 36px rgba(0,0,0,.4);';
1256        t.textContent = msg;
1257        document.body.appendChild(t);
1258        setTimeout(function () { t.remove(); }, 2600);
1259    }
1260
1261    // ---- 在导航「更多功能」下拉 + 手机抽屉里注入入口 ----
1262    function inject() {
1263        var panel = document.querySelector('.nav-more-panel');
1264        if (panel && !panel.querySelector('[data-nb-upd]')) {
1265            var a = document.createElement('a');
1266            a.href = 'javascript:void(0)';
1267            a.setAttribute('data-nb-upd', '1');
1268            a.textContent = '🔄 检查更新';
1269            a.addEventListener('click', function (e) {
1270                e.preventDefault();
1271                var more = document.querySelector('.nav-more');
1272                if (more) more.classList.remove('open');
1273                check(true);
1274            });
1275            panel.insertBefore(a, panel.firstChild);
1276        }
1277        var authBox = document.querySelector('.drawer .d-auth');
1278        if (authBox && !document.querySelector('[data-nb-upd-d]')) {
1279            var d = document.createElement('a');
1280            d.className = 'd-item';
1281            d.href = 'javascript:void(0)';
1282            d.setAttribute('data-nb-upd-d', '1');
1283            d.textContent = '🔄 检查更新(v' + localVer + ')';
1284            d.addEventListener('click', function (e) { e.preventDefault(); check(true); });
1285            authBox.parentNode.insertBefore(d, authBox);
1286        }
1287    }
1288
1289    if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', inject);
1290    else inject();
1291    setTimeout(inject, 1200);      // 兜底:导航是脚本渲染时再试一次
1292
1293    // 启动自动查一次,之后每 30 分钟
1294    setTimeout(function () { check(false); }, 2000);
1295    setInterval(function () { check(false); }, 30 * 60 * 1000);
1296})();
1297</script>
1297
1298
1299<script>
1300/* ===== Android 上让 B站链接优先打开 B站 APP ===== */
1301(function () {
1302    try {
1303        if (!/Android/i.test(navigator.userAgent)) return;   // 只在安卓上改,桌面/iPhone 保持原样
1304        function toIntent(href) {
1305            var m = href.match(/space\.bilibili\.com\/(\d+)/);
1306            if (!m) return null;
1307            // intent:// 是安卓专属协议:能打开 APP 就打开,打不开就回退到 browser_fallback_url
1308            return 'intent://space/' + m[1] + '#Intent;scheme=bilibili;package=tv.danmaku.bili' +
1309                   ';S.browser_fallback_url=' + encodeURIComponent(href) + ';end';
1310        }
1311        function patch() {
1312            var links = document.querySelectorAll('a[href*="space.bilibili.com"]');
1313            for (var i = 0; i < links.length; i++) {
1314                var a = links[i];
1315                if (a.dataset.nbIntent) continue;
1316                var it = toIntent(a.getAttribute('href') || a.href);
1317                if (it) { a.setAttribute('href', it); a.dataset.nbIntent = '1'; }
1318            }
1319        }
1320        if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', patch);
1321        else patch();
1322        setTimeout(patch, 1500);
1323    } catch (e) {}
1324})();
1325
1326/* ===== 双击视频铺满屏幕 ===== */
1327(function () {
1328    try {
1329        var style = document.createElement('style');
1330        style.textContent =
1331            'video.nb-fs{position:fixed!important;left:0!important;top:0!important;' +
1332            'width:100vw!important;height:100vh!important;max-width:100vw!important;' +
1333            'max-height:100vh!important;margin:0!important;border-radius:0!important;' +
1334            'z-index:99999!important;background:#000!important;object-fit:contain!important;}' +
1335            'body.nb-fs-lock{overflow:hidden!important;}';
1336        document.head.appendChild(style);
1337
1338        var current = null;
1339        function exit() {
1340            if (!current) return;
1341            current.classList.remove('nb-fs');
1342            document.body.classList.remove('nb-fs-lock');
1343            current = null;
1344        }
1345        function enter(v) {
1346            exit();
1347            v.classList.add('nb-fs');
1348            document.body.classList.add('nb-fs-lock');
1349            current = v;
1350            try { v.play(); } catch (e) {}
1351        }
1352        // 双击:进/出全屏
1353        document.addEventListener('dblclick', function (e) {
1354            var v = e.target && e.target.closest ? e.target.closest('video') : null;
1355            if (!v) return;
1356            e.preventDefault();
1357            if (current === v) exit(); else enter(v);
1358        }, true);
1359        // 全屏状态下点空白处/按 Esc 退出
1360        document.addEventListener('click', function (e) {
1361            if (current && !(e.target.closest && e.target.closest('video'))) exit();
1362        }, true);
1363        document.addEventListener('keydown', function (e) { if (e.key === 'Escape') exit(); });
1364        // 页面切换/尺寸变化时兜底
1365        window.addEventListener('resize', function () { if (current) exit(); });
1366    } catch (e) {}
1367})();
1368</script>
1368
1369
1370<!--
1371  ══════════════════════════════════════════════════════════════════
1372   NB-CHANNEL ORIGINAL · 本页面由 NB频道 原创制作
1373   构建指纹 NBC-20261001-F883C59469B6
1374   官方域名 nb-channel.top (github. / cloudflare. / edgeone. / pythonanywhere.)
1375   如果你在其他域名看到本页,说明该站点未经授权复制了 NB频道 的内容,
1376   欢迎举报:[email protected]
1377  ══════════════════════════════════════════════════════════════════
1378-->
1379
1380<script>/* 构建元信息(请勿删除,侵权取证用) */
1381(function () {
1382    try {
1383        var _nb = "TkJDLTIwMjYxMDAxLUY4ODNDNTk0NjlCNg";
1384        if (typeof window !== "undefined") window.__nbBuild = _nb;
1385    } catch (e) {}
1386})();
1387</script>
vendor: 1 bytes, line 1387
1387
1388<script defer src="../js/science-tips.js?v=26"></script>
vendor: 1 bytes, line 1388
1388
1389<script src="../js/pomodoro.js?v=7" defer></script>
vendor: 1 bytes, line 1389
1389
1390<script type="module" src="https://static.cloudflareinsights.com/beacon.min.js/v31edd6df95cf4e85bb4c19e7a9bdbcba1788362987495" integrity="sha512-iIg7k2xntmwu6/uSb5tpc/hySgZc4eoL31yB29W6tJFo2akwjPWcEqnCEdJvGexCL0KEQwVYv5BlowfhVz26hg==" data-cf-beacon='{"version":"2024.11.0","token":"2694d6c1b70c42ee8414dc6303584599","r":1,"spa":2}' crossorigin="anonymous"></script>
1390
1391</body>
1392</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.