Skip to content

Commit f7e649c

Browse files
committed
Surprise me hover glow; screenshot mode
1 parent 17bb02d commit f7e649c

File tree

4 files changed

+151
-40
lines changed

4 files changed

+151
-40
lines changed

src/_includes/footer.njk

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,14 @@
7272
<span class="opacity-50">+1 LVL</span>
7373
</button>
7474

75+
<button
76+
onclick="toggleScreenshotMode()"
77+
class="w-full flex justify-between items-center p-2 mb-2 rounded-md border border-white/5 bg-white/5 text-[10px] font-mono text-slate-400 hover:bg-white/10 hover:border-slate-400 hover:translate-x-1 transition-all duration-200 cursor-pointer"
78+
>
79+
<span class="flex items-center gap-2">📸 SCREENSHOT</span>
80+
<span class="opacity-50">[5 seconds]</span>
81+
</button>
82+
7583
<div class="pt-2">
7684
<button onclick="localStorage.clear(); location.reload();" class="w-full py-3 bg-blue-600/20 hover:bg-blue-600/40 text-blue-400 text-[10px] font-bold border border-blue-500/30 rounded-lg transition-all">
7785
RESET_PLAYER_DATA

src/_includes/header.njk

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,11 @@
3434

3535
<div class="flex items-center gap-3 md:gap-4">
3636
{% if page.url == "/" %}
37-
<button onclick="scrollToRandomUser()"
38-
class="surprise-btn px-4 py-2 md:px-6 md:py-3 bg-accent text-white text-[10px] md:text-[11px] font-black uppercase tracking-widest rounded-xl hover:brightness-110 hover:-translate-y-0.5 transition-all shadow-lg shadow-accent/20">
39-
✨ Surprise
37+
<button
38+
onclick="scrollToRandomUser()"
39+
class="surprise-btn bg-blue-600 text-white px-8 py-3 rounded-full font-black uppercase tracking-widest transition-all active:scale-95 shadow-lg shadow-blue-500/30"
40+
>
41+
✨ Surprise Me
4042
</button>
4143
{% endif %}
4244

src/assets/css/style.css

Lines changed: 74 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -42,38 +42,36 @@ html, body {
4242
/**
4343
* 2. USER CARDS - DYNAMIC & STATIC
4444
*/
45-
.user-card h2 {
46-
/* Dynamic color from theme logic */
47-
color: var(--accent) !important;
48-
font-weight: 800;
49-
transition: color 0.3s ease; /* Only animate the color fade, not movement */
50-
margin-bottom: 0.5rem;
51-
}
52-
53-
/* Hover state: No movement, just a slight brightness shift */
54-
.user-card:hover h2 {
55-
filter: brightness(1.1);
56-
}
57-
5845
/**
59-
* 3. PROFILE LINKS - THEMED
46+
* DYNAMIC COLORING (NO ANIMATION)
6047
*/
48+
.user-card h2,
6149
.profile-link,
62-
.user-card a[href*="github"],
63-
.user-card a[href*="linkedin"] {
50+
.user-card a {
6451
color: var(--accent) !important;
65-
font-weight: 700;
52+
font-weight: 800;
6653
text-decoration: none;
67-
transition: opacity 0.2s ease;
68-
display: inline-flex;
69-
align-items: center;
70-
gap: 0.4rem;
54+
/* Animate ONLY the color property when theme changes */
55+
transition: color 0.4s ease, opacity 0.2s ease;
56+
}
57+
58+
/* Static Hover: No movement */
59+
.user-card:hover h2 {
60+
filter: brightness(1.2);
7161
}
7262

7363
.profile-link:hover,
7464
.user-card a:hover {
7565
text-decoration: underline;
76-
opacity: 0.8; /* Subtle visual feedback instead of moving */
66+
opacity: 0.8;
67+
}
68+
69+
/* Button to trigger Screenshot Mode in the Dev Panel */
70+
.screenshot-btn {
71+
border-color: var(--text-muted) !important;
72+
color: var(--text-muted) !important;
73+
font-size: 0.6rem !important;
74+
margin-top: 10px;
7775
}
7876

7977
/* If your links look like tags/pills */
@@ -291,3 +289,57 @@ html body #dev-tools[data-lock="true"] {
291289
}
292290

293291
.konami-roll { animation: konami-barrel-roll 2s cubic-bezier(0.45, 0.05, 0.55, 0.95); }
292+
293+
/**
294+
* FANCY USER SELECTION EFFECT
295+
*/
296+
@keyframes fancy-ping {
297+
0% {
298+
box-shadow: 0 0 0 0 rgba(var(--accent-rgb), 0.7);
299+
}
300+
70% {
301+
box-shadow: 0 0 0 20px rgba(var(--accent-rgb), 0);
302+
}
303+
100% {
304+
box-shadow: 0 0 0 0 rgba(var(--accent-rgb), 0);
305+
}
306+
}
307+
/* Ensure the card can show the trace glow */
308+
.user-card.selected-fancy {
309+
z-index: 50;
310+
overflow: visible !important;
311+
transform: scale(1.02);
312+
transition: transform 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275);
313+
}
314+
315+
.border-trace {
316+
position: absolute;
317+
inset: -2px; /* Slightly outside the card border */
318+
width: calc(100% + 4px);
319+
height: calc(100% + 4px);
320+
pointer-events: none;
321+
fill: none;
322+
}
323+
324+
.border-trace rect {
325+
stroke-width: 4px;
326+
stroke-linecap: round;
327+
/* Perimeter length - 2500px is a safe bet for these cards */
328+
stroke-dasharray: 2500;
329+
stroke-dashoffset: 2500;
330+
animation: retrace-sequence 7.5s linear forwards;
331+
}
332+
333+
@keyframes retrace-sequence {
334+
0% {
335+
stroke-dashoffset: 2500;
336+
stroke: var(--accent);
337+
filter: drop-shadow(0 0 8px var(--accent));
338+
}
339+
100% {
340+
stroke-dashoffset: 0;
341+
/* Cycle through colors while drawing */
342+
stroke: var(--accent);
343+
filter: drop-shadow(0 0 12px var(--accent)) hue-rotate(360deg);
344+
}
345+
}

src/assets/js/script.js

Lines changed: 64 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -193,8 +193,8 @@ function applyTheme(theme) {
193193
html.style.setProperty('--bg-footer', `hsl(${h}, 40%, 5%)`); // Deepest
194194
html.style.setProperty('--text-main', `hsl(${h}, 20%, 95%)`); // Near White
195195
html.style.setProperty('--text-muted', `hsl(${h}, 15%, 70%)`); // Softened
196-
html.style.setProperty('--accent', `hsl(${h}, 90%, 65%)`); // Vivid Pop
197-
html.style.setProperty('--accent-light', `hsla(${h}, 90%, 65%, 0.15)`);
196+
html.style.setProperty('--accent', `hsl(${h}, 95%, 70%)`); // Vivid Pop
197+
html.style.setProperty('--accent-light', `hsla(${h}, 95%, 70%, 0.2)`);
198198
html.style.setProperty('--border-color', `hsl(${h}, 30%, 20%)`);
199199

200200
if (heart) {
@@ -439,32 +439,81 @@ window.startSelfDestruct = function() {
439439
function scrollToRandomUser() {
440440
playSound('click');
441441

442-
// 1. Secret Unlock Logic
443442
surpriseClickCount++;
444443
if (surpriseClickCount >= 5) {
445444
surpriseClickCount = 0;
446-
// This triggers the Matrix overlay
447445
triggerSecretUnlock('matrix');
446+
return;
448447
}
449448

450-
// 2. Scrolling Logic
451449
const cards = document.querySelectorAll('.user-card');
452-
if (cards.length === 0) {
453-
console.warn("No .user-card elements found to scroll to.");
454-
return;
455-
}
450+
if (cards.length === 0) return;
456451

457-
// Clear previous highlights
458-
cards.forEach(c => c.classList.remove('highlight-pulse'));
452+
// Clean up previous selection
453+
cards.forEach(c => {
454+
c.classList.remove('selected-fancy');
455+
const oldTrace = c.querySelector('.border-trace');
456+
if (oldTrace) oldTrace.remove();
457+
});
459458

460-
// Pick a random card and scroll
461459
const randomCard = cards[Math.floor(Math.random() * cards.length)];
462-
randomCard.scrollIntoView({ behavior: 'smooth', block: 'center' }); // Changed to center for better visibility
460+
randomCard.scrollIntoView({ behavior: 'smooth', block: 'center' });
461+
462+
setTimeout(() => {
463+
playSound('levelUp');
464+
randomCard.classList.add('selected-fancy');
465+
466+
// Inject the Tracing SVG
467+
const svgNamespace = "http://www.w3.org/2000/svg";
468+
const svg = document.createElementNS(svgNamespace, "svg");
469+
const rect = document.createElementNS(svgNamespace, "rect");
470+
471+
svg.setAttribute("class", "border-trace");
472+
rect.setAttribute("fill", "none");
473+
rect.setAttribute("width", "100%");
474+
rect.setAttribute("height", "100%");
475+
476+
svg.appendChild(rect);
477+
randomCard.appendChild(svg);
463478

464-
// Add the pulse animation
465-
randomCard.classList.add('highlight-pulse');
479+
// Remove trace and fancy class after the 7.5s animation ends
480+
setTimeout(() => {
481+
randomCard.classList.remove('selected-fancy');
482+
svg.remove();
483+
}, 7500);
484+
}, 400);
466485
}
467486

487+
/**
488+
* UTILITY: SCREENSHOT MODE
489+
*/
490+
window.toggleScreenshotMode = function() {
491+
const devPanel = document.getElementById('dev-tools');
492+
const header = document.querySelector('header');
493+
const footer = document.querySelector('footer');
494+
const gameStats = document.getElementById('game-stats');
495+
496+
// Hide everything
497+
[devPanel, header, footer, gameStats].forEach(el => {
498+
if(el) el.style.opacity = '0';
499+
if(el) el.style.pointerEvents = 'none';
500+
});
501+
502+
// Show a tiny notification that it's active
503+
const toast = document.createElement('div');
504+
toast.style.cssText = "position:fixed; bottom:20px; left:50%; transform:translateX(-50%); color:var(--text-muted); font-family:monospace; font-size:10px; z-index:9999;";
505+
toast.innerText = "SCREENSHOT MODE ACTIVE - RESTORING IN 5S";
506+
document.body.appendChild(toast);
507+
508+
setTimeout(() => {
509+
[devPanel, header, footer, gameStats].forEach(el => {
510+
if(el) el.style.opacity = '1';
511+
if(el) el.style.pointerEvents = 'auto';
512+
});
513+
toast.remove();
514+
}, 5000);
515+
};
516+
468517
/**
469518
* 8. INITIALIZATION
470519
*/

0 commit comments

Comments
 (0)