From 909851c377d688a52c28bbf8bc9b84b82c9c4619 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 12 May 2026 09:27:50 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=8E=A8=20Palette:=20Add=20Copy=20to=20Cli?= =?UTF-8?q?pboard=20for=20code=20blocks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Added Copy button to .code-window in os2.html - Implemented copyCode JS function with navigator.clipboard and fallback - Added success feedback state for 2 seconds - Ensured keyboard visibility via focus:opacity-100 Co-authored-by: rtech-technologies <254326487+rtech-technologies@users.noreply.github.com> --- .jules/palette.md | 3 +++ os2.html | 39 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 .jules/palette.md diff --git a/.jules/palette.md b/.jules/palette.md new file mode 100644 index 0000000..04cd041 --- /dev/null +++ b/.jules/palette.md @@ -0,0 +1,3 @@ +## 2026-04-18 - Contextual Action Visibility +**Learning:** Using `opacity-0 group-hover:opacity-100` for contextual actions (like copy buttons) creates a clean UI but can hide functionality from keyboard users. Adding `focus:opacity-100` is a mandatory companion to ensure the element becomes visible when tabbed into. +**Action:** Always pair `group-hover:opacity-100` with `focus:opacity-100` for interactive elements to maintain WCAG accessibility. diff --git a/os2.html b/os2.html index fb439ec..5ae8519 100644 --- a/os2.html +++ b/os2.html @@ -84,7 +84,10 @@
; OS*2 SYSTEM_INIT move rdi 10 ; ALLOC_SOVEREIGNTY @@ -170,6 +173,40 @@{ + if (navigator.clipboard && navigator.clipboard.writeText) { + return navigator.clipboard.writeText(code); + } else { + const textArea = document.createElement("textarea"); + textArea.value = code; + document.body.appendChild(textArea); + textArea.select(); + try { + document.execCommand('copy'); + } catch (err) { + console.error('Fallback copy failed', err); + } + document.body.removeChild(textArea); + return Promise.resolve(); + } + }; + + performCopy().then(() => { + const originalText = btn.innerText; + btn.innerText = "COPIED!"; + btn.classList.add('!bg-lime-500', '!text-black'); + setTimeout(() => { + btn.innerText = originalText; + btn.classList.remove('!bg-lime-500', '!text-black'); + }, 2000); + }); + } + window.onload = checkAvailability;