diff --git a/css/style.css b/css/style.css
index 63ee3a3..3dbaeab 100644
--- a/css/style.css
+++ b/css/style.css
@@ -1648,9 +1648,8 @@ footer.footer-modern a:hover {
width: 32px;
height: 32px;
padding: 0;
- display: inline-flex;
- align-items: center;
- justify-content: center;
+ display: grid;
+ place-items: center;
border: 1px solid var(--border-color);
border-radius: var(--radius-sm);
background: var(--bg-subtle);
@@ -1677,14 +1676,34 @@ footer.footer-modern a:hover {
border-color: var(--accent);
}
-.code-copy i {
+.code-copy svg {
+ display: block;
+}
+
+/* "Copied" toast — pops up just left of the button */
+.code-copy-toast {
+ position: absolute;
+ top: 0.5rem;
+ right: calc(0.5rem + 32px + 8px); /* clears the 32px button + gap */
+ height: 32px;
display: flex;
align-items: center;
- justify-content: center;
- width: 100%;
- height: 100%;
- font-size: 0.95rem;
- line-height: 1;
+ padding: 0 0.6rem;
+ border-radius: var(--radius-sm);
+ background: var(--accent);
+ color: var(--accent-contrast);
+ font-size: var(--font-size-xs);
+ font-weight: 600;
+ white-space: nowrap;
+ pointer-events: none;
+ opacity: 0;
+ transform: translateX(6px);
+ transition: opacity 0.15s ease, transform 0.15s ease;
+}
+
+.code-copy-toast.is-visible {
+ opacity: 1;
+ transform: translateX(0);
}
/* Touch devices have no hover — keep the button discoverable */
diff --git a/js/blowdit.js b/js/blowdit.js
index ae4d4df..b499a4d 100644
--- a/js/blowdit.js
+++ b/js/blowdit.js
@@ -561,6 +561,16 @@
});
}
+ // Inline SVGs — centred in their own viewBox, so no icon-font baseline /
+ // side-bearing offsets to fight.
+ var SVG_COPY = '';
+ var SVG_CHECK = '';
+
function enhance(pre) {
// Skip if already wrapped
if (pre.parentNode && pre.parentNode.classList &&
@@ -575,7 +585,12 @@
btn.type = 'button';
btn.className = 'code-copy';
btn.setAttribute('aria-label', T.copyCode);
- btn.innerHTML = '';
+ btn.innerHTML = SVG_COPY;
+
+ // "Copied" toast that pops up next to the button
+ var toast = document.createElement('span');
+ toast.className = 'code-copy-toast';
+ toast.textContent = T.copied;
var resetTimer = null;
btn.addEventListener('click', function () {
@@ -583,18 +598,21 @@
var text = (code ? code.textContent : pre.textContent) || '';
copyText(text).then(function () {
btn.classList.add('is-copied');
- btn.innerHTML = '';
+ btn.innerHTML = SVG_CHECK;
btn.setAttribute('aria-label', T.copied);
+ toast.classList.add('is-visible');
clearTimeout(resetTimer);
resetTimer = setTimeout(function () {
btn.classList.remove('is-copied');
- btn.innerHTML = '';
+ btn.innerHTML = SVG_COPY;
btn.setAttribute('aria-label', T.copyCode);
- }, 1800);
+ toast.classList.remove('is-visible');
+ }, 1000);
}).catch(function () {});
});
wrap.appendChild(btn);
+ wrap.appendChild(toast);
}
var pres = document.querySelectorAll('.content pre, .tab-panel pre');