Skip to content
Draft
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
3 changes: 2 additions & 1 deletion .claude/settings.local.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
"Bash(npm run:*)",
"Read(//Users/johnlarkin/Desktop/Screenshots/**)",
"Bash(npx sass:*)",
"Bash(npx postcss:*)"
"Bash(npx postcss:*)",
"Skill(document-skills:frontend-design)"
],
"deny": []
}
Expand Down
4 changes: 4 additions & 0 deletions _includes/head.html
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,10 @@
/>
<meta name="theme-color" content="#ffffff" />

<!-- Inter font for headings -->
<link rel="preconnect" href="https://rsms.me/" crossorigin />
<link rel="stylesheet" href="https://rsms.me/inter/inter.css" />

<script>
window.dataLayer = window.dataLayer || [];
function gtag() {
Expand Down
8 changes: 4 additions & 4 deletions _includes/header.html
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,13 @@
{% endif %}
{% if forloop.first %}
<div class="header__dropdown">
<span class="header__link header__dropdown-trigger">
<button class="header__link header__dropdown-trigger" type="button" aria-expanded="false" aria-controls="projects-menu">
Projects
<svg class="header__dropdown-chevron" width="10" height="6" viewBox="0 0 10 6" fill="none" xmlns="http://www.w3.org/2000/svg">
<svg class="header__dropdown-chevron" width="10" height="6" viewBox="0 0 10 6" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
<path d="M1 1L5 5L9 1" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</span>
<div class="header__dropdown-menu">
</button>
<div class="header__dropdown-menu" id="projects-menu">
{% for project in site.projects %}
<a class="header__dropdown-item" href="{{ project.link }}" target="_blank" rel="noopener noreferrer">
{{ project.name }}
Expand Down
50 changes: 49 additions & 1 deletion _js/scripts.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ $(window).resize(function () {
$(".header__links").removeClass("js--open");
$(".header__links").removeAttr("style"); // If mobile nav was collapsed, make sure it's show on DESK
$(".header__overlay").remove(); // Remove mobile navigation overlay in case it was opened
// Reset accordion state on resize
if (typeof resetMobileAccordion === "function") {
resetMobileAccordion();
}
});

/*-------------------------------------------------------------------------*/
Expand All @@ -69,6 +73,41 @@ function toggleMobileNav() {
hideMobileNav();
}
});

// Initialize mobile accordion for Projects dropdown
initMobileAccordion();
}

/*-------------------------------------------------------------------------*/
/* MOBILE ACCORDION (Projects Dropdown) */
/* -----------------------------------------------------------------------*/

function initMobileAccordion() {
var $trigger = $(".header__dropdown-trigger");
var lgBreakpoint = 992; // Matches $lg SCSS variable

$trigger.on("click", function (e) {
// Only handle accordion on mobile (below $lg breakpoint)
if ($(window).width() < lgBreakpoint) {
e.preventDefault();
e.stopPropagation();

var $dropdown = $(this).closest(".header__dropdown");
var isOpen = $dropdown.hasClass("is-open");

// Toggle accordion state
$dropdown.toggleClass("is-open", !isOpen);

// Update aria-expanded for accessibility
$(this).attr("aria-expanded", !isOpen);
}
});
}

function resetMobileAccordion() {
// Reset accordion state when closing menu or resizing
$(".header__dropdown").removeClass("is-open");
$(".header__dropdown-trigger").attr("aria-expanded", "false");
}

function openMobileNav() {
Expand All @@ -80,12 +119,19 @@ function openMobileNav() {
begin: function () {
$(".header__toggle").addClass("--open");
$("body").append("<div class='header__overlay'></div>");
// Add animating class for staggered reveal
$(this).addClass("js--animating");
},
progress: function () {
$(".header__overlay").addClass("--open");
},
complete: function () {
$(this).addClass("js--open");
// Remove animating class after animations complete (500ms buffer)
var $links = $(this);
setTimeout(function() {
$links.removeClass("js--animating");
}, 500);
},
});
}
Expand All @@ -99,12 +145,14 @@ function hideMobileNav() {
visibility: "hidden",
begin: function () {
$(".header__toggle").removeClass("--open");
// Reset accordion when menu closes
resetMobileAccordion();
},
progress: function () {
$(".header__overlay").removeClass("--open");
},
complete: function () {
$(this).removeClass("js--open");
$(this).removeClass("js--open js--animating");
$(".header__toggle, .header__overlay").removeClass("--open");
},
});
Expand Down
9 changes: 8 additions & 1 deletion _sass/abstracts/_variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ $quiz-incorrect: $error;


$font-stack: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Hiragino Sans GB", "Microsoft YaHei", "WenQuanYi Micro Hei", sans-serif;
$font-heading: 'Inter', -apple-system, BlinkMacSystemFont, "SF Pro Display", "Segoe UI", system-ui, sans-serif;

// Unified accent system (promoted from pinned badge purple)
$accent-primary: #5837F5;
$accent-primary-light: #7C5DFA;
$accent-primary-glow: rgba(88, 55, 245, 0.15);

$spacing-unit: 30px;

Expand All @@ -64,7 +70,8 @@ $code-border-color: #e1e4e8 !default;
$dark-bg: #1a1a1a !default;
$dark-text: #e4e4e4 !default;
$dark-heading: #ffffff !default;
$dark-link: #68a4f1 !default;
$dark-link: #A78BFA !default;
$dark-link-hover: #C4B5FD !default;
$dark-border: #333333 !default;
$dark-code-bg: #0d1117 !default;
$dark-code-text: #e6e6e6 !default;
Expand Down
73 changes: 65 additions & 8 deletions _sass/base/_typography.scss
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
// General
body {
background-color: $dark-bg;
// Subtle radial gradient for depth
background-image: radial-gradient(
ellipse at 50% 0%,
rgba($accent-primary, 0.03) 0%,
transparent 50%
);
background-attachment: fixed;
font-family: $font-stack;
font-size: 1.1rem;
line-height: 1.5;
font-size: 1.125rem;
line-height: 1.65;
letter-spacing: -0.01em;
color: $dark-text;
-webkit-font-smoothing: antialiased;
-webkit-text-size-adjust: 100%;
font-feature-settings: "kern" 1, "liga" 1;
}

::selection {
Expand All @@ -27,17 +36,51 @@ h3,
h4,
h5,
h6 {
font-family: $font-heading;
color: $dark-heading;
margin-top: 0;
margin-bottom: .5rem;
margin-bottom: 0.5rem;
letter-spacing: -0.02em;
font-weight: 600;
}

//reset link
h1 {
font-size: 2.5rem;
letter-spacing: -0.03em;
line-height: 1.2;
}

h2 {
font-size: 1.875rem;
letter-spacing: -0.025em;
line-height: 1.25;
}

h3 {
font-size: 1.5rem;
line-height: 1.3;
}

// Modern link styling with animated underline
a {
color: $dark-link;
text-decoration: none;
transition: all .2s linear;
border-bottom: 1px dashed $dark-link;
position: relative;
transition: color 0.2s ease;

// Animated gradient underline
&::after {
content: "";
position: absolute;
left: 0;
bottom: -2px;
width: 100%;
height: 2px;
background: linear-gradient(90deg, $accent-primary, $accent-primary-light);
transform: scaleX(0);
transform-origin: right;
transition: transform 0.3s cubic-bezier(0.25, 1, 0.5, 1);
}

&:active,
&:focus {
Expand All @@ -46,8 +89,22 @@ a {

&:hover,
&:focus {
color: lighten($dark-link, 10%);
border-bottom: 1px solid lighten($dark-link, 10%);
color: $dark-link-hover;

&::after {
transform: scaleX(1);
transform-origin: left;
}
}
}

// Clean link variant (no underline animation) for nav, cards, buttons
a.link--clean,
.nav a,
.card a,
.btn {
&::after {
display: none;
}
}

Expand Down
101 changes: 69 additions & 32 deletions _sass/components/_search.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ $search-bg: #0d0d0d;
$search-surface: #161616;
$search-surface-hover: #1a1a1a;
$search-border: rgba(255, 255, 255, 0.08);
$search-border-focus: rgba(39, 124, 234, 0.5);
$search-border-focus: rgba($accent-primary, 0.5);
$search-text: #e8e8e8;
$search-text-muted: rgba(255, 255, 255, 0.45);
$search-accent: #3b9eff;
$search-accent-glow: rgba(59, 158, 255, 0.15);
$search-highlight: rgba(59, 158, 255, 0.25);
$search-accent: $accent-primary;
$search-accent-glow: $accent-primary-glow;
$search-highlight: rgba($accent-primary, 0.25);

// Animation timing
$search-ease: cubic-bezier(0.16, 1, 0.3, 1);
Expand Down Expand Up @@ -41,56 +41,93 @@ $search-ease-out: cubic-bezier(0, 0, 0.2, 1);

// Search trigger button in header
.search-trigger {
// Mobile: full-width menu item style
display: flex;
align-items: center;
gap: 0.625rem;
padding: 0.5rem 0.875rem !important;
background: rgba(255, 255, 255, 0.04);
border: 1px solid rgba(255, 255, 255, 0.08);
border-radius: 10px;
gap: 0.75rem;
width: 100%;
padding: 0.875rem 0 !important;
background: transparent;
border: none;
border-radius: 0;
cursor: pointer;
transition: all 0.2s $search-ease;
transition: background-color 0.15s ease;
color: $dark-text;
font-size: 1.05rem;

&:hover {
background: rgba(255, 255, 255, 0.08);
border-color: rgba(255, 255, 255, 0.12);
transform: translateY(-1px);
&:active {
background-color: rgba(255, 255, 255, 0.04);
}

&:active {
transform: translateY(0);
// Add "Search" text on mobile via pseudo-element
&::before {
content: "Search";
font-family: inherit;
font-size: 1.05rem;
letter-spacing: 0.01em;
}

&__icon {
display: flex;
align-items: center;
color: rgba(255, 255, 255, 0.6);
transition: color 0.2s;

.search-trigger:hover & {
color: rgba(255, 255, 255, 0.9);
}
order: -1; // Icon before text
}

&__shortcut {
display: none;
}

// Desktop: compact pill button style
@media (min-width: $lg) {
width: auto;
gap: 0.625rem;
padding: 0.5rem 0.875rem !important;
background: rgba(255, 255, 255, 0.04);
border: 1px solid rgba(255, 255, 255, 0.08);
border-radius: 10px;
font-size: inherit;

&::before {
display: none; // Hide "Search" text on desktop
}

&:hover {
background: rgba(255, 255, 255, 0.08);
border-color: rgba(255, 255, 255, 0.12);
transform: translateY(-1px);
}

&:active {
transform: translateY(0);
background: rgba(255, 255, 255, 0.08);
}

&__icon {
order: 0;

@media (min-width: $md) {
.search-trigger:hover & {
color: rgba(255, 255, 255, 0.9);
}
}

&__shortcut {
display: flex;
align-items: center;
gap: 0.25rem;
}

kbd {
font-family: "SF Mono", "JetBrains Mono", monospace;
font-size: 0.6875rem;
font-weight: 500;
letter-spacing: 0.02em;
color: rgba(255, 255, 255, 0.4);
background: rgba(255, 255, 255, 0.06);
padding: 0.2rem 0.45rem;
border-radius: 5px;
border: 1px solid rgba(255, 255, 255, 0.08);
kbd {
font-family: "SF Mono", "JetBrains Mono", monospace;
font-size: 0.6875rem;
font-weight: 500;
letter-spacing: 0.02em;
color: rgba(255, 255, 255, 0.4);
background: rgba(255, 255, 255, 0.06);
padding: 0.2rem 0.45rem;
border-radius: 5px;
border: 1px solid rgba(255, 255, 255, 0.08);
}
}
}
}
Expand Down
Loading