CompactAI commited on
Commit
e933ca7
·
verified ·
1 Parent(s): 7d87e20

Upload 4 files

Browse files
Files changed (2) hide show
  1. everywhere.css +74 -5
  2. reveal.js +124 -0
everywhere.css CHANGED
@@ -706,12 +706,81 @@ body::after {
706
  margin: 28px 0;
707
  }
708
 
 
 
 
 
 
709
  .paper-body blockquote {
710
- border-left: 2px solid var(--accent-muted);
711
- padding-left: 16px;
712
- margin: 18px 0;
713
- color: var(--text-muted);
714
- font-style: italic;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
715
  }
716
 
717
  .proof-section {
 
706
  margin: 28px 0;
707
  }
708
 
709
+ .paper-body p,
710
+ .paper-body h1,
711
+ .paper-body h2,
712
+ .paper-body h3,
713
+ .paper-body li,
714
  .paper-body blockquote {
715
+ /* Ensure parent has relative for cursor positioning if needed */
716
+ position: relative;
717
+ }
718
+
719
+ .word-wrapper {
720
+ display: inline-block;
721
+ position: relative;
722
+ vertical-align: bottom;
723
+ opacity: 0;
724
+ padding: 0 1px;
725
+ }
726
+
727
+ .word-wrapper.revealing,
728
+ .word-wrapper.revealed {
729
+ opacity: 1;
730
+ }
731
+
732
+ .word-wrapper::after {
733
+ content: '';
734
+ position: absolute;
735
+ top: 0;
736
+ left: 0;
737
+ width: 100%;
738
+ height: 100%;
739
+ background: #000;
740
+ transform: scaleX(0);
741
+ transform-origin: left;
742
+ z-index: 1;
743
+ pointer-events: none;
744
+ }
745
+
746
+ .word-wrapper.revealing::after {
747
+ animation: revealBar 0.4s cubic-bezier(0.19, 1, 0.22, 1) forwards;
748
+ }
749
+
750
+ @keyframes revealBar {
751
+ 0% { transform: scaleX(0); transform-origin: left; }
752
+ 45% { transform: scaleX(1.1); transform-origin: left; }
753
+ 55% { transform: scaleX(1.1); transform-origin: right; }
754
+ 100% { transform: scaleX(0); transform-origin: right; }
755
+ }
756
+
757
+ /* LLM Cursor effect */
758
+ .llm-cursor {
759
+ pointer-events: none;
760
+ background: var(--accent);
761
+ box-shadow: 0 0 10px var(--accent-bright);
762
+ transition: opacity 0.2s, transform 0.1s cubic-bezier(0.19, 1, 0.22, 1);
763
+ z-index: 2000;
764
+ }
765
+
766
+ .llm-cursor.active {
767
+ opacity: 1;
768
+ }
769
+
770
+ @keyframes blink {
771
+ 0%, 100% { opacity: 1; }
772
+ 50% { opacity: 0; }
773
+ }
774
+
775
+ @media (prefers-reduced-motion: reduce) {
776
+ .word-wrapper {
777
+ opacity: 1 !important;
778
+ transform: none !important;
779
+ transition: none !important;
780
+ }
781
+ .word-wrapper::after {
782
+ display: none !important;
783
+ }
784
  }
785
 
786
  .proof-section {
reveal.js ADDED
@@ -0,0 +1,124 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ document.addEventListener('DOMContentLoaded', () => {
2
+ const paperBody = document.querySelector('.paper-body');
3
+ if (!paperBody) return;
4
+
5
+ const cursor = document.createElement('div');
6
+ cursor.className = 'llm-cursor';
7
+ document.body.appendChild(cursor);
8
+
9
+ function wrapWords(element) {
10
+ const nodes = Array.from(element.childNodes);
11
+ nodes.forEach(node => {
12
+ if (node.nodeType === Node.TEXT_NODE) {
13
+ const text = node.textContent;
14
+ if (text.trim() === '') return;
15
+ const fragment = document.createDocumentFragment();
16
+ const words = text.split(/(\s+)/);
17
+ words.forEach(word => {
18
+ if (word.length === 0) return;
19
+ if (word.trim() === '') {
20
+ fragment.appendChild(document.createTextNode(word));
21
+ } else {
22
+ const span = document.createElement('span');
23
+ span.className = 'word-wrapper';
24
+ span.textContent = word;
25
+ fragment.appendChild(span);
26
+ }
27
+ });
28
+ element.replaceChild(fragment, node);
29
+ } else if (node.nodeType === Node.ELEMENT_NODE &&
30
+ node.tagName !== 'SCRIPT' &&
31
+ node.tagName !== 'STYLE' &&
32
+ !node.classList.contains('proof-script')) {
33
+ wrapWords(node);
34
+ }
35
+ });
36
+ }
37
+
38
+ wrapWords(paperBody);
39
+
40
+ const queue = [];
41
+ let isProcessing = false;
42
+ const containers = Array.from(paperBody.querySelectorAll('p, h1, h2, h3, li, blockquote'));
43
+ const revealedContainers = new Set();
44
+
45
+ // Track active word for cursor repositioning on scroll
46
+ let activeWord = null;
47
+
48
+ function updateCursorPosition() {
49
+ if (!activeWord || !cursor.classList.contains('active')) return;
50
+ const rect = activeWord.getBoundingClientRect();
51
+ cursor.style.position = 'fixed';
52
+ cursor.style.left = `${rect.right}px`;
53
+ cursor.style.top = `${rect.top}px`;
54
+ cursor.style.height = `${rect.height}px`;
55
+ cursor.style.width = '2px';
56
+ }
57
+
58
+ function checkVisibility() {
59
+ const viewportHeight = window.innerHeight;
60
+ containers.forEach(container => {
61
+ if (revealedContainers.has(container)) return;
62
+ const rect = container.getBoundingClientRect();
63
+ if (rect.top < viewportHeight * 0.95) {
64
+ revealedContainers.add(container);
65
+ queue.push(container);
66
+ if (!isProcessing) processQueue();
67
+ }
68
+ });
69
+ // Ensure cursor follows scroll
70
+ updateCursorPosition();
71
+ }
72
+
73
+ window.addEventListener('scroll', checkVisibility, { passive: true });
74
+ setInterval(checkVisibility, 50); // High frequency check for smoother cursor
75
+ checkVisibility();
76
+
77
+ async function processQueue() {
78
+ if (queue.length === 0) {
79
+ isProcessing = false;
80
+ cursor.classList.remove('active');
81
+ activeWord = null;
82
+ return;
83
+ }
84
+ isProcessing = true;
85
+ const container = queue.shift();
86
+ await revealWordsInContainer(container);
87
+ processQueue();
88
+ }
89
+
90
+ function getDynamicDelay() {
91
+ const viewportHeight = window.innerHeight;
92
+ const hiddenWordsInView = document.querySelectorAll('.word-wrapper:not(.revealed)');
93
+ let countInView = 0;
94
+ hiddenWordsInView.forEach(word => {
95
+ const rect = word.getBoundingClientRect();
96
+ if (rect.top < viewportHeight && rect.bottom > 0) countInView++;
97
+ });
98
+ const minDelay = 4;
99
+ const maxDelay = 60;
100
+ const scaleFactor = 150;
101
+ const ratio = Math.min(countInView / scaleFactor, 1);
102
+ return maxDelay - (ratio * (maxDelay - minDelay));
103
+ }
104
+
105
+ async function revealWordsInContainer(container) {
106
+ const words = Array.from(container.querySelectorAll('.word-wrapper:not(.revealed)'));
107
+ if (words.length === 0) return;
108
+ cursor.classList.add('active');
109
+
110
+ for (const word of words) {
111
+ activeWord = word;
112
+ word.classList.add('revealing');
113
+ updateCursorPosition();
114
+
115
+ const baseDelay = getDynamicDelay();
116
+ const delay = baseDelay + Math.random() * (baseDelay * 0.4);
117
+ await new Promise(r => setTimeout(r, delay));
118
+
119
+ word.classList.add('revealed');
120
+ word.classList.remove('revealing');
121
+ updateCursorPosition();
122
+ }
123
+ }
124
+ });