Skip to content

Commit 135daf6

Browse files
committed
Enhance index.html and style.css: add a copy button for code snippets, update button styles for improved visibility, and implement a new download button for rules.yaml. Adjust CSS for better layout and responsiveness of code container elements.
1 parent 8a72f68 commit 135daf6

3 files changed

Lines changed: 112 additions & 19 deletions

File tree

index.html

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ <h1 class="title">
2626
<span class="title-word-1">Agentic</span> <span class="title-word-2">GitHub</span> <span class="title-word-3">Guardrails</span>
2727
</h1>
2828
<p class="subtitle">
29-
Replace static protection rules with context-aware monitoring. Let Watchflow ensure consistent quality standards so your team can focus on building.
29+
Replace static protection rules with context-aware monitoring. Let <strong>Watchflow</strong> ensure consistent quality standards so your team can focus on building.
3030
</p>
3131
</header>
3232

@@ -74,9 +74,16 @@ <h2 class="section-title">Your repo, your rules</h2>
7474
<div class="window-dot green"></div>
7575
</div>
7676
</div>
77-
<pre id="codeContent" class="code-content"></pre>
77+
<div class="code-container">
78+
<pre id="codeContent" class="code-content"></pre>
79+
<button id="copyIconBtn" class="copy-icon-btn" title="Copy to clipboard">
80+
<svg viewBox="0 0 24 24" width="16" height="16">
81+
<path d="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z" fill="currentColor"/>
82+
</svg>
83+
</button>
84+
</div>
7885
<div class="code-actions">
79-
<button id="copyBtn" class="code-action-btn copy-btn">Copy to clipboard</button>
86+
<button id="downloadBtn" class="code-action-btn download-btn">Download rules.yaml</button>
8087
<a href="https://github.com/apps/watchflow" target="_blank" rel="noopener noreferrer" class="code-action-btn install-btn">Install Watchflow</a>
8188
</div>
8289
</div>

script.js

Lines changed: 50 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ const loadingIndicator = document.getElementById('loadingIndicator');
66
const errorAlert = document.getElementById('errorAlert');
77
const errorMessage = document.getElementById('errorMessage');
88
const codeContent = document.getElementById('codeContent');
9-
const copyBtn = document.getElementById('copyBtn');
9+
const downloadBtn = document.getElementById('downloadBtn');
10+
const copyIconBtn = document.getElementById('copyIconBtn');
1011
// showExamplesBtn removed - examples are now always visible
1112
const examplesGrid = document.getElementById('examplesGrid');
1213

@@ -41,8 +42,11 @@ function initializeEventListeners() {
4142
}
4243
});
4344

44-
// Copy button click
45-
copyBtn.addEventListener('click', handleCopyClick);
45+
// Download button click
46+
downloadBtn.addEventListener('click', handleDownloadClick);
47+
48+
// Copy icon button click
49+
copyIconBtn.addEventListener('click', handleCopyClick);
4650

4751
// Examples are now always visible - no button needed
4852

@@ -181,17 +185,40 @@ rules:
181185
}
182186
}
183187

184-
// Handle copy button click
188+
// Handle download button click
189+
function handleDownloadClick() {
190+
if (!currentRule) return;
191+
192+
// Create blob with YAML content
193+
const blob = new Blob([currentRule], { type: 'text/yaml' });
194+
const url = URL.createObjectURL(blob);
195+
196+
// Create temporary download link
197+
const a = document.createElement('a');
198+
a.href = url;
199+
a.download = 'rules.yaml';
200+
document.body.appendChild(a);
201+
a.click();
202+
203+
// Cleanup
204+
document.body.removeChild(a);
205+
URL.revokeObjectURL(url);
206+
207+
// Show feedback
208+
showDownloadFeedback();
209+
}
210+
211+
// Handle copy icon button click
185212
async function handleCopyClick() {
186213
if (!currentRule) return;
187214

188215
try {
189216
await navigator.clipboard.writeText(currentRule);
190-
showCopyTooltip();
217+
showCopyFeedback();
191218
} catch (error) {
192219
// Fallback for older browsers
193220
fallbackCopyToClipboard(currentRule);
194-
showCopyTooltip();
221+
showCopyFeedback();
195222
}
196223
}
197224

@@ -227,15 +254,26 @@ function fallbackCopyToClipboard(text) {
227254
document.body.removeChild(textArea);
228255
}
229256

257+
// Show download feedback
258+
function showDownloadFeedback() {
259+
const originalText = downloadBtn.textContent;
260+
downloadBtn.textContent = 'Downloaded!';
261+
downloadBtn.style.background = '#4CAF50';
262+
263+
setTimeout(() => {
264+
downloadBtn.textContent = originalText;
265+
downloadBtn.style.background = '';
266+
}, 1500);
267+
}
268+
230269
// Show copy feedback
231-
function showCopyTooltip() {
232-
const originalText = copyBtn.textContent;
233-
copyBtn.textContent = 'Copied!';
234-
copyBtn.style.background = '#4CAF50';
270+
function showCopyFeedback() {
271+
copyIconBtn.style.background = '#4CAF50';
272+
copyIconBtn.style.color = '#FFFFFF';
235273

236274
setTimeout(() => {
237-
copyBtn.textContent = originalText;
238-
copyBtn.style.background = '';
275+
copyIconBtn.style.background = '';
276+
copyIconBtn.style.color = '';
239277
}, 1500);
240278
}
241279

style.css

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,20 @@ body::after {
576576
transform: translateY(-1px);
577577
}
578578

579+
.download-btn {
580+
background: var(--accent-secondary);
581+
color: var(--text-primary);
582+
}
583+
584+
.download-btn:hover {
585+
background: #E6C200;
586+
transform: translateY(-1px);
587+
}
588+
589+
.code-container {
590+
position: relative;
591+
}
592+
579593
.code-content {
580594
padding: 1.5rem;
581595
color: var(--text-light);
@@ -586,6 +600,32 @@ body::after {
586600
overflow-x: auto;
587601
}
588602

603+
.copy-icon-btn {
604+
position: absolute;
605+
top: 1rem;
606+
right: 1rem;
607+
padding: 0.5rem;
608+
background: rgba(255, 255, 255, 0.9);
609+
border: 2px solid var(--border-color);
610+
border-radius: 6px;
611+
cursor: pointer;
612+
transition: all 0.2s ease;
613+
color: var(--text-primary);
614+
box-shadow: 2px 2px 0 var(--shadow-color);
615+
z-index: 10;
616+
}
617+
618+
.copy-icon-btn:hover {
619+
background: var(--accent-secondary);
620+
transform: translate(1px, 1px);
621+
box-shadow: 1px 1px 0 var(--shadow-color);
622+
}
623+
624+
.copy-icon-btn:active {
625+
transform: translate(2px, 2px);
626+
box-shadow: none;
627+
}
628+
589629
/* Loading Indicator */
590630
.loading {
591631
display: flex;
@@ -1142,7 +1182,7 @@ body::after {
11421182

11431183
/* Mobile devices */
11441184
@media (max-width: 480px) {
1145-
/* Cartoony mobile bubbles */
1185+
/* Cartoony mobile bubbles - star colors */
11461186
body::before {
11471187
display: block;
11481188
content: '';
@@ -1155,7 +1195,11 @@ body::after {
11551195
radial-gradient(circle 40px at 20% 30%, rgba(78, 205, 196, 0.4) 0%, rgba(78, 205, 196, 0.2) 50%, rgba(0, 0, 0, 0.08) 55%, transparent 60%),
11561196
radial-gradient(circle 50px at 80% 20%, rgba(255, 215, 0, 0.35) 0%, rgba(255, 215, 0, 0.18) 50%, rgba(0, 0, 0, 0.08) 55%, transparent 60%),
11571197
radial-gradient(circle 30px at 60% 70%, rgba(255, 107, 107, 0.4) 0%, rgba(255, 107, 107, 0.2) 50%, rgba(0, 0, 0, 0.08) 55%, transparent 60%),
1158-
radial-gradient(circle 35px at 25% 80%, rgba(149, 225, 211, 0.35) 0%, rgba(149, 225, 211, 0.18) 50%, rgba(0, 0, 0, 0.08) 55%, transparent 60%);
1198+
radial-gradient(circle 35px at 25% 80%, rgba(149, 225, 211, 0.35) 0%, rgba(149, 225, 211, 0.18) 50%, rgba(0, 0, 0, 0.08) 55%, transparent 60%),
1199+
radial-gradient(circle 25px at 10% 15%, rgba(255, 215, 0, 0.3) 0%, rgba(255, 215, 0, 0.15) 50%, rgba(0, 0, 0, 0.06) 55%, transparent 60%),
1200+
radial-gradient(circle 45px at 90% 40%, rgba(78, 205, 196, 0.35) 0%, rgba(78, 205, 196, 0.18) 50%, rgba(0, 0, 0, 0.08) 55%, transparent 60%),
1201+
radial-gradient(circle 32px at 45% 10%, rgba(255, 107, 107, 0.3) 0%, rgba(255, 107, 107, 0.15) 50%, rgba(0, 0, 0, 0.06) 55%, transparent 60%),
1202+
radial-gradient(circle 38px at 75% 85%, rgba(149, 225, 211, 0.32) 0%, rgba(149, 225, 211, 0.16) 50%, rgba(0, 0, 0, 0.07) 55%, transparent 60%);
11591203
animation: bubblesFloat 25s linear infinite;
11601204
z-index: -1;
11611205
pointer-events: none;
@@ -1170,8 +1214,12 @@ body::after {
11701214
width: 100%;
11711215
height: 120%;
11721216
background:
1173-
radial-gradient(circle 45px at 70% 50%, rgba(255, 182, 193, 0.3) 0%, rgba(255, 182, 193, 0.15) 50%, rgba(0, 0, 0, 0.06) 55%, transparent 60%),
1174-
radial-gradient(circle 30px at 15% 60%, rgba(138, 43, 226, 0.25) 0%, rgba(138, 43, 226, 0.12) 50%, rgba(0, 0, 0, 0.06) 55%, transparent 60%);
1217+
radial-gradient(circle 45px at 70% 50%, rgba(255, 107, 107, 0.3) 0%, rgba(255, 107, 107, 0.15) 50%, rgba(0, 0, 0, 0.06) 55%, transparent 60%),
1218+
radial-gradient(circle 30px at 15% 60%, rgba(149, 225, 211, 0.25) 0%, rgba(149, 225, 211, 0.12) 50%, rgba(0, 0, 0, 0.06) 55%, transparent 60%),
1219+
radial-gradient(circle 42px at 95% 75%, rgba(255, 215, 0, 0.28) 0%, rgba(255, 215, 0, 0.14) 50%, rgba(0, 0, 0, 0.06) 55%, transparent 60%),
1220+
radial-gradient(circle 28px at 35% 35%, rgba(78, 205, 196, 0.25) 0%, rgba(78, 205, 196, 0.12) 50%, rgba(0, 0, 0, 0.06) 55%, transparent 60%),
1221+
radial-gradient(circle 36px at 55% 90%, rgba(255, 215, 0, 0.27) 0%, rgba(255, 215, 0, 0.13) 50%, rgba(0, 0, 0, 0.06) 55%, transparent 60%),
1222+
radial-gradient(circle 33px at 5% 45%, rgba(78, 205, 196, 0.26) 0%, rgba(78, 205, 196, 0.13) 50%, rgba(0, 0, 0, 0.06) 55%, transparent 60%);
11751223
animation: bubblesFloat 30s linear infinite;
11761224
animation-delay: -15s;
11771225
z-index: -2;

0 commit comments

Comments
 (0)