Hero: on the FC album visit (?pae2) a 'The FC album · 9 songs' button after Get in touch jumps to the music; spinning accent ring, breathing glow, live equalizer and a nudging arrow (still under reduced motion); hidden on every other visit
Changes
@@@ -41,6 +41,13 @@ const offsets = words.map((_, i) => words.slice(0, i).join(" ").length + (i ? 1<a href="#work" class="btn btn--primary" data-magnetic><i class="fa-solid fa-layer-group"></i> See what I've built <span class="btn__arrow">→</span></a><a href={profile.resumePdf} class="btn" data-magnetic data-resume-link><i class="fa-solid fa-file-pdf"></i> Resume PDF</a><a href="#contact" class="btn btn--ghost" data-magnetic><i class="fa-solid fa-paper-plane"></i> Get in touch</a>++ <!-- Only on the FC album visit (?pae2, from the hat): jump straight to the music. -->++ <a href="#album" class="btn hero__album" data-magnetic aria-label="Jump to the FC album, 9 songs">++ <span class="hero__eq" aria-hidden="true"><i></i><i></i><i></i><i></i></span>++ <span>The FC album</span>++ <span class="hero__album-badge" aria-hidden="true">9 songs</span>++ <span class="btn__arrow hero__album-arrow" aria-hidden="true">↓</span>++ </a></div><div class="hero__tags hero__in" style="--d:950ms">@@@ -162,6 +169,47 @@ const offsets = words.map((_, i) => words.slice(0, i).join(" ").length + (i ? 1.hero__lead { max-width: 58ch; font-size: clamp(1rem, 1.3vw, 1.12rem); color: var(--muted); }.hero__cta { display: flex; gap: 12px; flex-wrap: wrap; margin: 1.6rem 0 1.4rem; }++++ /* The FC album jump (html.pae2 only): a spinning accent ring, a breathing glow, a live equalizer++ and a nudging arrow, so nobody misses it. Still under prefers-reduced-motion. */++ @property --album-ang { syntax: "<angle>"; inherits: false; initial-value: 0deg; }++ .hero__album { display: none; }++ :global(html.pae2) .hero__album {++ display: inline-flex; border: 2px solid transparent; color: var(--fg);++ background:++ linear-gradient(var(--bg-2), var(--bg-2)) padding-box,++ conic-gradient(from var(--album-ang), var(--accent), var(--accent-2), var(--accent-3), var(--accent)) border-box;++ animation: albumSpin 3.2s linear infinite, albumGlow 2.4s ease-in-out infinite, albumIn .7s var(--ease) 1.1s both;++ }++ :global(html.pae2) .hero__album:hover {++ background:++ linear-gradient(var(--surface-2), var(--surface-2)) padding-box,++ conic-gradient(from var(--album-ang), var(--accent), var(--accent-2), var(--accent-3), var(--accent)) border-box;++ border-color: transparent;++ }++ @keyframes albumSpin { to { --album-ang: 360deg; } }++ @keyframes albumGlow {++ 0%, 100% { box-shadow: 0 0 0 0 rgba(var(--accent-rgb), 0), 0 8px 24px -10px rgba(var(--accent-2-rgb), .6); }++ 50% { box-shadow: 0 0 0 7px rgba(var(--accent-rgb), .12), 0 10px 34px -8px rgba(var(--accent-2-rgb), .85); }++ }++ @keyframes albumIn { from { opacity: 0; transform: translateY(8px) scale(.96); } to { opacity: 1; transform: none; } }++ .hero__eq { display: inline-flex; align-items: flex-end; gap: 2px; width: 16px; height: 15px; }++ .hero__eq i { flex: 1; height: 40%; border-radius: 2px; background: linear-gradient(180deg, var(--accent-2), var(--accent)); animation: eqBar .9s ease-in-out infinite; }++ .hero__eq i:nth-child(2) { animation-duration: 1.1s; animation-delay: -.35s; }++ .hero__eq i:nth-child(3) { animation-duration: .8s; animation-delay: -.6s; }++ .hero__eq i:nth-child(4) { animation-duration: 1.2s; animation-delay: -.15s; }++ @keyframes eqBar { 0%, 100% { height: 25%; } 50% { height: 100%; } }++ .hero__album-badge {++ padding: 3px 8px; border-radius: 999px; font: 600 .66rem/1 var(--font-mono); letter-spacing: .08em; text-transform: uppercase;++ background: rgba(var(--accent-rgb), .16); color: var(--accent); border: 1px solid rgba(var(--accent-rgb), .3);++ }++ .hero__album .hero__album-arrow { animation: albumNudge 1.5s ease-in-out infinite; }++ .hero__album:hover .hero__album-arrow { transform: none; }++ @keyframes albumNudge { 0%, 100% { transform: translateY(-1px); } 50% { transform: translateY(3px); } }++ @media (prefers-reduced-motion: reduce) {++ :global(html.pae2) .hero__album, .hero__eq i, .hero__album .hero__album-arrow { animation: none; }++ .hero__eq i { height: 70%; }++ }.hero__tags { max-width: 620px; }.hero__tags-label { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; font: 500 .72rem var(--font-mono); letter-spacing: .16em; text-transform: uppercase; color: var(--dim); }.hero__tags-label i { color: var(--accent); }
@@ -41,6 +41,13 @@ const offsets = words.map((_, i) => words.slice(0, i).join(" ").length + (i ? 1
@@ -41,6 +41,13 @@ const offsets = words.map((_, i) => words.slice(0, i).join(" ").length + (i ? 1
<a href="#work" class="btn btn--primary" data-magnetic><i class="fa-solid fa-layer-group"></i> See what I've built <span class="btn__arrow">→</span></a>
<a href="#work" class="btn btn--primary" data-magnetic><i class="fa-solid fa-layer-group"></i> See what I've built <span class="btn__arrow">→</span></a>
<a href={profile.resumePdf} class="btn" data-magnetic data-resume-link><i class="fa-solid fa-file-pdf"></i> Resume PDF</a>
<a href={profile.resumePdf} class="btn" data-magnetic data-resume-link><i class="fa-solid fa-file-pdf"></i> Resume PDF</a>
<a href="#contact" class="btn btn--ghost" data-magnetic><i class="fa-solid fa-paper-plane"></i> Get in touch</a>
<a href="#contact" class="btn btn--ghost" data-magnetic><i class="fa-solid fa-paper-plane"></i> Get in touch</a>
+ <!-- Only on the FC album visit (?pae2, from the hat): jump straight to the music. -->
+ <a href="#album" class="btn hero__album" data-magnetic aria-label="Jump to the FC album, 9 songs">
+ <span class="hero__eq" aria-hidden="true"><i></i><i></i><i></i><i></i></span>
+ <span>The FC album</span>
+ <span class="hero__album-badge" aria-hidden="true">9 songs</span>
+ <span class="btn__arrow hero__album-arrow" aria-hidden="true">↓</span>
+ </a>
</div>
</div>
<div class="hero__tags hero__in" style="--d:950ms">
<div class="hero__tags hero__in" style="--d:950ms">
@@ -162,6 +169,47 @@ const offsets = words.map((_, i) => words.slice(0, i).join(" ").length + (i ? 1
@@ -162,6 +169,47 @@ const offsets = words.map((_, i) => words.slice(0, i).join(" ").length + (i ? 1
.hero__lead { max-width: 58ch; font-size: clamp(1rem, 1.3vw, 1.12rem); color: var(--muted); }
.hero__lead { max-width: 58ch; font-size: clamp(1rem, 1.3vw, 1.12rem); color: var(--muted); }
.hero__cta { display: flex; gap: 12px; flex-wrap: wrap; margin: 1.6rem 0 1.4rem; }
.hero__cta { display: flex; gap: 12px; flex-wrap: wrap; margin: 1.6rem 0 1.4rem; }
+
+ /* The FC album jump (html.pae2 only): a spinning accent ring, a breathing glow, a live equalizer
+ and a nudging arrow, so nobody misses it. Still under prefers-reduced-motion. */
+ @property --album-ang { syntax: "<angle>"; inherits: false; initial-value: 0deg; }
+ .hero__album { display: none; }
+ :global(html.pae2) .hero__album {
+ display: inline-flex; border: 2px solid transparent; color: var(--fg);
+ background:
+ linear-gradient(var(--bg-2), var(--bg-2)) padding-box,
+ conic-gradient(from var(--album-ang), var(--accent), var(--accent-2), var(--accent-3), var(--accent)) border-box;
+ animation: albumSpin 3.2s linear infinite, albumGlow 2.4s ease-in-out infinite, albumIn .7s var(--ease) 1.1s both;
+ }
+ :global(html.pae2) .hero__album:hover {
+ background:
+ linear-gradient(var(--surface-2), var(--surface-2)) padding-box,
+ conic-gradient(from var(--album-ang), var(--accent), var(--accent-2), var(--accent-3), var(--accent)) border-box;
+ border-color: transparent;
+ }
+ @keyframes albumSpin { to { --album-ang: 360deg; } }
+ @keyframes albumGlow {
+ 0%, 100% { box-shadow: 0 0 0 0 rgba(var(--accent-rgb), 0), 0 8px 24px -10px rgba(var(--accent-2-rgb), .6); }
+ 50% { box-shadow: 0 0 0 7px rgba(var(--accent-rgb), .12), 0 10px 34px -8px rgba(var(--accent-2-rgb), .85); }
+ }
+ @keyframes albumIn { from { opacity: 0; transform: translateY(8px) scale(.96); } to { opacity: 1; transform: none; } }
+ .hero__eq { display: inline-flex; align-items: flex-end; gap: 2px; width: 16px; height: 15px; }
+ .hero__eq i { flex: 1; height: 40%; border-radius: 2px; background: linear-gradient(180deg, var(--accent-2), var(--accent)); animation: eqBar .9s ease-in-out infinite; }
+ .hero__eq i:nth-child(2) { animation-duration: 1.1s; animation-delay: -.35s; }
+ .hero__eq i:nth-child(3) { animation-duration: .8s; animation-delay: -.6s; }
+ .hero__eq i:nth-child(4) { animation-duration: 1.2s; animation-delay: -.15s; }
+ @keyframes eqBar { 0%, 100% { height: 25%; } 50% { height: 100%; } }
+ .hero__album-badge {
+ padding: 3px 8px; border-radius: 999px; font: 600 .66rem/1 var(--font-mono); letter-spacing: .08em; text-transform: uppercase;
+ background: rgba(var(--accent-rgb), .16); color: var(--accent); border: 1px solid rgba(var(--accent-rgb), .3);
+ }
+ .hero__album .hero__album-arrow { animation: albumNudge 1.5s ease-in-out infinite; }
+ .hero__album:hover .hero__album-arrow { transform: none; }
+ @keyframes albumNudge { 0%, 100% { transform: translateY(-1px); } 50% { transform: translateY(3px); } }
+ @media (prefers-reduced-motion: reduce) {
+ :global(html.pae2) .hero__album, .hero__eq i, .hero__album .hero__album-arrow { animation: none; }
+ .hero__eq i { height: 70%; }
+ }
.hero__tags { max-width: 620px; }
.hero__tags { max-width: 620px; }
.hero__tags-label { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; font: 500 .72rem var(--font-mono); letter-spacing: .16em; text-transform: uppercase; color: var(--dim); }
.hero__tags-label { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; font: 500 .72rem var(--font-mono); letter-spacing: .16em; text-transform: uppercase; color: var(--dim); }
.hero__tags-label i { color: var(--accent); }
.hero__tags-label i { color: var(--accent); }