@@ -6489,3 +6489,272 @@ body.sidebar-collapsed .sidebar-dock .sidebar-footer button {
64896489 pointer-events : auto;
64906490 }
64916491}
6492+
6493+ /* ═══════════════════════════════════════════════════════════════
6494+ COPY BUTTON COMPONENT — Issue #1215
6495+ Copy-to-Clipboard for Code Snippets
6496+ ═══════════════════════════════════════════════════════════════ */
6497+
6498+ /**
6499+ * Code Block Wrapper
6500+ * Creates relative positioning context for absolute button placement
6501+ */
6502+ .code-block-wrapper {
6503+ position : relative !important ;
6504+ display : block;
6505+ }
6506+
6507+ /**
6508+ * Copy Button
6509+ * Reusable, accessible button for copying code to clipboard
6510+ *
6511+ * Features:
6512+ * • Positioned absolutely over code block (top-right)
6513+ * • Keyboard accessible (Tab, Enter, Space)
6514+ * • Screen reader friendly (aria-label)
6515+ * • Mobile & desktop optimized
6516+ * • Theme aware (dark/light mode)
6517+ * • Visual feedback states (default, hover, active, success, error)
6518+ */
6519+ .copy-button {
6520+ /* Layout & Positioning */
6521+ position : absolute;
6522+ top : 8px ;
6523+ right : 8px ;
6524+ z-index : 10 ;
6525+
6526+ /* Dimensions */
6527+ min-width : 60px ;
6528+ padding : 6px 12px ;
6529+ height : 32px ;
6530+
6531+ /* Typography */
6532+ font-family : var (--font-sans );
6533+ font-size : 0.75rem ;
6534+ font-weight : 600 ;
6535+ letter-spacing : 0.5px ;
6536+ text-transform : uppercase;
6537+ line-height : 1 ;
6538+ white-space : nowrap;
6539+
6540+ /* Appearance */
6541+ border : 1px solid var (--border-accent );
6542+ border-radius : 8px ;
6543+ background : rgba (34 , 197 , 94 , 0.08 );
6544+ color : var (--accent );
6545+
6546+ /* Interaction */
6547+ cursor : pointer;
6548+ transition :
6549+ all var (--duration-fast ) ease,
6550+ box-shadow 150ms ease;
6551+
6552+ /* Reset default button styles */
6553+ margin : 0 ;
6554+ box-shadow : 0 1px 3px rgba (0 , 0 , 0 , 0.1 );
6555+
6556+ /* Accessibility */
6557+ outline : 2px solid transparent;
6558+ outline-offset : 2px ;
6559+
6560+ /* Prevent selection during copy action */
6561+ -webkit-user-select : none;
6562+ user-select : none;
6563+ }
6564+
6565+ /**
6566+ * Copy Button — Hover State
6567+ * Elevated appearance with enhanced visibility
6568+ */
6569+ .copy-button : hover {
6570+ background : rgba (34 , 197 , 94 , 0.15 );
6571+ border-color : var (--accent );
6572+ box-shadow : 0 4px 12px rgba (34 , 197 , 94 , 0.2 );
6573+ transform : translateY (-1px );
6574+ }
6575+
6576+ /**
6577+ * Copy Button — Focus State
6578+ * High contrast focus ring for keyboard navigation
6579+ * Critical for accessibility (WCAG AA compliant)
6580+ */
6581+ .copy-button : focus {
6582+ outline-color : var (--accent );
6583+ outline-width : 2px ;
6584+ }
6585+
6586+ .copy-button : focus-visible {
6587+ outline-color : var (--accent );
6588+ outline-width : 2px ;
6589+ outline-offset : 2px ;
6590+ }
6591+
6592+ /**
6593+ * Copy Button — Active State
6594+ * Pressed down appearance when clicked
6595+ */
6596+ .copy-button : active {
6597+ transform : translateY (0 );
6598+ box-shadow : 0 2px 6px rgba (0 , 0 , 0 , 0.15 );
6599+ }
6600+
6601+ /**
6602+ * Copy Button — Success State (After Copy)
6603+ * "Copied!" text with success color and brief animation
6604+ */
6605+ .copy-button .copy-success {
6606+ background : rgba (16 , 185 , 129 , 0.12 );
6607+ border-color : var (--success );
6608+ color : var (--success );
6609+ box-shadow : 0 4px 12px rgba (16 , 185 , 129 , 0.15 );
6610+ animation : copy-pulse 400ms ease-out;
6611+ }
6612+
6613+ /**
6614+ * Copy Button — Error State (Copy Failed)
6615+ * Brief error feedback if clipboard access fails
6616+ */
6617+ .copy-button .copy-error {
6618+ background : rgba (239 , 68 , 68 , 0.12 );
6619+ border-color : var (--danger );
6620+ color : var (--danger );
6621+ box-shadow : 0 4px 12px rgba (239 , 68 , 68 , 0.15 );
6622+ }
6623+
6624+ /**
6625+ * Pulse Animation
6626+ * Gentle scale-up feedback when copy succeeds
6627+ * Helps draw user attention without being jarring
6628+ */
6629+ @keyframes copy-pulse {
6630+ 0% {
6631+ transform : scale (1 );
6632+ }
6633+ 50% {
6634+ transform : scale (1.05 );
6635+ }
6636+ 100% {
6637+ transform : scale (1 );
6638+ }
6639+ }
6640+
6641+ /**
6642+ * Light Mode Adjustments
6643+ * Ensures button is visible and accessible in light theme
6644+ */
6645+ [data-theme = "light" ] .copy-button {
6646+ background : rgba (34 , 197 , 94 , 0.1 );
6647+ border-color : rgba (34 , 197 , 94 , 0.4 );
6648+ color : # 059669 ;
6649+ box-shadow : 0 1px 3px rgba (0 , 0 , 0 , 0.05 );
6650+ }
6651+
6652+ [data-theme = "light" ] .copy-button : hover {
6653+ background : rgba (34 , 197 , 94 , 0.15 );
6654+ border-color : # 059669 ;
6655+ box-shadow : 0 4px 12px rgba (34 , 197 , 94 , 0.15 );
6656+ }
6657+
6658+ [data-theme = "light" ] .copy-button .copy-success {
6659+ background : rgba (16 , 185 , 129 , 0.1 );
6660+ border-color : # 0d9488 ;
6661+ color : # 0d9488 ;
6662+ box-shadow : 0 4px 12px rgba (16 , 185 , 129 , 0.1 );
6663+ }
6664+
6665+ [data-theme = "light" ] .copy-button .copy-error {
6666+ background : rgba (239 , 68 , 68 , 0.1 );
6667+ border-color : # dc2626 ;
6668+ color : # dc2626 ;
6669+ box-shadow : 0 4px 12px rgba (239 , 68 , 68 , 0.1 );
6670+ }
6671+
6672+ /**
6673+ * Mobile Optimizations
6674+ * Larger touch target for mobile devices
6675+ * Prevents accidental clicks
6676+ */
6677+ @media (max-width : 768px ) {
6678+ .copy-button {
6679+ min-width : 50px ;
6680+ padding : 8px 12px ;
6681+ height : 36px ;
6682+ font-size : 0.7rem ;
6683+ top : 6px ;
6684+ right : 6px ;
6685+ }
6686+
6687+ /* Ensure adequate space around button for touch */
6688+ .copy-button ::before {
6689+ content : "" ;
6690+ position : absolute;
6691+ inset : -8px ;
6692+ pointer-events : none;
6693+ }
6694+ }
6695+
6696+ /**
6697+ * High Contrast Mode Support
6698+ * For users with vision impairments
6699+ * Uses forced colors to ensure readability
6700+ */
6701+ @media (prefers-contrast : more) {
6702+ .copy-button {
6703+ border-width : 2px ;
6704+ font-weight : 700 ;
6705+ }
6706+
6707+ .copy-button : focus ,
6708+ .copy-button : focus-visible {
6709+ outline-width : 3px ;
6710+ outline-offset : 3px ;
6711+ }
6712+ }
6713+
6714+ /**
6715+ * Reduced Motion Support
6716+ * Respects user's motion preferences
6717+ * Disables animations for users with vestibular disorders
6718+ */
6719+ @media (prefers-reduced-motion : reduce) {
6720+ .copy-button ,
6721+ .copy-button : hover ,
6722+ .copy-button : active ,
6723+ .copy-button .copy-success ,
6724+ .copy-button .copy-error {
6725+ transition : none;
6726+ animation : none;
6727+ transform : none !important ;
6728+ }
6729+
6730+ @keyframes copy-pulse {
6731+ 0% , 100% {
6732+ transform : none;
6733+ }
6734+ 50% {
6735+ transform : none;
6736+ }
6737+ }
6738+ }
6739+
6740+ /* ═══════════════════════════════════════════════════════════════
6741+ PLAYGROUND COPY BUTTON STATES — Issue #1215
6742+ Visual feedback for editor code copy button
6743+ ═══════════════════════════════════════════════════════════════ */
6744+
6745+ /**
6746+ * Copy Button in Playground
6747+ * Shows success/error feedback with color changes and icon updates
6748+ */
6749+ .btn-panel-action .copy-success {
6750+ background : rgba (16 , 185 , 129 , 0.12 );
6751+ border-color : var (--success );
6752+ color : var (--success );
6753+ animation : copy-pulse 400ms ease-out;
6754+ }
6755+
6756+ .btn-panel-action .copy-error {
6757+ background : rgba (239 , 68 , 68 , 0.12 );
6758+ border-color : var (--danger );
6759+ color : var (--danger );
6760+ }
0 commit comments