Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

**Where code meets conscience.** A brutalist × cyberpunk portfolio built with Next.js 16.

[![Version](https://img.shields.io/badge/version-1.1.3-cyan?logo=github)](package.json)
[![Version](https://img.shields.io/badge/version-1.1.4-cyan?logo=github)](package.json)
[![Security: SLSA Level 3](https://img.shields.io/badge/SLSA-Level%203-brightgreen)](https://github.com/devakesu/devakesu-web/attestations)
[![Security Scan: Trivy](https://img.shields.io/badge/Security-Trivy%20Scanned-blue)](.github/workflows/deploy.yml)
[![Attestations](https://img.shields.io/badge/Attestations-Enabled-success)](https://github.com/devakesu/devakesu-web/attestations)
Expand Down Expand Up @@ -414,4 +414,4 @@ _Love is the only way to rescue humanity from all evils._
---

**Last Updated**: March 02, 2026
**Version**: 1.1.3
**Version**: 1.1.4
2 changes: 1 addition & 1 deletion SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,4 +149,4 @@ We appreciate security researchers who responsibly disclose vulnerabilities.
---

**Last Updated**: March 02, 2026
**Version**: 1.1.3
**Version**: 1.1.4
43 changes: 39 additions & 4 deletions app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {
import { FaXTwitter } from "react-icons/fa6";

const SCROLL_LOCK_DURATION = 800;
const WHEEL_SNAP_THRESHOLD_PX = 50;

// Throttle utility for performance optimization
const throttle = <T extends (...args: unknown[]) => void>(
Expand Down Expand Up @@ -650,7 +651,41 @@ export default function Home() {
}, SCROLL_LOCK_DURATION);
};

const rootComputedStyle = window.getComputedStyle(document.documentElement);
const rawLineHeight = rootComputedStyle.lineHeight;

const parsedLineHeight = Number.parseFloat(rawLineHeight);
const cachedLineHeight: number = (() => {
if (Number.isFinite(parsedLineHeight) && parsedLineHeight > 0) {
return parsedLineHeight;
}
const fontSize = Number.parseFloat(rootComputedStyle.fontSize);
const derivedFromFontSize = Number.isFinite(fontSize) && fontSize > 0
? fontSize * 1.2
: 16;
return derivedFromFontSize;
})();
const getNormalizedWheelDeltaY = (event: WheelEvent): number => {
// Firefox on Linux often reports wheel deltas in lines/pages instead of
// pixels. Normalize to px so threshold checks stay consistent.
if (event.deltaMode === WheelEvent.DOM_DELTA_LINE) {
return event.deltaY * cachedLineHeight;
}

if (event.deltaMode === WheelEvent.DOM_DELTA_PAGE) {
return event.deltaY * window.innerHeight;
}

return event.deltaY;
};

const handleWheel = (event: WheelEvent) => {
const normalizedDeltaY = getNormalizedWheelDeltaY(event);

if (normalizedDeltaY === 0) {
return;
}

// Setup scrolling ends detector to reset inertia blocking
if (scrollEndTimeoutRef.current) {
clearTimeout(scrollEndTimeoutRef.current);
Expand All @@ -666,12 +701,12 @@ export default function Home() {
// but only if it's not a modifying shortcut or inside a scrollable div
if (
event.ctrlKey ||
allowNativeScroll(event.target, event.deltaY > 0 ? 1 : -1)
allowNativeScroll(event.target, normalizedDeltaY > 0 ? 1 : -1)
) {
return;
}

const direction = event.deltaY > 0 ? 1 : -1;
const direction = normalizedDeltaY > 0 ? 1 : -1;

// Allow free native scrolling within sections taller than the viewport
if (canScrollWithinSection(direction)) {
Expand Down Expand Up @@ -705,7 +740,7 @@ export default function Home() {

// Trackpads fire hundreds of tiny wheel events. We use an accumulator
// to ensure a deliberate swipe happens, ignoring delicate resting finger movements
wheelAccumulatorRef.current += event.deltaY;
wheelAccumulatorRef.current += normalizedDeltaY;

if (wheelLockTimeoutRef.current) {
clearTimeout(wheelLockTimeoutRef.current);
Expand All @@ -717,7 +752,7 @@ export default function Home() {
}, 50);

// Require a larger accumulation for trackpads to trigger the next section
if (Math.abs(wheelAccumulatorRef.current) < 50) {
if (Math.abs(wheelAccumulatorRef.current) < WHEEL_SNAP_THRESHOLD_PX) {
return;
}

Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "devakesu-web",
"version": "1.1.3",
"version": "1.1.4",
"private": true,
"engines": {
"node": ">=20.19.0"
Expand Down