Compare commits

..

2 Commits

Author SHA1 Message Date
368ad9b48e Promote ascii-frame-outer to GPU layer to stop hover blink
The body::before scanline overlay (position:fixed, z-index:9999) requires
the compositor to re-blend over the section every time a CPU repaint
happens inside it. Hover state entry/exit triggers these repaints, causing
a visible blink as the compositor flushes.

Fixes:
- Add will-change:transform + transform:translateZ(0) to ascii-frame-outer
  to promote it to its own GPU compositing layer, isolating its repaints
  from the scanline compositing pass
- Convert corner-pulse and subtle-pulse from text-shadow (CPU repaint)
  to opacity (GPU composited) to eliminate continuous repaint pressure
  inside the section

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 11:35:38 -04:00
3497c4cb47 Fix ascii-frame-outer blink: remove compositor layer thrashing on hover
Four root causes removed:
- body { transition: all } — forced browser to check all CSS properties
  on every hover event across the entire page
- a:not(.btn)::after underline: width+box-shadow transition replaced with
  opacity transition — width repaints paint layer, box-shadow forced parent
  section repaint; opacity is GPU-composited and doesn't repaint ancestors
- .ticket-link:hover { transform: translateX } — created/destroyed GPU
  compositor layer on every ticket ID hover; removed, scoped transition
  to specific non-layout properties
- .btn:hover { transform: translateY } in ticket.css — same layer issue

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 11:25:18 -04:00
2 changed files with 11 additions and 12 deletions

View File

@@ -97,7 +97,6 @@ body {
padding: var(--spacing-md); padding: var(--spacing-md);
background-color: var(--bg-primary); background-color: var(--bg-primary);
color: var(--text-primary); color: var(--text-primary);
transition: var(--transition-default);
position: relative; position: relative;
} }
@@ -271,15 +270,15 @@ a:not(.btn)::after {
position: absolute; position: absolute;
bottom: -2px; bottom: -2px;
left: 0; left: 0;
width: 0; width: 100%;
height: 1px; height: 1px;
background: currentColor; background: currentColor;
box-shadow: 0 0 5px currentColor; opacity: 0;
transition: width 0.3s ease; transition: opacity 0.2s ease;
} }
a:not(.btn):hover::after { a:not(.btn):hover::after {
width: 100%; opacity: 1;
} }
/* Matrix-style rain effect on hover for stats */ /* Matrix-style rain effect on hover for stats */
@@ -992,6 +991,8 @@ h1 {
padding: 0; padding: 0;
background: var(--bg-primary); background: var(--bg-primary);
margin-bottom: 2rem; margin-bottom: 2rem;
will-change: transform;
transform: translateZ(0);
} }
.ascii-frame-outer::before { .ascii-frame-outer::before {
@@ -1030,8 +1031,8 @@ h1 {
} }
@keyframes corner-pulse { @keyframes corner-pulse {
0%, 100% { text-shadow: var(--glow-green); } 0%, 100% { opacity: 0.7; }
50% { text-shadow: var(--glow-green-intense); } 50% { opacity: 1; }
} }
.bottom-left-corner { .bottom-left-corner {
@@ -1087,8 +1088,8 @@ h1 {
} }
@keyframes subtle-pulse { @keyframes subtle-pulse {
0%, 100% { text-shadow: var(--glow-amber); } 0%, 100% { opacity: 0.75; }
50% { text-shadow: var(--glow-amber-intense); } 50% { opacity: 1; }
} }
.ascii-section-header::before { .ascii-section-header::before {
@@ -2830,7 +2831,7 @@ input[type="checkbox"]:checked {
border-radius: 0; border-radius: 0;
display: inline-block; display: inline-block;
border: 1px solid transparent; border: 1px solid transparent;
transition: all 0.3s ease; transition: background 0.2s ease, border-color 0.2s ease, text-shadow 0.2s ease;
text-shadow: var(--glow-green); text-shadow: var(--glow-green);
} }
@@ -2844,7 +2845,6 @@ input[type="checkbox"]:checked {
background: rgba(0, 255, 65, 0.2); background: rgba(0, 255, 65, 0.2);
border-color: var(--terminal-green); border-color: var(--terminal-green);
text-shadow: var(--glow-green-intense); text-shadow: var(--glow-green-intense);
transform: translateX(2px);
} }
/* ===== PAGINATION STYLES ===== */ /* ===== PAGINATION STYLES ===== */

View File

@@ -564,7 +564,6 @@ textarea.editable {
} }
.btn:hover { .btn:hover {
transform: translateY(-2px);
box-shadow: 0 2px 4px rgba(0,0,0,0.1); box-shadow: 0 2px 4px rgba(0,0,0,0.1);
} }