@anglefeint/astro-theme 0.1.0-alpha.0 → 0.1.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,3 +1,12 @@
1
+ ---
2
+ doc_id: package_readme
3
+ doc_role: package-guide
4
+ doc_scope: [package-install, package-upgrade, package-usage]
5
+ update_triggers: [package-change, command-change, export-change]
6
+ source_of_truth: true
7
+ depends_on: [docs/PACKAGING_WORKFLOW.md, docs/PACKAGE_RELEASE.md]
8
+ ---
9
+
1
10
  # @anglefeint/astro-theme
2
11
 
3
12
  Core package for the Anglefeint Astro theme.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anglefeint/astro-theme",
3
- "version": "0.1.0-alpha.0",
3
+ "version": "0.1.0-alpha.2",
4
4
  "type": "module",
5
5
  "description": "Anglefeint core theme package for Astro",
6
6
  "license": "MIT",
@@ -1,7 +1,7 @@
1
1
  (function() {
2
2
  function init() {
3
3
  var runtimeConfig = {};
4
- var runtimeConfigEl = document.getElementById('term-runtime-config');
4
+ var runtimeConfigEl = document.getElementById('hacker-runtime-config');
5
5
  if (runtimeConfigEl && runtimeConfigEl.textContent) {
6
6
  try {
7
7
  runtimeConfig = JSON.parse(runtimeConfigEl.textContent);
@@ -10,7 +10,7 @@
10
10
  }
11
11
  }
12
12
  // ── Terminal background: dir + 可输入 (点击背景聚焦,回车仅换行) ──
13
- var bgCanvas = document.querySelector('.term-bg-canvas');
13
+ var bgCanvas = document.querySelector('.hacker-bg-canvas');
14
14
  if (bgCanvas) {
15
15
  var bgCtx = bgCanvas.getContext('2d');
16
16
  var fontSize = 13;
@@ -29,9 +29,9 @@
29
29
  var dirLines = runtimeConfig.effects && Array.isArray(runtimeConfig.effects.backgroundLines) && runtimeConfig.effects.backgroundLines.length > 0
30
30
  ? runtimeConfig.effects.backgroundLines
31
31
  : fallbackDirLines;
32
- var termFocused = false;
33
- var termInput = '';
34
- var termHistory = [];
32
+ var hackerFocused = false;
33
+ var hackerInput = '';
34
+ var hackerHistory = [];
35
35
 
36
36
  function sizeBackground() {
37
37
  var dpr = Math.min(window.devicePixelRatio || 1, 2);
@@ -75,23 +75,23 @@
75
75
  var promptY = baseY + dirLines.length * lineHeight + 10;
76
76
 
77
77
  // 用户输入历史 (回车产生的行)
78
- for (var i = 0; i < termHistory.length; i++) {
78
+ for (var i = 0; i < hackerHistory.length; i++) {
79
79
  bgCtx.fillStyle = 'rgba(255, 255, 255, 0.9)';
80
- bgCtx.fillText('~ $ ' + termHistory[i], padX, promptY + i * lineHeight);
80
+ bgCtx.fillText('~ $ ' + hackerHistory[i], padX, promptY + i * lineHeight);
81
81
  }
82
82
 
83
83
  // 当前行: prompt + 输入 + 光标
84
- var currentY = promptY + termHistory.length * lineHeight;
84
+ var currentY = promptY + hackerHistory.length * lineHeight;
85
85
  bgCtx.fillStyle = 'rgba(255, 255, 255, 0.9)';
86
86
  bgCtx.fillText('~ $ ', padX, currentY);
87
87
  var promptW = bgCtx.measureText('~ $ ').width;
88
- bgCtx.fillText(termInput, padX + promptW, currentY);
89
- var inputW = bgCtx.measureText(termInput).width;
88
+ bgCtx.fillText(hackerInput, padX + promptW, currentY);
89
+ var inputW = bgCtx.measureText(hackerInput).width;
90
90
  var blink = Math.floor(t / 530) % 2;
91
- if (blink && termFocused) {
91
+ if (blink && hackerFocused) {
92
92
  bgCtx.fillStyle = 'rgba(0, 255, 100, 0.9)';
93
93
  bgCtx.fillRect(padX + promptW + inputW, currentY - fontSize + 4, 8, fontSize - 2);
94
- } else if (!termFocused && blink) {
94
+ } else if (!hackerFocused && blink) {
95
95
  bgCtx.fillStyle = 'rgba(0, 255, 100, 0.9)';
96
96
  bgCtx.fillRect(padX + promptW + inputW, currentY - fontSize + 4, 8, fontSize - 2);
97
97
  }
@@ -122,31 +122,31 @@
122
122
  var header = document.querySelector('header');
123
123
  var footer = document.querySelector('footer');
124
124
  if (content && content.contains(e.target)) {
125
- termFocused = false;
125
+ hackerFocused = false;
126
126
  } else if (header && header.contains(e.target)) {
127
- termFocused = false;
127
+ hackerFocused = false;
128
128
  } else if (footer && footer.contains(e.target)) {
129
- termFocused = false;
130
- } else if (e.target.closest('.term-back-to-top, .term-regenerate')) {
131
- termFocused = false;
129
+ hackerFocused = false;
130
+ } else if (e.target.closest('.hacker-back-to-top, .hacker-regenerate')) {
131
+ hackerFocused = false;
132
132
  } else {
133
- termFocused = true;
133
+ hackerFocused = true;
134
134
  }
135
135
  });
136
136
 
137
137
  // 键盘输入 (仅当聚焦时)
138
138
  document.addEventListener('keydown', function(e) {
139
- if (!termFocused) return;
139
+ if (!hackerFocused) return;
140
140
  if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') return;
141
141
  e.preventDefault();
142
142
  if (e.key === 'Enter') {
143
- termHistory.push(termInput);
144
- termInput = '';
145
- if (termHistory.length > 8) termHistory.shift();
143
+ hackerHistory.push(hackerInput);
144
+ hackerInput = '';
145
+ if (hackerHistory.length > 8) hackerHistory.shift();
146
146
  } else if (e.key === 'Backspace') {
147
- termInput = termInput.slice(0, -1);
148
- } else if (e.key.length === 1 && !e.ctrlKey && !e.metaKey && !e.altKey && termInput.length < 80) {
149
- termInput += e.key;
147
+ hackerInput = hackerInput.slice(0, -1);
148
+ } else if (e.key.length === 1 && !e.ctrlKey && !e.metaKey && !e.altKey && hackerInput.length < 80) {
149
+ hackerInput += e.key;
150
150
  }
151
151
  });
152
152
 
@@ -156,8 +156,8 @@
156
156
  }
157
157
 
158
158
  // ── Progress bar + toasts + back-to-top ──
159
- var progress = document.querySelector('.term-progress');
160
- var toast = document.querySelector('.term-toast');
159
+ var progress = document.querySelector('.hacker-progress');
160
+ var toast = document.querySelector('.hacker-toast');
161
161
  var fallbackToasts = {
162
162
  p30: 'context parsed',
163
163
  p60: 'inference stable',
@@ -184,7 +184,7 @@
184
184
  var scrollHeight = document.documentElement.scrollHeight - window.innerHeight;
185
185
  var p = scrollHeight > 0 ? Math.min(1, scrollTop / scrollHeight) : 1;
186
186
  progress.style.setProperty('--read-progress', String(p));
187
- var btn = document.querySelector('.term-back-to-top');
187
+ var btn = document.querySelector('.hacker-back-to-top');
188
188
  if (btn) btn.classList.toggle('visible', scrollTop > 400);
189
189
  if (!hasScrolled && scrollTop > 6) hasScrolled = true;
190
190
  if (!hasScrolled) return;
@@ -204,7 +204,7 @@
204
204
  onScroll();
205
205
  window.addEventListener('scroll', onScroll, { passive: true });
206
206
  }
207
- var backTop = document.querySelector('.term-back-to-top');
207
+ var backTop = document.querySelector('.hacker-back-to-top');
208
208
  if (backTop) {
209
209
  backTop.addEventListener('click', function() {
210
210
  window.scrollTo({ top: 0, behavior: 'smooth' });
@@ -212,9 +212,9 @@
212
212
  }
213
213
 
214
214
  // ── 文件夹弹窗 ──
215
- var modalOverlay = document.getElementById('term-modal');
216
- var modalBody = document.getElementById('term-modal-body');
217
- var modalTitle = document.querySelector('.term-modal-title');
215
+ var modalOverlay = document.getElementById('hacker-modal');
216
+ var modalBody = document.getElementById('hacker-modal-body');
217
+ var modalTitle = document.querySelector('.hacker-modal-title');
218
218
  var decryptorKeysLabel = runtimeConfig.decryptorKeysLabel || 'keys tested';
219
219
  var decryptorInterval = null;
220
220
  function randHex() {
@@ -277,13 +277,13 @@
277
277
  ['Ctrl','Alt','Space','AltRight','CtrlRight']
278
278
  ];
279
279
  var codeMap = { '`':'Backquote','1':'Digit1','2':'Digit2','3':'Digit3','4':'Digit4','5':'Digit5','6':'Digit6','7':'Digit7','8':'Digit8','9':'Digit9','0':'Digit0','-':'Minus','=':'Equal','Backspace':'Backspace','Tab':'Tab','Q':'KeyQ','W':'KeyW','E':'KeyE','R':'KeyR','T':'KeyT','Y':'KeyY','U':'KeyU','I':'KeyI','O':'KeyO','P':'KeyP','[':'BracketLeft',']':'BracketRight','CapsLock':'CapsLock','A':'KeyA','S':'KeyS','D':'KeyD','F':'KeyF','G':'KeyG','H':'KeyH','J':'KeyJ','K':'KeyK','L':'KeyL',';':'Semicolon',"'":'Quote','Enter':'Enter','Shift':'ShiftLeft','ShiftRight':'ShiftRight','Z':'KeyZ','X':'KeyX','C':'KeyC','V':'KeyV','B':'KeyB','N':'KeyN','M':'KeyM',',':'Comma','.':'Period','/':'Slash','Ctrl':'ControlLeft','CtrlRight':'ControlRight','Alt':'AltLeft','AltRight':'AltRight','Space':'Space' };
280
- var html = '<div class="term-vkeyboard-wrap" id="help-keyboard">';
281
- html += '<div class="term-vkeyboard term-vkeyboard-main">';
280
+ var html = '<div class="hacker-vkeyboard-wrap" id="help-keyboard">';
281
+ html += '<div class="hacker-vkeyboard hacker-vkeyboard-main">';
282
282
  rows.forEach(function(row) {
283
- html += '<div class="term-vkeyboard-row">';
283
+ html += '<div class="hacker-vkeyboard-row">';
284
284
  row.forEach(function(k) {
285
285
  var code = codeMap[k] || k;
286
- var cls = 'term-vkey';
286
+ var cls = 'hacker-vkey';
287
287
  if (k === 'Tab' || k === 'CapsLock' || k === 'Enter') cls += ' wide';
288
288
  if (k === 'Space') cls += ' space';
289
289
  if (k === 'Backspace') cls += ' acc backspace';
@@ -293,30 +293,30 @@
293
293
  html += '</div>';
294
294
  });
295
295
  html += '</div>';
296
- html += '<div class="term-vkeyboard-side">';
297
- html += '<div class="term-vkeyboard-side-block">';
298
- html += '<div class="term-vkeyboard-side-row"><span class="term-vkey" data-code="Insert" data-key="Ins">Insert</span><span class="term-vkey nav-home" data-code="Home" data-key="Home">Home</span><span class="term-vkey" data-code="PageUp" data-key="PgUp">PgUp</span></div>';
299
- html += '<div class="term-vkeyboard-side-row"><span class="term-vkey" data-code="Delete" data-key="Del">Delete</span><span class="term-vkey nav-end" data-code="End" data-key="End">End</span><span class="term-vkey" data-code="PageDown" data-key="PgDn">PgDn</span></div>';
296
+ html += '<div class="hacker-vkeyboard-side">';
297
+ html += '<div class="hacker-vkeyboard-side-block">';
298
+ html += '<div class="hacker-vkeyboard-side-row"><span class="hacker-vkey" data-code="Insert" data-key="Ins">Insert</span><span class="hacker-vkey nav-home" data-code="Home" data-key="Home">Home</span><span class="hacker-vkey" data-code="PageUp" data-key="PgUp">PgUp</span></div>';
299
+ html += '<div class="hacker-vkeyboard-side-row"><span class="hacker-vkey" data-code="Delete" data-key="Del">Delete</span><span class="hacker-vkey nav-end" data-code="End" data-key="End">End</span><span class="hacker-vkey" data-code="PageDown" data-key="PgDn">PgDn</span></div>';
300
300
  html += '</div>';
301
- html += '<div class="term-vkeyboard-side-row"><span class="term-vkey" data-code="Purge" data-key="Purge">Purge</span></div>';
302
- html += '<div class="term-vkeyboard-arrows-wrap">';
303
- html += '<div class="term-vkeyboard-arrows">';
304
- html += '<span class="term-vkey arr-u" data-code="ArrowUp" data-key="↑">↑</span>';
305
- html += '<span class="term-vkey arr-l" data-code="ArrowLeft" data-key="←">←</span>';
306
- html += '<span class="term-vkey arr-r" data-code="ArrowRight" data-key="→">→</span>';
307
- html += '<span class="term-vkey arr-d" data-code="ArrowDown" data-key="↓">↓</span>';
301
+ html += '<div class="hacker-vkeyboard-side-row"><span class="hacker-vkey" data-code="Purge" data-key="Purge">Purge</span></div>';
302
+ html += '<div class="hacker-vkeyboard-arrows-wrap">';
303
+ html += '<div class="hacker-vkeyboard-arrows">';
304
+ html += '<span class="hacker-vkey arr-u" data-code="ArrowUp" data-key="↑">↑</span>';
305
+ html += '<span class="hacker-vkey arr-l" data-code="ArrowLeft" data-key="←">←</span>';
306
+ html += '<span class="hacker-vkey arr-r" data-code="ArrowRight" data-key="→">→</span>';
307
+ html += '<span class="hacker-vkey arr-d" data-code="ArrowDown" data-key="↓">↓</span>';
308
308
  html += '</div>';
309
309
  html += '</div></div></div>';
310
- html += '<div class="term-vkeyboard-stats"><span class="term-vkeyboard-stats-label">' + statsLabel + '</span><br>' + typedPrefix + ' <span id="help-char-count">0</span> ' + typedSuffix + '</div>';
310
+ html += '<div class="hacker-vkeyboard-stats"><span class="hacker-vkeyboard-stats-label">' + statsLabel + '</span><br>' + typedPrefix + ' <span id="help-char-count">0</span> ' + typedSuffix + '</div>';
311
311
  return html;
312
312
  }
313
313
  function highlightKey(code) {
314
314
  if (code === 'Escape') code = 'Backspace';
315
- var el = modalBody.querySelector('.term-vkey[data-code="' + code + '"]');
315
+ var el = modalBody.querySelector('.hacker-vkey[data-code="' + code + '"]');
316
316
  if (!el) {
317
- if (code === 'ShiftRight') el = modalBody.querySelector('.term-vkey[data-code="ShiftLeft"]');
318
- else if (code === 'ControlRight') el = modalBody.querySelector('.term-vkey[data-code="ControlLeft"]');
319
- else if (code === 'AltRight') el = modalBody.querySelector('.term-vkey[data-code="AltLeft"]');
317
+ if (code === 'ShiftRight') el = modalBody.querySelector('.hacker-vkey[data-code="ShiftLeft"]');
318
+ else if (code === 'ControlRight') el = modalBody.querySelector('.hacker-vkey[data-code="ControlLeft"]');
319
+ else if (code === 'AltRight') el = modalBody.querySelector('.hacker-vkey[data-code="AltLeft"]');
320
320
  }
321
321
  if (el) {
322
322
  el.classList.add('highlight');
@@ -327,7 +327,7 @@
327
327
  helpCharCount = 0;
328
328
  var charEl = document.getElementById('help-char-count');
329
329
  if (charEl) charEl.textContent = '0';
330
- modalBody.querySelectorAll('.term-vkey').forEach(function(k) {
330
+ modalBody.querySelectorAll('.hacker-vkey').forEach(function(k) {
331
331
  k.addEventListener('click', function() {
332
332
  var code = k.getAttribute('data-code');
333
333
  highlightKey(code);
@@ -346,7 +346,7 @@
346
346
  });
347
347
  }
348
348
  function handleHelpKeydown(e) {
349
- if (!modalOverlay.classList.contains('open') || !modalBody.classList.contains('term-modal-keyboard')) return;
349
+ if (!modalOverlay.classList.contains('open') || !modalBody.classList.contains('hacker-modal-keyboard')) return;
350
350
  if (e.key === 'Escape') return;
351
351
  e.preventDefault();
352
352
  highlightKey(e.code);
@@ -356,25 +356,25 @@
356
356
  if (charEl) charEl.textContent = helpCharCount;
357
357
  }
358
358
  }
359
- var scriptsTpl = document.getElementById('term-scripts-folders-tpl');
359
+ var scriptsTpl = document.getElementById('hacker-scripts-folders-tpl');
360
360
  var fallbackModalContent = {
361
- 'dl-data': { title: 'Downloading...', body: '<div class="term-modal-download"><div class="modal-subtitle">Critical Data</div><div class="term-modal-progress" id="dl-progress"></div></div>', type: 'progress' },
361
+ 'dl-data': { title: 'Downloading...', body: '<div class="hacker-modal-download"><div class="modal-subtitle">Critical Data</div><div class="hacker-modal-progress" id="dl-progress"></div></div>', type: 'progress' },
362
362
  'ai': { title: 'AI', body: '<pre>~ $ model --status\n\ninference: stable\ncontext: 8k tokens\nlatency: &lt; 200ms\n\n&gt;&gt; system online</pre>' },
363
- 'decryptor': { title: 'Password Decryptor', body: '<pre class="term-decryptor-pre">Calculating Hashes\n\n<span id="dec-keys">[00:00:01] 0 keys tested</span>\n\nCurrent passphrase: <span id="dec-pass">********</span>\n\nMaster key\n<span id="dec-master1"></span>\n<span id="dec-master2"></span>\n\nTransient key\n<span id="dec-trans1"></span>\n<span id="dec-trans2"></span>\n<span id="dec-trans3"></span>\n<span id="dec-trans4"></span></pre>', type: 'decryptor' },
363
+ 'decryptor': { title: 'Password Decryptor', body: '<pre class="hacker-decryptor-pre">Calculating Hashes\n\n<span id="dec-keys">[00:00:01] 0 keys tested</span>\n\nCurrent passphrase: <span id="dec-pass">********</span>\n\nMaster key\n<span id="dec-master1"></span>\n<span id="dec-master2"></span>\n\nTransient key\n<span id="dec-trans1"></span>\n<span id="dec-trans2"></span>\n<span id="dec-trans3"></span>\n<span id="dec-trans4"></span></pre>', type: 'decryptor' },
364
364
  'help': { title: 'Help', body: '', type: 'keyboard' },
365
365
  'all-scripts': { title: '/root/bash/scripts', body: '', type: 'scripts' }
366
366
  };
367
367
  var modalContent = runtimeConfig.modalContent || fallbackModalContent;
368
- document.querySelectorAll('.term-folder[data-modal]').forEach(function(btn) {
368
+ document.querySelectorAll('.hacker-folder[data-modal]').forEach(function(btn) {
369
369
  btn.addEventListener('click', function() {
370
370
  var id = btn.getAttribute('data-modal');
371
371
  var data = modalContent[id];
372
372
  if (data) {
373
- var modalEl = modalOverlay.querySelector('.term-modal');
374
- if (modalEl) modalEl.classList.remove('term-modal-wide');
373
+ var modalEl = modalOverlay.querySelector('.hacker-modal');
374
+ if (modalEl) modalEl.classList.remove('hacker-modal-wide');
375
375
  modalTitle.textContent = data.title;
376
376
  modalBody.innerHTML = data.body;
377
- modalBody.className = 'term-modal-body' + (data.type === 'progress' ? ' term-modal-download' : '') + (data.type === 'keyboard' ? ' term-modal-keyboard' : '') + (data.type === 'scripts' ? ' term-modal-scripts-wrap' : '');
377
+ modalBody.className = 'hacker-modal-body' + (data.type === 'progress' ? ' hacker-modal-download' : '') + (data.type === 'keyboard' ? ' hacker-modal-keyboard' : '') + (data.type === 'scripts' ? ' hacker-modal-scripts-wrap' : '');
378
378
  if (data.type === 'progress') {
379
379
  var bar = document.getElementById('dl-progress');
380
380
  if (bar) {
@@ -410,13 +410,13 @@
410
410
  startDecryptorFlash();
411
411
  } else if (data.type === 'keyboard') {
412
412
  modalBody.innerHTML = buildHelpKeyboard();
413
- if (modalEl) modalEl.classList.add('term-modal-wide');
413
+ if (modalEl) modalEl.classList.add('hacker-modal-wide');
414
414
  initHelpKeyboard();
415
415
  document.addEventListener('keydown', handleHelpKeydown);
416
416
  } else if (data.type === 'scripts' && scriptsTpl && scriptsTpl.content) {
417
417
  modalBody.innerHTML = '';
418
418
  modalBody.appendChild(scriptsTpl.content.cloneNode(true));
419
- if (modalEl) modalEl.classList.add('term-modal-wide');
419
+ if (modalEl) modalEl.classList.add('hacker-modal-wide');
420
420
  }
421
421
  modalOverlay.classList.add('open');
422
422
  modalOverlay.setAttribute('aria-hidden', 'false');
@@ -429,12 +429,12 @@
429
429
  decryptorInterval = null;
430
430
  }
431
431
  document.removeEventListener('keydown', handleHelpKeydown);
432
- var modalEl = modalOverlay.querySelector('.term-modal');
433
- if (modalEl) modalEl.classList.remove('term-modal-wide');
432
+ var modalEl = modalOverlay.querySelector('.hacker-modal');
433
+ if (modalEl) modalEl.classList.remove('hacker-modal-wide');
434
434
  modalOverlay.classList.remove('open');
435
435
  modalOverlay.setAttribute('aria-hidden', 'true');
436
436
  }
437
- document.querySelector('.term-modal-close').addEventListener('click', closeModal);
437
+ document.querySelector('.hacker-modal-close').addEventListener('click', closeModal);
438
438
  modalOverlay.addEventListener('click', function(e) {
439
439
  if (e.target === modalOverlay) closeModal();
440
440
  });
@@ -443,7 +443,7 @@
443
443
  });
444
444
 
445
445
  // ── Mouse glow ──
446
- var glow = document.querySelector('.term-mouse-glow');
446
+ var glow = document.querySelector('.hacker-mouse-glow');
447
447
  if (glow) {
448
448
  var glowRaf;
449
449
  var mx = 0, my = 0;
@@ -459,19 +459,19 @@
459
459
  }
460
460
 
461
461
  // ── Paragraph scroll reveal ──
462
- var paras = document.querySelectorAll('.term-body p, .term-body h2, .term-body blockquote, .about-manifest');
462
+ var paras = document.querySelectorAll('.hacker-body p, .hacker-body h2, .hacker-body blockquote, .about-manifest');
463
463
  if (window.IntersectionObserver) {
464
464
  var io = new IntersectionObserver(function(entries) {
465
465
  entries.forEach(function(e) {
466
466
  if (e.isIntersecting) {
467
- e.target.classList.add('term-visible');
467
+ e.target.classList.add('hacker-visible');
468
468
  io.unobserve(e.target);
469
469
  }
470
470
  });
471
471
  }, { rootMargin: '0px 0px -60px 0px', threshold: 0.1 });
472
472
  paras.forEach(function(p) { io.observe(p); });
473
473
  } else {
474
- paras.forEach(function(p) { p.classList.add('term-visible'); });
474
+ paras.forEach(function(p) { p.classList.add('hacker-visible'); });
475
475
  }
476
476
 
477
477
  // ── Typewriter section titles ──
@@ -505,22 +505,22 @@
505
505
  }
506
506
 
507
507
  // ── Regenerate button ──
508
- var regen = document.querySelector('.term-regenerate');
508
+ var regen = document.querySelector('.hacker-regenerate');
509
509
  var article = document.querySelector('.about-shell');
510
- var scan = document.querySelector('.term-load-scan');
510
+ var scan = document.querySelector('.hacker-load-scan');
511
511
  if (regen && article) {
512
512
  regen.addEventListener('click', function() {
513
513
  regen.disabled = true;
514
- article.classList.add('term-flash');
514
+ article.classList.add('hacker-flash');
515
515
  if (scan) {
516
516
  scan.style.animation = 'none';
517
517
  scan.offsetHeight;
518
- scan.style.animation = 'term-scan 0.8s ease-out forwards';
518
+ scan.style.animation = 'hacker-scan 0.8s ease-out forwards';
519
519
  scan.style.top = '0';
520
520
  scan.style.opacity = '1';
521
521
  }
522
522
  setTimeout(function() {
523
- article.classList.remove('term-flash');
523
+ article.classList.remove('hacker-flash');
524
524
  regen.disabled = false;
525
525
  }, 1200);
526
526
  });
@@ -1,9 +1,9 @@
1
1
  (function() {
2
2
  function init() {
3
3
  // 阅读进度条
4
- var progress = document.querySelector('.mesh-read-progress');
5
- var article = document.querySelector('.mesh-article');
6
- var toast = document.querySelector('.mesh-stage-toast');
4
+ var progress = document.querySelector('.ai-read-progress');
5
+ var article = document.querySelector('.ai-article');
6
+ var toast = document.querySelector('.ai-stage-toast');
7
7
  var stageSeen = { p30: false, p60: false, p90: false };
8
8
  var toastTimer = 0;
9
9
  var hasScrolled = false;
@@ -22,7 +22,7 @@
22
22
  var scrollHeight = document.documentElement.scrollHeight - window.innerHeight;
23
23
  var p = scrollHeight > 0 ? Math.min(1, scrollTop / scrollHeight) : 1;
24
24
  progress.style.setProperty('--read-progress', String(p));
25
- var btn = document.querySelector('.mesh-back-to-top');
25
+ var btn = document.querySelector('.ai-back-to-top');
26
26
  if (btn) btn.classList.toggle('visible', scrollTop > 400);
27
27
  if (!hasScrolled && scrollTop > 6) hasScrolled = true;
28
28
  if (!hasScrolled) return;
@@ -42,7 +42,7 @@
42
42
  onScroll();
43
43
  window.addEventListener('scroll', onScroll, { passive: true });
44
44
  }
45
- var backTop = document.querySelector('.mesh-back-to-top');
45
+ var backTop = document.querySelector('.ai-back-to-top');
46
46
  if (backTop) {
47
47
  backTop.addEventListener('click', function() {
48
48
  window.scrollTo({ top: 0, behavior: 'smooth' });
@@ -880,7 +880,7 @@
880
880
  initRedQueenTv();
881
881
 
882
882
  // 鼠标跟随光斑
883
- var glow = document.querySelector('.mesh-mouse-glow');
883
+ var glow = document.querySelector('.ai-mouse-glow');
884
884
  if (glow) {
885
885
  var raf;
886
886
  var x = 0, y = 0;
@@ -896,10 +896,10 @@
896
896
  }
897
897
 
898
898
  // 悬浮预览卡:为链接添加 data-preview
899
- document.querySelectorAll('.mesh-prose-body a[href]').forEach(function(a) {
899
+ document.querySelectorAll('.ai-prose-body a[href]').forEach(function(a) {
900
900
  var href = a.getAttribute('href') || '';
901
901
  if (!href || href.startsWith('#')) return;
902
- a.classList.add('mesh-link-preview');
902
+ a.classList.add('ai-link-preview');
903
903
  try {
904
904
  a.setAttribute('data-preview', href.startsWith('http') ? new URL(href, location.origin).hostname : href);
905
905
  } catch (_) {
@@ -908,40 +908,40 @@
908
908
  });
909
909
 
910
910
  // 段落滚动浮现
911
- var paras = document.querySelectorAll('.mesh-prose-body p, .mesh-prose-body h2, .mesh-prose-body h3, .mesh-prose-body pre, .mesh-prose-body blockquote, .mesh-prose-body ul, .mesh-prose-body ol');
911
+ var paras = document.querySelectorAll('.ai-prose-body p, .ai-prose-body h2, .ai-prose-body h3, .ai-prose-body pre, .ai-prose-body blockquote, .ai-prose-body ul, .ai-prose-body ol');
912
912
  if (window.IntersectionObserver) {
913
913
  var io = new IntersectionObserver(function(entries) {
914
914
  entries.forEach(function(e) {
915
915
  if (e.isIntersecting) {
916
- e.target.classList.add('mesh-para-visible');
916
+ e.target.classList.add('ai-para-visible');
917
917
  io.unobserve(e.target);
918
918
  }
919
919
  });
920
920
  }, { rootMargin: '0px 0px -60px 0px', threshold: 0.1 });
921
921
  paras.forEach(function(p) { io.observe(p); });
922
922
  } else {
923
- paras.forEach(function(p) { p.classList.add('mesh-para-visible'); });
923
+ paras.forEach(function(p) { p.classList.add('ai-para-visible'); });
924
924
  }
925
925
 
926
926
  // Regenerate 按钮
927
- var regen = document.querySelector('.mesh-regenerate');
928
- var article = document.querySelector('.mesh-article');
929
- var scan = document.querySelector('.mesh-load-scan');
927
+ var regen = document.querySelector('.ai-regenerate');
928
+ var article = document.querySelector('.ai-article');
929
+ var scan = document.querySelector('.ai-load-scan');
930
930
  if (regen && article) {
931
931
  regen.addEventListener('click', function() {
932
932
  regen.disabled = true;
933
- regen.classList.add('mesh-regenerating');
934
- article.classList.add('mesh-regenerate-flash');
933
+ regen.classList.add('ai-regenerating');
934
+ article.classList.add('ai-regenerate-flash');
935
935
  if (scan) {
936
936
  scan.style.animation = 'none';
937
937
  scan.offsetHeight;
938
- scan.style.animation = 'mesh-scan 0.8s ease-out forwards';
938
+ scan.style.animation = 'ai-scan 0.8s ease-out forwards';
939
939
  scan.style.top = '0';
940
940
  scan.style.opacity = '1';
941
941
  }
942
942
  setTimeout(function() {
943
- article.classList.remove('mesh-regenerate-flash');
944
- regen.classList.remove('mesh-regenerating');
943
+ article.classList.remove('ai-regenerate-flash');
944
+ regen.classList.remove('ai-regenerating');
945
945
  regen.disabled = false;
946
946
  }, 1200);
947
947
  });