From 98f5d839fdd5cbf8a5c5afc8161b5f604dac51c0 Mon Sep 17 00:00:00 2001 From: Paul Bakaus Date: Wed, 4 Mar 2026 09:39:05 -0800 Subject: [PATCH] Improve split comparison: add before/after badges, extend slider range Adds floating corner badges to clarify which side is before/after, removes the "With Skills" divider label, and extends the slider range to account for the skewed divider so it can fully reveal each side. Co-Authored-By: Claude Opus 4.6 --- public/css/main.css | 3 +++ public/css/problem-section.css | 27 ++++++++++++++++++++++++++ public/css/styles.css | 26 +++++++++++++++++++++++++ public/index.html | 6 +++--- public/js/components/glass-terminal.js | 8 ++++---- public/js/components/lens.js | 4 +--- public/js/effects/split-compare.js | 24 +++++++++++++---------- 7 files changed, 78 insertions(+), 20 deletions(-) diff --git a/public/css/main.css b/public/css/main.css index f3828f9e2..75a4c7156 100644 --- a/public/css/main.css +++ b/public/css/main.css @@ -525,6 +525,9 @@ code { width: 100%; max-width: 600px; margin: 0 auto; + padding: 20px; + margin-top: -20px; + margin-bottom: -20px; } .split-container { diff --git a/public/css/problem-section.css b/public/css/problem-section.css index d375d8960..b9cf273e4 100644 --- a/public/css/problem-section.css +++ b/public/css/problem-section.css @@ -79,6 +79,33 @@ transition: transform var(--duration-fast) var(--ease-spring); } +/* Floating corner badges */ +.split-badge { + position: absolute; + top: 10px; + font-size: 0.625rem; + font-weight: 600; + letter-spacing: 0.08em; + text-transform: uppercase; + padding: 3px 8px; + border-radius: 3px; + z-index: 5; + pointer-events: none; +} + +.split-badge--before { + left: 10px; + color: var(--color-ash); + background: var(--color-paper); + border: 1px solid var(--color-mist); +} + +.split-badge--after { + right: 10px; + color: var(--color-paper); + background: var(--color-accent); +} + /* Mobile adjustments */ @media (hover: none) { .split-container::after { diff --git a/public/css/styles.css b/public/css/styles.css index 42da6bef2..81223fa78 100644 --- a/public/css/styles.css +++ b/public/css/styles.css @@ -58,6 +58,29 @@ .split-label-dot { transition: transform var(--duration-fast) var(--ease-spring); } +.split-badge { + position: absolute; + top: 10px; + font-size: 0.625rem; + font-weight: 600; + letter-spacing: 0.08em; + text-transform: uppercase; + padding: 3px 8px; + border-radius: 3px; + z-index: 5; + pointer-events: none; +} +.split-badge--before { + left: 10px; + color: var(--color-ash); + background: var(--color-paper); + border: 1px solid var(--color-mist); +} +.split-badge--after { + right: 10px; + color: var(--color-paper); + background: var(--color-accent); +} @media (hover: none) { .split-container::after { content: '← Swipe →'; @@ -2374,6 +2397,9 @@ code { width: 100%; max-width: 600px; margin: 0 auto; + padding: 20px; + margin-top: -20px; + margin-bottom: -20px; } .split-container { position: relative; diff --git a/public/index.html b/public/index.html index 8d8ce88fe..c770cfe64 100644 --- a/public/index.html +++ b/public/index.html @@ -79,6 +79,7 @@
+ Before
@@ -100,6 +101,7 @@
+ After

Introducing

Thoughtful Design

@@ -108,9 +110,7 @@
-
- With Skills -
+
diff --git a/public/js/components/glass-terminal.js b/public/js/components/glass-terminal.js index 338c51d16..68b1c0d3d 100644 --- a/public/js/components/glass-terminal.js +++ b/public/js/components/glass-terminal.js @@ -219,8 +219,8 @@ function updateTerminal(cmd, container, allCommands) { currentSplitInstance = initSplitCompare(splitComparison, { defaultPosition: 50, skewOffset: 8, - minPosition: 5, - maxPosition: 95 + + }); } } @@ -330,8 +330,8 @@ function setupMobileInteractions(commands) { currentSplitInstance = initSplitCompare(splitComparison, { defaultPosition: 50, skewOffset: 6, - minPosition: 10, - maxPosition: 90 + + }); } }); diff --git a/public/js/components/lens.js b/public/js/components/lens.js index c3fc87eb7..789cbc463 100644 --- a/public/js/components/lens.js +++ b/public/js/components/lens.js @@ -6,9 +6,7 @@ export function initLensEffect() { initSplitCompare(container, { defaultPosition: 70, - skewOffset: 8, - minPosition: 5, - maxPosition: 95 + skewOffset: 8 }); } diff --git a/public/js/effects/split-compare.js b/public/js/effects/split-compare.js index 66ffd89b1..b1e81d26a 100644 --- a/public/js/effects/split-compare.js +++ b/public/js/effects/split-compare.js @@ -11,8 +11,8 @@ export function initSplitCompare(container, options = {}) { const { defaultPosition = 70, skewOffset = 8, - minPosition = 5, - maxPosition = 95, + minPosition = -skewOffset, + maxPosition = 100 + skewOffset, lerpSpeed = 0.15, animationThreshold = 40, // Re-trigger animations when crossing this threshold onCrossThreshold = null // Callback when crossing threshold toward "after" side @@ -89,7 +89,8 @@ export function initSplitCompare(container, options = {}) { function handleMouseMove(e) { if (isHovering) { const rect = splitContainer.getBoundingClientRect(); - targetX = ((e.clientX - rect.left) / rect.width) * 100; + const range = 100 + 2 * skewOffset; + targetX = ((e.clientX - rect.left) / rect.width) * range - skewOffset; startAnimation(); } } @@ -142,10 +143,13 @@ export function initSplitCompare(container, options = {}) { } } - // Attach listeners - splitContainer.addEventListener('mouseenter', handleMouseEnter); - splitContainer.addEventListener('mouseleave', handleMouseLeave); - splitContainer.addEventListener('mousemove', handleMouseMove); + // Use the parent container for mouse events to create a larger hit area + const hitArea = splitContainer.parentElement || splitContainer; + + // Attach listeners — mouse events on the wider hit area + hitArea.addEventListener('mouseenter', handleMouseEnter); + hitArea.addEventListener('mouseleave', handleMouseLeave); + hitArea.addEventListener('mousemove', handleMouseMove); splitContainer.addEventListener('touchstart', handleTouchStart); splitContainer.addEventListener('touchend', handleTouchEnd); splitContainer.addEventListener('touchmove', handleTouchMove, { passive: false }); @@ -156,9 +160,9 @@ export function initSplitCompare(container, options = {}) { // Return cleanup function return { destroy() { - splitContainer.removeEventListener('mouseenter', handleMouseEnter); - splitContainer.removeEventListener('mouseleave', handleMouseLeave); - splitContainer.removeEventListener('mousemove', handleMouseMove); + hitArea.removeEventListener('mouseenter', handleMouseEnter); + hitArea.removeEventListener('mouseleave', handleMouseLeave); + hitArea.removeEventListener('mousemove', handleMouseMove); splitContainer.removeEventListener('touchstart', handleTouchStart); splitContainer.removeEventListener('touchend', handleTouchEnd); splitContainer.removeEventListener('touchmove', handleTouchMove);