Skip to content

Commit 7ae59a7

Browse files
authored
Website Update
1 parent 27784cb commit 7ae59a7

3 files changed

Lines changed: 122 additions & 68 deletions

File tree

docs/assets/css/style.css

Lines changed: 52 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1519,13 +1519,13 @@ a {
15191519
}
15201520

15211521
.discipline-stack-card__surface {
1522-
--discipline-bg-1: #181e2e;
1523-
--discipline-bg-2: #0f131d;
1524-
--discipline-edge: rgba(127, 149, 255, 0.12);
1522+
--discipline-bg-1: #10131d;
1523+
--discipline-bg-2: #06090f;
1524+
--discipline-edge: rgba(127, 149, 255, 0.095);
15251525
--discipline-shadow: rgba(8, 11, 18, 0.16);
1526-
--discipline-sheen: rgba(255, 255, 255, 0.018);
1526+
--discipline-sheen: rgba(255, 255, 255, 0.012);
15271527
--discipline-depth-dim: 0;
1528-
--discipline-surface-lift: 0.028;
1528+
--discipline-surface-lift: 0.018;
15291529
position: relative;
15301530
display: grid;
15311531
grid-template-rows: auto auto auto;
@@ -1540,13 +1540,13 @@ a {
15401540
border-radius: 36px;
15411541
background:
15421542
linear-gradient(180deg, rgba(255, 255, 255, var(--discipline-surface-lift)) 0%, rgba(255, 255, 255, 0) 16%),
1543-
linear-gradient(180deg, rgba(0, 0, 0, var(--discipline-depth-dim)) 0%, rgba(0, 0, 0, calc(var(--discipline-depth-dim) + 0.03)) 100%),
1543+
linear-gradient(180deg, rgba(0, 0, 0, var(--discipline-depth-dim)) 0%, rgba(0, 0, 0, calc(var(--discipline-depth-dim) + 0.04)) 100%),
15441544
radial-gradient(124% 104% at 12% 0%, var(--discipline-sheen), transparent 46%),
15451545
linear-gradient(180deg, var(--discipline-bg-1) 0%, var(--discipline-bg-2) 100%);
15461546
box-shadow:
15471547
inset 0 0 0 1px var(--discipline-edge),
1548-
0 16px 28px rgba(0, 0, 0, 0.14),
1549-
0 8px 18px var(--discipline-shadow);
1548+
0 14px 24px rgba(0, 0, 0, 0.12),
1549+
0 6px 16px var(--discipline-shadow);
15501550
overflow: hidden;
15511551
transition:
15521552
transform 240ms cubic-bezier(0.22, 1, 0.36, 1),
@@ -1562,43 +1562,43 @@ a {
15621562
}
15631563

15641564
.discipline-stack-card[data-tone="development"] .discipline-stack-card__surface {
1565-
--discipline-bg-1: #141d31;
1566-
--discipline-bg-2: #0b111c;
1567-
--discipline-edge: rgba(112, 138, 255, 0.11);
1565+
--discipline-bg-1: #0f1728;
1566+
--discipline-bg-2: #060a12;
1567+
--discipline-edge: rgba(112, 138, 255, 0.085);
15681568
--discipline-shadow: rgba(24, 41, 92, 0.15);
1569-
--discipline-sheen: rgba(110, 139, 255, 0.034);
1569+
--discipline-sheen: rgba(110, 139, 255, 0.02);
15701570
}
15711571

15721572
.discipline-stack-card[data-tone="engineering"] .discipline-stack-card__surface {
1573-
--discipline-bg-1: #1c1513;
1574-
--discipline-bg-2: #0f0c11;
1575-
--discipline-edge: rgba(223, 141, 93, 0.115);
1573+
--discipline-bg-1: #17110f;
1574+
--discipline-bg-2: #09070a;
1575+
--discipline-edge: rgba(223, 141, 93, 0.09);
15761576
--discipline-shadow: rgba(84, 50, 35, 0.15);
1577-
--discipline-sheen: rgba(223, 141, 93, 0.032);
1577+
--discipline-sheen: rgba(223, 141, 93, 0.018);
15781578
}
15791579

15801580
.discipline-stack-card[data-tone="design"] .discipline-stack-card__surface {
1581-
--discipline-bg-1: #1a1724;
1582-
--discipline-bg-2: #0f0d14;
1583-
--discipline-edge: rgba(165, 127, 233, 0.108);
1581+
--discipline-bg-1: #15121d;
1582+
--discipline-bg-2: #09080d;
1583+
--discipline-edge: rgba(165, 127, 233, 0.084);
15841584
--discipline-shadow: rgba(64, 44, 99, 0.15);
1585-
--discipline-sheen: rgba(176, 144, 234, 0.03);
1585+
--discipline-sheen: rgba(176, 144, 234, 0.018);
15861586
}
15871587

15881588
.discipline-stack-card[data-tone="music"] .discipline-stack-card__surface {
1589-
--discipline-bg-1: #1d1318;
1590-
--discipline-bg-2: #100c11;
1591-
--discipline-edge: rgba(201, 109, 95, 0.108);
1589+
--discipline-bg-1: #170f13;
1590+
--discipline-bg-2: #09070a;
1591+
--discipline-edge: rgba(201, 109, 95, 0.084);
15921592
--discipline-shadow: rgba(74, 38, 42, 0.15);
1593-
--discipline-sheen: rgba(211, 128, 112, 0.03);
1593+
--discipline-sheen: rgba(211, 128, 112, 0.018);
15941594
}
15951595

15961596
.discipline-stack-card[data-tone="research"] .discipline-stack-card__surface {
1597-
--discipline-bg-1: #132026;
1598-
--discipline-bg-2: #0b1117;
1599-
--discipline-edge: rgba(106, 184, 161, 0.108);
1597+
--discipline-bg-1: #101b20;
1598+
--discipline-bg-2: #060b10;
1599+
--discipline-edge: rgba(106, 184, 161, 0.084);
16001600
--discipline-shadow: rgba(32, 69, 63, 0.15);
1601-
--discipline-sheen: rgba(106, 184, 161, 0.03);
1601+
--discipline-sheen: rgba(106, 184, 161, 0.018);
16021602
}
16031603

16041604
.discipline-stack-card__header {
@@ -1664,6 +1664,8 @@ a {
16641664
line-height: 1;
16651665
flex: 0 0 auto;
16661666
overflow: hidden;
1667+
outline: none;
1668+
box-shadow: none;
16671669
}
16681670

16691671
.discipline-stack-card__arsenal[data-arsenal-kind="development"] .discipline-pill__icon {
@@ -1680,19 +1682,39 @@ a {
16801682

16811683
.discipline-pill__icon img,
16821684
.discipline-pill__icon svg {
1683-
width: 0.92rem;
1684-
height: 0.92rem;
1685+
width: 0.86rem;
1686+
height: 0.86rem;
16851687
display: block;
16861688
flex: 0 0 auto;
16871689
}
16881690

16891691
.discipline-pill__icon img {
16901692
object-fit: contain;
1693+
outline: none;
1694+
box-shadow: none;
1695+
pointer-events: none;
1696+
user-select: none;
1697+
-webkit-user-drag: none;
16911698
}
16921699

16931700
.discipline-stack-card__arsenal[data-arsenal-kind="development"] .discipline-pill__icon img {
16941701
filter: brightness(0) saturate(100%) invert(92%) sepia(7%) saturate(304%) hue-rotate(193deg) brightness(101%) contrast(96%);
16951702
opacity: 0.94;
1703+
width: 0.72rem;
1704+
height: 0.72rem;
1705+
}
1706+
1707+
.discipline-pill--python .discipline-pill__icon img,
1708+
.discipline-pill--swift .discipline-pill__icon img {
1709+
width: 0.7rem;
1710+
height: 0.7rem;
1711+
}
1712+
1713+
.discipline-pill--kotlin .discipline-pill__icon img,
1714+
.discipline-pill--javascript .discipline-pill__icon img,
1715+
.discipline-pill--html .discipline-pill__icon img {
1716+
width: 0.66rem;
1717+
height: 0.66rem;
16961718
}
16971719

16981720
.discipline-pill__icon svg {

docs/assets/js/shell.js

Lines changed: 68 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
const body = document.body;
55
const base = (body?.getAttribute('data-base') || '.').trim();
6-
const assetVersion = '20260410f';
6+
const assetVersion = '20260410g';
77
const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
88
const SETTLE_PASS_DELAYS = [0, 140, 320, 560];
99
const simpleIcon = (name) => `https://cdn.jsdelivr.net/npm/simple-icons@v11/icons/${name}.svg`;
@@ -51,10 +51,10 @@
5151
"Diving into the core of operating systems and device environments. My work involves Custom ROM development and low-level system exploration, studying how device architectures function from the inside out to build highly optimized environments.",
5252
arsenalKind: "engineering",
5353
arsenal: [
54-
{ iconSvg: iconSvg('<rect x="4.1" y="4.5" width="11.8" height="8.2" rx="1.8"/><path d="M6.5 15.5h7"/><path d="M8 12.7v2.8M12 12.7v2.8"/>'), label: "Custom ROM Building" },
54+
{ iconSvg: iconSvg('<path d="M6.1 7.2h7.8"/><path d="M7.3 5.1v2.1M12.7 5.1v2.1"/><path d="M6.8 7.2 5.7 12h8.6l-1.1-4.8"/><path d="M7.6 12v2.2M12.4 12v2.2"/><path d="M6.2 14.2h1.7M12.1 14.2h1.7"/>'), label: "Custom ROM Building" },
5555
{ iconSvg: iconSvg('<path d="M10 4.2 14 5.7v3.8c0 2.6-1.6 4.8-4 5.9-2.4-1.1-4-3.3-4-5.9V5.7L10 4.2Z"/><path d="m12.7 12.7 2.6 2.6"/><circle cx="12.1" cy="12.1" r="2.3"/>'), label: "iOS Security Analysis" },
5656
{ iconSvg: iconSvg('<path d="m6.4 6.2-3.1 3.8 3.1 3.8"/><path d="m13.6 6.2 3.1 3.8-3.1 3.8"/><path d="m11 4.8-2 10.4"/>'), label: "Reverse Engineering" },
57-
{ iconSvg: iconSvg('<rect x="4.2" y="4.2" width="6.2" height="6.2" rx="1.3"/><rect x="9.6" y="9.6" width="6.2" height="6.2" rx="1.3"/><path d="M9.6 7.4h2.1M10.7 6.3v2.2"/>'), label: "System Virtualization" }
57+
{ iconSvg: iconSvg('<rect x="4.1" y="4.5" width="11.8" height="8.2" rx="1.8"/><path d="M6.5 15.5h7"/><path d="M8 12.7v2.8M12 12.7v2.8"/>'), label: "System Virtualization" }
5858
]
5959
},
6060
{
@@ -190,6 +190,9 @@
190190
discipline.arsenal.forEach((item) => {
191191
const pill = document.createElement("span");
192192
pill.className = "discipline-pill";
193+
if (item.label) {
194+
pill.classList.add(`discipline-pill--${item.label.toLowerCase().replace(/[^a-z0-9]+/g, "-")}`);
195+
}
193196

194197
const icon = document.createElement("span");
195198
icon.className = "discipline-pill__icon";
@@ -202,6 +205,7 @@
202205
image.loading = "lazy";
203206
image.decoding = "async";
204207
image.referrerPolicy = "no-referrer";
208+
image.draggable = false;
205209
icon.appendChild(image);
206210
} else if (item.iconSvg) {
207211
icon.innerHTML = item.iconSvg;
@@ -1582,22 +1586,38 @@
15821586
const clamp = (value, min, max) => Math.min(max, Math.max(min, value));
15831587
const createLayout = (x, y, scale, rotate) => ({ x, y, scale, rotate });
15841588
const getSide = (offset) => (offset === 0 ? "front" : offset < 0 ? "left" : "right");
1589+
const getBaseCardHeight = () => {
1590+
const rem = parseFloat(getComputedStyle(document.documentElement).fontSize) || 16;
1591+
if (portraitQuery.matches) {
1592+
return clamp(window.innerWidth * 0.84, 25.8 * rem, 30.4 * rem);
1593+
}
1594+
1595+
if (window.matchMedia("(max-width: 980px) and (orientation: landscape)").matches) {
1596+
return clamp(window.innerWidth * 0.33, 18.8 * rem, 22.8 * rem);
1597+
}
1598+
1599+
if (window.innerWidth <= 980) {
1600+
return clamp(window.innerWidth * 0.4, 20 * rem, 24 * rem);
1601+
}
1602+
1603+
return clamp(window.innerWidth * 0.39, 22 * rem, 28 * rem);
1604+
};
15851605

15861606
const buildLayouts = (cardWidth) => {
15871607
const steps = portraitQuery.matches
15881608
? [
15891609
{ x: 0, scale: 1, rotate: 0 },
1590-
{ x: cardWidth * 0.19, scale: 0.912, rotate: 4.2 },
1591-
{ x: cardWidth * 0.302, scale: 0.828, rotate: 6.2 },
1592-
{ x: cardWidth * 0.378, scale: 0.752, rotate: 7.5 },
1593-
{ x: cardWidth * 0.428, scale: 0.688, rotate: 8.4 }
1610+
{ x: cardWidth * 0.21, scale: 0.892, rotate: 4.9 },
1611+
{ x: cardWidth * 0.334, scale: 0.786, rotate: 7.8 },
1612+
{ x: cardWidth * 0.418, scale: 0.692, rotate: 10.2 },
1613+
{ x: cardWidth * 0.474, scale: 0.614, rotate: 12.2 }
15941614
]
15951615
: [
15961616
{ x: 0, scale: 1, rotate: 0 },
1597-
{ x: cardWidth * 0.214, scale: 0.924, rotate: 3.7 },
1598-
{ x: cardWidth * 0.338, scale: 0.846, rotate: 5.1 },
1599-
{ x: cardWidth * 0.424, scale: 0.772, rotate: 6.2 },
1600-
{ x: cardWidth * 0.482, scale: 0.71, rotate: 7.0 }
1617+
{ x: cardWidth * 0.224, scale: 0.904, rotate: 4.4 },
1618+
{ x: cardWidth * 0.356, scale: 0.8, rotate: 6.8 },
1619+
{ x: cardWidth * 0.446, scale: 0.706, rotate: 8.9 },
1620+
{ x: cardWidth * 0.506, scale: 0.626, rotate: 10.5 }
16011621
];
16021622

16031623
return steps.reduce((layouts, step, depth) => {
@@ -1616,13 +1636,6 @@
16161636
const formatTransform = (layout) =>
16171637
`translate(calc(-50% + ${layout.x.toFixed(2)}px), ${layout.y.toFixed(2)}px) scale(${layout.scale.toFixed(4)}) rotate(${layout.rotate.toFixed(2)}deg)`;
16181638

1619-
const interpolateLayout = (from, to, t) => ({
1620-
x: from.x + (to.x - from.x) * t,
1621-
y: from.y + (to.y - from.y) * t,
1622-
scale: from.scale + (to.scale - from.scale) * t,
1623-
rotate: from.rotate + (to.rotate - from.rotate) * t
1624-
});
1625-
16261639
const getDepthAppearance = (offset) => {
16271640
const depth = Math.min(Math.abs(offset), total - 1);
16281641
const dim = [0.028, 0.11, 0.18, 0.24, 0.29][depth] || 0.29;
@@ -1644,14 +1657,27 @@
16441657

16451658
cards.forEach((card) => {
16461659
const surface = card.querySelector(".discipline-stack-card__surface");
1647-
const contentHeight = surface?.scrollHeight || card.scrollHeight || 0;
1660+
const header = surface?.querySelector(".discipline-stack-card__header");
1661+
const body = surface?.querySelector(".discipline-stack-card__body");
1662+
const arsenal = surface?.querySelector(".discipline-stack-card__arsenal:not([hidden])");
1663+
const styles = surface ? getComputedStyle(surface) : null;
1664+
const gap = styles ? parseFloat(styles.rowGap || styles.gap) || 0 : 0;
1665+
const paddingTop = styles ? parseFloat(styles.paddingTop) || 0 : 0;
1666+
const paddingBottom = styles ? parseFloat(styles.paddingBottom) || 0 : 0;
1667+
const parts = [header, body, arsenal].filter(Boolean);
1668+
const contentHeight = Math.ceil(
1669+
paddingTop +
1670+
paddingBottom +
1671+
parts.reduce((sum, part) => sum + (part.scrollHeight || part.getBoundingClientRect().height || 0), 0) +
1672+
gap * Math.max(0, parts.length - 1)
1673+
);
16481674
maxContentHeight = Math.max(maxContentHeight, contentHeight);
16491675
});
16501676

16511677
const cardWidth = firstCard?.offsetWidth || stack.clientWidth || window.innerWidth;
16521678
const breathingRoom = Math.ceil(clamp(window.innerHeight * 0.04, 32, 56));
1653-
const currentHeight = firstCard?.offsetHeight || stack.clientHeight || 0;
1654-
const cardHeight = Math.ceil(Math.max(currentHeight, maxContentHeight + breathingRoom));
1679+
const baseHeight = Math.ceil(getBaseCardHeight());
1680+
const cardHeight = Math.ceil(Math.max(baseHeight, maxContentHeight + breathingRoom));
16551681
const pad = Math.ceil(Math.max(28, cardHeight * 0.08));
16561682

16571683
shell?.style.setProperty("--discipline-card-width-resolved", `${cardWidth}px`);
@@ -1702,17 +1728,23 @@
17021728

17031729
const applyState = ({ dragProgress = 0 } = {}) => {
17041730
const isDragging = portraitQuery.matches && Math.abs(dragProgress) > 0.001;
1705-
const travel = dragProgress === 0 ? 0 : dragProgress < 0 ? 1 : -1;
1731+
const dragSign = dragProgress === 0 ? 0 : Math.sign(dragProgress);
1732+
const currentMetrics = getMetrics();
1733+
const dragMagnitude = Math.abs(dragProgress);
17061734

17071735
stack.classList.toggle("is-dragging", isDragging);
17081736

17091737
cards.forEach((card, index) => {
17101738
const offset = index - activeIndex;
17111739
let visual = getLayoutForOffset(offset);
17121740

1713-
if (isDragging && travel !== 0) {
1714-
const target = getLayoutForOffset(offset + travel);
1715-
visual = interpolateLayout(visual, target, Math.abs(dragProgress));
1741+
if (isDragging && offset === 0 && dragSign !== 0) {
1742+
visual = createLayout(
1743+
currentMetrics.cardWidth * 0.66 * dragMagnitude * dragSign,
1744+
0,
1745+
1 - dragMagnitude * 0.028,
1746+
dragSign * 10.5 * dragMagnitude
1747+
);
17161748
}
17171749

17181750
const appearance = getDepthAppearance(offset);
@@ -1743,16 +1775,16 @@
17431775
const throwSign = direction > 0 ? -1 : 1;
17441776
const finalLayout = getLayoutForOffset(direction > 0 ? -1 : 1);
17451777
const midLayout = createLayout(
1746-
throwSign * currentMetrics.cardWidth * (portraitQuery.matches ? 0.34 : 0.3),
1778+
throwSign * currentMetrics.cardWidth * (portraitQuery.matches ? 0.56 : 0.52),
17471779
0,
1748-
0.972,
1749-
throwSign * (portraitQuery.matches ? 9.8 : 8.2)
1780+
0.968,
1781+
throwSign * (portraitQuery.matches ? 12.8 : 10.4)
17501782
);
17511783
const tuckLayout = createLayout(
1752-
finalLayout.x * 1.12,
1784+
finalLayout.x * 1.18,
17531785
0,
1754-
Math.min(0.985, finalLayout.scale * 1.01),
1755-
finalLayout.rotate + throwSign * 1.1
1786+
Math.min(0.982, finalLayout.scale * 1.012),
1787+
finalLayout.rotate + throwSign * 1.35
17561788
);
17571789

17581790
card.style.transition = "none";
@@ -1764,8 +1796,8 @@
17641796
{ transform: formatTransform(finalLayout) }
17651797
],
17661798
{
1767-
duration: portraitQuery.matches ? 860 : 740,
1768-
easing: "cubic-bezier(0.2, 0.82, 0.22, 1)",
1799+
duration: portraitQuery.matches ? 920 : 820,
1800+
easing: "cubic-bezier(0.18, 0.86, 0.22, 1)",
17691801
fill: "both"
17701802
}
17711803
);
@@ -1863,11 +1895,11 @@
18631895

18641896
event.preventDefault();
18651897
const width = Math.max(stack.clientWidth, 1);
1866-
const raw = deltaX / (width * 0.28);
1898+
const raw = deltaX / (width * 0.2);
18671899
const direction = raw === 0 ? 0 : raw > 0 ? -1 : 1;
18681900
const outOfBounds = (direction < 0 && activeIndex === 0) || (direction > 0 && activeIndex === total - 1);
1869-
const limit = outOfBounds ? 0.18 : 0.74;
1870-
const resistance = outOfBounds ? 2.2 : 1.08;
1901+
const limit = outOfBounds ? 0.2 : 0.92;
1902+
const resistance = outOfBounds ? 2.05 : 0.88;
18711903
const progress = clamp(Math.sign(raw || 0) * limit * (1 - Math.exp(-Math.abs(raw) * resistance)), -limit, limit);
18721904
pointerState.progress = progress;
18731905
applyState({ dragProgress: progress });

docs/index.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
<link rel="preconnect" href="https://fonts.googleapis.com">
99
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
1010
<link href="https://fonts.googleapis.com/css2?family=Rock+Salt&family=Space+Grotesk:wght@400;500;600;700&family=Unbounded:wght@500;700;800&display=swap" rel="stylesheet">
11-
<link rel="stylesheet" href="assets/css/style.css?v=20260410f">
11+
<link rel="stylesheet" href="assets/css/style.css?v=20260410g">
1212

1313
<link rel="icon" type="image/svg+xml" href="favicon.svg">
1414
<link rel="icon" sizes="192x192" href="android-chrome-192x192.png">
@@ -168,6 +168,6 @@ <h2>A <span class="tagline-script">Closer Look</span> At The Path</h2>
168168

169169
<div id="footer-slot"></div>
170170

171-
<script src="assets/js/shell.js?v=20260410f" defer></script>
171+
<script src="assets/js/shell.js?v=20260410g" defer></script>
172172
</body>
173173
</html>

0 commit comments

Comments
 (0)