@programinglive/commiter 1.2.6 → 1.2.12
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/.github/ISSUE_TEMPLATE/bug_report.md +28 -28
- package/.github/ISSUE_TEMPLATE/config.yml +5 -5
- package/.github/ISSUE_TEMPLATE/feature_request.md +20 -20
- package/.github/PULL_REQUEST_TEMPLATE.md +24 -24
- package/.netlify/netlify.toml +25 -0
- package/.netlify/state.json +3 -0
- package/CHANGELOG.md +259 -189
- package/CODE_OF_CONDUCT.md +36 -36
- package/LICENSE +21 -21
- package/PRD.md +96 -91
- package/PUBLISH.md +142 -142
- package/README.md +217 -211
- package/SECURITY.md +30 -30
- package/commitlint.config.cjs +4 -4
- package/docs/CREATE_RELEASES.md +103 -103
- package/docs/QUICK_RELEASE_GUIDE.md +101 -101
- package/docs/release-notes/RELEASE_NOTES.md +233 -177
- package/index.js +199 -196
- package/netlify.toml +2 -0
- package/package.json +96 -97
- package/scripts/create-releases.js +219 -219
- package/scripts/release.cjs +258 -284
- package/scripts/update-release-notes.cjs +182 -182
- package/web/README.md +79 -79
- package/web/css/style.css +963 -963
- package/web/favicon.svg +10 -10
- package/web/index.html +510 -507
- package/web/js/script.js +256 -256
- package/web/og-image.svg +24 -24
- package/scripts/update-web-releases.js +0 -232
- package/scripts/update-web-version.js +0 -37
package/web/js/script.js
CHANGED
|
@@ -1,256 +1,256 @@
|
|
|
1
|
-
// ===========================
|
|
2
|
-
// Mobile Menu Toggle
|
|
3
|
-
// ===========================
|
|
4
|
-
const mobileMenuToggle = document.querySelector('.mobile-menu-toggle');
|
|
5
|
-
const navLinks = document.querySelector('.nav-links');
|
|
6
|
-
|
|
7
|
-
if (mobileMenuToggle) {
|
|
8
|
-
mobileMenuToggle.addEventListener('click', () => {
|
|
9
|
-
navLinks.classList.toggle('active');
|
|
10
|
-
mobileMenuToggle.classList.toggle('active');
|
|
11
|
-
});
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
// ===========================
|
|
15
|
-
// Copy to Clipboard
|
|
16
|
-
// ===========================
|
|
17
|
-
const copyButtons = document.querySelectorAll('.copy-btn');
|
|
18
|
-
|
|
19
|
-
copyButtons.forEach(button => {
|
|
20
|
-
button.addEventListener('click', async () => {
|
|
21
|
-
const textToCopy = button.getAttribute('data-copy');
|
|
22
|
-
|
|
23
|
-
try {
|
|
24
|
-
await navigator.clipboard.writeText(textToCopy);
|
|
25
|
-
|
|
26
|
-
// Visual feedback
|
|
27
|
-
const originalHTML = button.innerHTML;
|
|
28
|
-
button.innerHTML = `
|
|
29
|
-
<svg width="20" height="20" viewBox="0 0 20 20" fill="none">
|
|
30
|
-
<path d="M16.667 5L7.5 14.167L3.333 10" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
31
|
-
</svg>
|
|
32
|
-
`;
|
|
33
|
-
button.style.color = '#10b981';
|
|
34
|
-
|
|
35
|
-
setTimeout(() => {
|
|
36
|
-
button.innerHTML = originalHTML;
|
|
37
|
-
button.style.color = '';
|
|
38
|
-
}, 2000);
|
|
39
|
-
} catch (err) {
|
|
40
|
-
console.error('Failed to copy text: ', err);
|
|
41
|
-
}
|
|
42
|
-
});
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
// ===========================
|
|
46
|
-
// Smooth Scroll with Offset
|
|
47
|
-
// ===========================
|
|
48
|
-
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
|
|
49
|
-
anchor.addEventListener('click', function (e) {
|
|
50
|
-
const href = this.getAttribute('href');
|
|
51
|
-
|
|
52
|
-
// Skip if it's just "#"
|
|
53
|
-
if (href === '#') return;
|
|
54
|
-
|
|
55
|
-
e.preventDefault();
|
|
56
|
-
|
|
57
|
-
const target = document.querySelector(href);
|
|
58
|
-
if (target) {
|
|
59
|
-
const navbarHeight = document.querySelector('.navbar').offsetHeight;
|
|
60
|
-
const targetPosition = target.getBoundingClientRect().top + window.pageYOffset - navbarHeight - 20;
|
|
61
|
-
|
|
62
|
-
window.scrollTo({
|
|
63
|
-
top: targetPosition,
|
|
64
|
-
behavior: 'smooth'
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
// Close mobile menu if open
|
|
68
|
-
if (navLinks.classList.contains('active')) {
|
|
69
|
-
navLinks.classList.remove('active');
|
|
70
|
-
mobileMenuToggle.classList.remove('active');
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
// ===========================
|
|
77
|
-
// Navbar Background on Scroll
|
|
78
|
-
// ===========================
|
|
79
|
-
const navbar = document.querySelector('.navbar');
|
|
80
|
-
let lastScroll = 0;
|
|
81
|
-
|
|
82
|
-
window.addEventListener('scroll', () => {
|
|
83
|
-
const currentScroll = window.pageYOffset;
|
|
84
|
-
|
|
85
|
-
if (currentScroll > 100) {
|
|
86
|
-
navbar.style.background = 'rgba(10, 10, 15, 0.95)';
|
|
87
|
-
navbar.style.boxShadow = '0 4px 16px rgba(0, 0, 0, 0.2)';
|
|
88
|
-
} else {
|
|
89
|
-
navbar.style.background = 'rgba(10, 10, 15, 0.8)';
|
|
90
|
-
navbar.style.boxShadow = 'none';
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
lastScroll = currentScroll;
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
// ===========================
|
|
97
|
-
// Intersection Observer for Animations
|
|
98
|
-
// ===========================
|
|
99
|
-
const observerOptions = {
|
|
100
|
-
threshold: 0.1,
|
|
101
|
-
rootMargin: '0px 0px -50px 0px'
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
const observer = new IntersectionObserver((entries) => {
|
|
105
|
-
entries.forEach(entry => {
|
|
106
|
-
if (entry.isIntersecting) {
|
|
107
|
-
entry.target.style.opacity = '1';
|
|
108
|
-
entry.target.style.transform = 'translateY(0)';
|
|
109
|
-
}
|
|
110
|
-
});
|
|
111
|
-
}, observerOptions);
|
|
112
|
-
|
|
113
|
-
// Observe all feature cards, install cards, and step cards
|
|
114
|
-
const animatedElements = document.querySelectorAll('.feature-card, .install-card, .step-card, .release-item');
|
|
115
|
-
animatedElements.forEach(el => {
|
|
116
|
-
el.style.opacity = '0';
|
|
117
|
-
el.style.transform = 'translateY(20px)';
|
|
118
|
-
el.style.transition = 'opacity 0.6s ease-out, transform 0.6s ease-out';
|
|
119
|
-
observer.observe(el);
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
// ===========================
|
|
123
|
-
// Add Active State to Nav Links
|
|
124
|
-
// ===========================
|
|
125
|
-
const sections = document.querySelectorAll('section[id]');
|
|
126
|
-
const navItems = document.querySelectorAll('.nav-links a[href^="#"]');
|
|
127
|
-
|
|
128
|
-
window.addEventListener('scroll', () => {
|
|
129
|
-
let current = '';
|
|
130
|
-
|
|
131
|
-
sections.forEach(section => {
|
|
132
|
-
const sectionTop = section.offsetTop;
|
|
133
|
-
const sectionHeight = section.clientHeight;
|
|
134
|
-
if (pageYOffset >= (sectionTop - 200)) {
|
|
135
|
-
current = section.getAttribute('id');
|
|
136
|
-
}
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
navItems.forEach(item => {
|
|
140
|
-
item.classList.remove('active');
|
|
141
|
-
if (item.getAttribute('href') === `#${current}`) {
|
|
142
|
-
item.classList.add('active');
|
|
143
|
-
}
|
|
144
|
-
});
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
// ===========================
|
|
148
|
-
// Terminal Animation
|
|
149
|
-
// ===========================
|
|
150
|
-
function animateTerminal() {
|
|
151
|
-
const codeLines = document.querySelectorAll('.code-line');
|
|
152
|
-
let delay = 0;
|
|
153
|
-
|
|
154
|
-
codeLines.forEach((line, index) => {
|
|
155
|
-
line.style.opacity = '0';
|
|
156
|
-
line.style.animation = 'none';
|
|
157
|
-
// Trigger reflow to restart animation
|
|
158
|
-
void line.offsetWidth;
|
|
159
|
-
line.style.animation = `fadeIn 0.5s ease-out ${delay}s forwards`;
|
|
160
|
-
delay += 0.3;
|
|
161
|
-
});
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
// Initial animation on page load
|
|
165
|
-
animateTerminal();
|
|
166
|
-
|
|
167
|
-
// Replay animation when scrolling back to the terminal
|
|
168
|
-
const codeWindow = document.querySelector('.code-window');
|
|
169
|
-
if (codeWindow) {
|
|
170
|
-
const terminalObserver = new IntersectionObserver((entries) => {
|
|
171
|
-
entries.forEach(entry => {
|
|
172
|
-
if (entry.isIntersecting) {
|
|
173
|
-
animateTerminal();
|
|
174
|
-
}
|
|
175
|
-
});
|
|
176
|
-
}, { threshold: 0.5 });
|
|
177
|
-
|
|
178
|
-
terminalObserver.observe(codeWindow);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
// Add fadeIn keyframe animation
|
|
182
|
-
const style = document.createElement('style');
|
|
183
|
-
style.textContent = `
|
|
184
|
-
@keyframes fadeIn {
|
|
185
|
-
from {
|
|
186
|
-
opacity: 0;
|
|
187
|
-
transform: translateX(-10px);
|
|
188
|
-
}
|
|
189
|
-
to {
|
|
190
|
-
opacity: 1;
|
|
191
|
-
transform: translateX(0);
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
.nav-links.active {
|
|
196
|
-
display: flex;
|
|
197
|
-
flex-direction: column;
|
|
198
|
-
position: absolute;
|
|
199
|
-
top: 100%;
|
|
200
|
-
left: 0;
|
|
201
|
-
right: 0;
|
|
202
|
-
background: rgba(10, 10, 15, 0.98);
|
|
203
|
-
backdrop-filter: blur(20px);
|
|
204
|
-
padding: var(--spacing-md);
|
|
205
|
-
border-bottom: 1px solid var(--border);
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
.mobile-menu-toggle.active span:nth-child(1) {
|
|
209
|
-
transform: rotate(45deg) translate(5px, 5px);
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
.mobile-menu-toggle.active span:nth-child(2) {
|
|
213
|
-
opacity: 0;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
.mobile-menu-toggle.active span:nth-child(3) {
|
|
217
|
-
transform: rotate(-45deg) translate(7px, -6px);
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
.nav-links a.active {
|
|
221
|
-
color: var(--primary-light);
|
|
222
|
-
background: var(--bg-glass);
|
|
223
|
-
}
|
|
224
|
-
`;
|
|
225
|
-
document.head.appendChild(style);
|
|
226
|
-
|
|
227
|
-
// ===========================
|
|
228
|
-
// Performance Optimization
|
|
229
|
-
// ===========================
|
|
230
|
-
// Debounce function for scroll events
|
|
231
|
-
function debounce(func, wait) {
|
|
232
|
-
let timeout;
|
|
233
|
-
return function executedFunction(...args) {
|
|
234
|
-
const later = () => {
|
|
235
|
-
clearTimeout(timeout);
|
|
236
|
-
func(...args);
|
|
237
|
-
};
|
|
238
|
-
clearTimeout(timeout);
|
|
239
|
-
timeout = setTimeout(later, wait);
|
|
240
|
-
};
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
// Apply debounce to scroll handlers
|
|
244
|
-
const debouncedScroll = debounce(() => {
|
|
245
|
-
// Scroll handlers are already defined above
|
|
246
|
-
}, 10);
|
|
247
|
-
|
|
248
|
-
window.addEventListener('scroll', debouncedScroll);
|
|
249
|
-
|
|
250
|
-
// ===========================
|
|
251
|
-
// Console Easter Egg
|
|
252
|
-
// ===========================
|
|
253
|
-
console.log('%c🚀 Commiter', 'font-size: 24px; font-weight: bold; background: linear-gradient(135deg, #6366f1, #ec4899); -webkit-background-clip: text; -webkit-text-fill-color: transparent;');
|
|
254
|
-
console.log('%cAutomate your releases with confidence!', 'font-size: 14px; color: #a1a1aa;');
|
|
255
|
-
console.log('%cGitHub: https://github.com/programinglive/commiter', 'font-size: 12px; color: #6366f1;');
|
|
256
|
-
console.log('%cNPM: https://www.npmjs.com/package/@programinglive/commiter', 'font-size: 12px; color: #6366f1;');
|
|
1
|
+
// ===========================
|
|
2
|
+
// Mobile Menu Toggle
|
|
3
|
+
// ===========================
|
|
4
|
+
const mobileMenuToggle = document.querySelector('.mobile-menu-toggle');
|
|
5
|
+
const navLinks = document.querySelector('.nav-links');
|
|
6
|
+
|
|
7
|
+
if (mobileMenuToggle) {
|
|
8
|
+
mobileMenuToggle.addEventListener('click', () => {
|
|
9
|
+
navLinks.classList.toggle('active');
|
|
10
|
+
mobileMenuToggle.classList.toggle('active');
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// ===========================
|
|
15
|
+
// Copy to Clipboard
|
|
16
|
+
// ===========================
|
|
17
|
+
const copyButtons = document.querySelectorAll('.copy-btn');
|
|
18
|
+
|
|
19
|
+
copyButtons.forEach(button => {
|
|
20
|
+
button.addEventListener('click', async () => {
|
|
21
|
+
const textToCopy = button.getAttribute('data-copy');
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
await navigator.clipboard.writeText(textToCopy);
|
|
25
|
+
|
|
26
|
+
// Visual feedback
|
|
27
|
+
const originalHTML = button.innerHTML;
|
|
28
|
+
button.innerHTML = `
|
|
29
|
+
<svg width="20" height="20" viewBox="0 0 20 20" fill="none">
|
|
30
|
+
<path d="M16.667 5L7.5 14.167L3.333 10" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
31
|
+
</svg>
|
|
32
|
+
`;
|
|
33
|
+
button.style.color = '#10b981';
|
|
34
|
+
|
|
35
|
+
setTimeout(() => {
|
|
36
|
+
button.innerHTML = originalHTML;
|
|
37
|
+
button.style.color = '';
|
|
38
|
+
}, 2000);
|
|
39
|
+
} catch (err) {
|
|
40
|
+
console.error('Failed to copy text: ', err);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
// ===========================
|
|
46
|
+
// Smooth Scroll with Offset
|
|
47
|
+
// ===========================
|
|
48
|
+
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
|
|
49
|
+
anchor.addEventListener('click', function (e) {
|
|
50
|
+
const href = this.getAttribute('href');
|
|
51
|
+
|
|
52
|
+
// Skip if it's just "#"
|
|
53
|
+
if (href === '#') return;
|
|
54
|
+
|
|
55
|
+
e.preventDefault();
|
|
56
|
+
|
|
57
|
+
const target = document.querySelector(href);
|
|
58
|
+
if (target) {
|
|
59
|
+
const navbarHeight = document.querySelector('.navbar').offsetHeight;
|
|
60
|
+
const targetPosition = target.getBoundingClientRect().top + window.pageYOffset - navbarHeight - 20;
|
|
61
|
+
|
|
62
|
+
window.scrollTo({
|
|
63
|
+
top: targetPosition,
|
|
64
|
+
behavior: 'smooth'
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// Close mobile menu if open
|
|
68
|
+
if (navLinks.classList.contains('active')) {
|
|
69
|
+
navLinks.classList.remove('active');
|
|
70
|
+
mobileMenuToggle.classList.remove('active');
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// ===========================
|
|
77
|
+
// Navbar Background on Scroll
|
|
78
|
+
// ===========================
|
|
79
|
+
const navbar = document.querySelector('.navbar');
|
|
80
|
+
let lastScroll = 0;
|
|
81
|
+
|
|
82
|
+
window.addEventListener('scroll', () => {
|
|
83
|
+
const currentScroll = window.pageYOffset;
|
|
84
|
+
|
|
85
|
+
if (currentScroll > 100) {
|
|
86
|
+
navbar.style.background = 'rgba(10, 10, 15, 0.95)';
|
|
87
|
+
navbar.style.boxShadow = '0 4px 16px rgba(0, 0, 0, 0.2)';
|
|
88
|
+
} else {
|
|
89
|
+
navbar.style.background = 'rgba(10, 10, 15, 0.8)';
|
|
90
|
+
navbar.style.boxShadow = 'none';
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
lastScroll = currentScroll;
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
// ===========================
|
|
97
|
+
// Intersection Observer for Animations
|
|
98
|
+
// ===========================
|
|
99
|
+
const observerOptions = {
|
|
100
|
+
threshold: 0.1,
|
|
101
|
+
rootMargin: '0px 0px -50px 0px'
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
const observer = new IntersectionObserver((entries) => {
|
|
105
|
+
entries.forEach(entry => {
|
|
106
|
+
if (entry.isIntersecting) {
|
|
107
|
+
entry.target.style.opacity = '1';
|
|
108
|
+
entry.target.style.transform = 'translateY(0)';
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
}, observerOptions);
|
|
112
|
+
|
|
113
|
+
// Observe all feature cards, install cards, and step cards
|
|
114
|
+
const animatedElements = document.querySelectorAll('.feature-card, .install-card, .step-card, .release-item');
|
|
115
|
+
animatedElements.forEach(el => {
|
|
116
|
+
el.style.opacity = '0';
|
|
117
|
+
el.style.transform = 'translateY(20px)';
|
|
118
|
+
el.style.transition = 'opacity 0.6s ease-out, transform 0.6s ease-out';
|
|
119
|
+
observer.observe(el);
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
// ===========================
|
|
123
|
+
// Add Active State to Nav Links
|
|
124
|
+
// ===========================
|
|
125
|
+
const sections = document.querySelectorAll('section[id]');
|
|
126
|
+
const navItems = document.querySelectorAll('.nav-links a[href^="#"]');
|
|
127
|
+
|
|
128
|
+
window.addEventListener('scroll', () => {
|
|
129
|
+
let current = '';
|
|
130
|
+
|
|
131
|
+
sections.forEach(section => {
|
|
132
|
+
const sectionTop = section.offsetTop;
|
|
133
|
+
const sectionHeight = section.clientHeight;
|
|
134
|
+
if (pageYOffset >= (sectionTop - 200)) {
|
|
135
|
+
current = section.getAttribute('id');
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
navItems.forEach(item => {
|
|
140
|
+
item.classList.remove('active');
|
|
141
|
+
if (item.getAttribute('href') === `#${current}`) {
|
|
142
|
+
item.classList.add('active');
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
// ===========================
|
|
148
|
+
// Terminal Animation
|
|
149
|
+
// ===========================
|
|
150
|
+
function animateTerminal() {
|
|
151
|
+
const codeLines = document.querySelectorAll('.code-line');
|
|
152
|
+
let delay = 0;
|
|
153
|
+
|
|
154
|
+
codeLines.forEach((line, index) => {
|
|
155
|
+
line.style.opacity = '0';
|
|
156
|
+
line.style.animation = 'none';
|
|
157
|
+
// Trigger reflow to restart animation
|
|
158
|
+
void line.offsetWidth;
|
|
159
|
+
line.style.animation = `fadeIn 0.5s ease-out ${delay}s forwards`;
|
|
160
|
+
delay += 0.3;
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Initial animation on page load
|
|
165
|
+
animateTerminal();
|
|
166
|
+
|
|
167
|
+
// Replay animation when scrolling back to the terminal
|
|
168
|
+
const codeWindow = document.querySelector('.code-window');
|
|
169
|
+
if (codeWindow) {
|
|
170
|
+
const terminalObserver = new IntersectionObserver((entries) => {
|
|
171
|
+
entries.forEach(entry => {
|
|
172
|
+
if (entry.isIntersecting) {
|
|
173
|
+
animateTerminal();
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
}, { threshold: 0.5 });
|
|
177
|
+
|
|
178
|
+
terminalObserver.observe(codeWindow);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Add fadeIn keyframe animation
|
|
182
|
+
const style = document.createElement('style');
|
|
183
|
+
style.textContent = `
|
|
184
|
+
@keyframes fadeIn {
|
|
185
|
+
from {
|
|
186
|
+
opacity: 0;
|
|
187
|
+
transform: translateX(-10px);
|
|
188
|
+
}
|
|
189
|
+
to {
|
|
190
|
+
opacity: 1;
|
|
191
|
+
transform: translateX(0);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
.nav-links.active {
|
|
196
|
+
display: flex;
|
|
197
|
+
flex-direction: column;
|
|
198
|
+
position: absolute;
|
|
199
|
+
top: 100%;
|
|
200
|
+
left: 0;
|
|
201
|
+
right: 0;
|
|
202
|
+
background: rgba(10, 10, 15, 0.98);
|
|
203
|
+
backdrop-filter: blur(20px);
|
|
204
|
+
padding: var(--spacing-md);
|
|
205
|
+
border-bottom: 1px solid var(--border);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
.mobile-menu-toggle.active span:nth-child(1) {
|
|
209
|
+
transform: rotate(45deg) translate(5px, 5px);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
.mobile-menu-toggle.active span:nth-child(2) {
|
|
213
|
+
opacity: 0;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
.mobile-menu-toggle.active span:nth-child(3) {
|
|
217
|
+
transform: rotate(-45deg) translate(7px, -6px);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
.nav-links a.active {
|
|
221
|
+
color: var(--primary-light);
|
|
222
|
+
background: var(--bg-glass);
|
|
223
|
+
}
|
|
224
|
+
`;
|
|
225
|
+
document.head.appendChild(style);
|
|
226
|
+
|
|
227
|
+
// ===========================
|
|
228
|
+
// Performance Optimization
|
|
229
|
+
// ===========================
|
|
230
|
+
// Debounce function for scroll events
|
|
231
|
+
function debounce(func, wait) {
|
|
232
|
+
let timeout;
|
|
233
|
+
return function executedFunction(...args) {
|
|
234
|
+
const later = () => {
|
|
235
|
+
clearTimeout(timeout);
|
|
236
|
+
func(...args);
|
|
237
|
+
};
|
|
238
|
+
clearTimeout(timeout);
|
|
239
|
+
timeout = setTimeout(later, wait);
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// Apply debounce to scroll handlers
|
|
244
|
+
const debouncedScroll = debounce(() => {
|
|
245
|
+
// Scroll handlers are already defined above
|
|
246
|
+
}, 10);
|
|
247
|
+
|
|
248
|
+
window.addEventListener('scroll', debouncedScroll);
|
|
249
|
+
|
|
250
|
+
// ===========================
|
|
251
|
+
// Console Easter Egg
|
|
252
|
+
// ===========================
|
|
253
|
+
console.log('%c🚀 Commiter', 'font-size: 24px; font-weight: bold; background: linear-gradient(135deg, #6366f1, #ec4899); -webkit-background-clip: text; -webkit-text-fill-color: transparent;');
|
|
254
|
+
console.log('%cAutomate your releases with confidence!', 'font-size: 14px; color: #a1a1aa;');
|
|
255
|
+
console.log('%cGitHub: https://github.com/programinglive/commiter', 'font-size: 12px; color: #6366f1;');
|
|
256
|
+
console.log('%cNPM: https://www.npmjs.com/package/@programinglive/commiter', 'font-size: 12px; color: #6366f1;');
|
package/web/og-image.svg
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
<svg width="1200" height="630" viewBox="0 0 1200 630" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
-
<!-- Background: Very Dark Grey (GitHub/Terminal Style) -->
|
|
3
|
-
<rect width="1200" height="630" fill="#0D1117"/>
|
|
4
|
-
|
|
5
|
-
<!-- Subtle Background Pattern (Optional Grid) -->
|
|
6
|
-
<path d="M0 630V0H1200V630" fill="url(#grid)" opacity="0.1"/>
|
|
7
|
-
<defs>
|
|
8
|
-
<pattern id="grid" width="40" height="40" patternUnits="userSpaceOnUse">
|
|
9
|
-
<path d="M 40 0 L 0 0 0 40" fill="none" stroke="white" stroke-width="1"/>
|
|
10
|
-
</pattern>
|
|
11
|
-
</defs>
|
|
12
|
-
|
|
13
|
-
<!-- Central Group -->
|
|
14
|
-
<g transform="translate(600, 315)" text-anchor="middle">
|
|
15
|
-
<!-- Rocket Emoji (Using text for consistent vibe) -->
|
|
16
|
-
<text x="0" y="-20" font-family="Arial, sans-serif" font-size="150" fill="white" text-anchor="middle">🚀</text>
|
|
17
|
-
|
|
18
|
-
<!-- Brand Name -->
|
|
19
|
-
<text x="0" y="130" font-family="-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" font-weight="800" font-size="120" fill="#FFFFFF" text-anchor="middle">Commiter</text>
|
|
20
|
-
|
|
21
|
-
<!-- Tagline -->
|
|
22
|
-
<text x="0" y="200" font-family="-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" font-size="32" fill="#8B949E" text-anchor="middle">Automated Commit Conventions & Release Management</text>
|
|
23
|
-
</g>
|
|
24
|
-
</svg>
|
|
1
|
+
<svg width="1200" height="630" viewBox="0 0 1200 630" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<!-- Background: Very Dark Grey (GitHub/Terminal Style) -->
|
|
3
|
+
<rect width="1200" height="630" fill="#0D1117"/>
|
|
4
|
+
|
|
5
|
+
<!-- Subtle Background Pattern (Optional Grid) -->
|
|
6
|
+
<path d="M0 630V0H1200V630" fill="url(#grid)" opacity="0.1"/>
|
|
7
|
+
<defs>
|
|
8
|
+
<pattern id="grid" width="40" height="40" patternUnits="userSpaceOnUse">
|
|
9
|
+
<path d="M 40 0 L 0 0 0 40" fill="none" stroke="white" stroke-width="1"/>
|
|
10
|
+
</pattern>
|
|
11
|
+
</defs>
|
|
12
|
+
|
|
13
|
+
<!-- Central Group -->
|
|
14
|
+
<g transform="translate(600, 315)" text-anchor="middle">
|
|
15
|
+
<!-- Rocket Emoji (Using text for consistent vibe) -->
|
|
16
|
+
<text x="0" y="-20" font-family="Arial, sans-serif" font-size="150" fill="white" text-anchor="middle">🚀</text>
|
|
17
|
+
|
|
18
|
+
<!-- Brand Name -->
|
|
19
|
+
<text x="0" y="130" font-family="-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" font-weight="800" font-size="120" fill="#FFFFFF" text-anchor="middle">Commiter</text>
|
|
20
|
+
|
|
21
|
+
<!-- Tagline -->
|
|
22
|
+
<text x="0" y="200" font-family="-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" font-size="32" fill="#8B949E" text-anchor="middle">Automated Commit Conventions & Release Management</text>
|
|
23
|
+
</g>
|
|
24
|
+
</svg>
|