<!DOCTYPE html>
<html lang="en">
<!-- ── Head ─────────────────────────────────────────────────────── -->
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>About | Kevin Fowler</title>
<link rel="preconnect" href="https://fonts.googleapis.com"/>
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin/>
<link href="https://fonts.googleapis.com/css2?family=Audiowide&family=Orbitron:wght@400;500;600;700;900&family=Oxanium:wght@200..800&display=swap" rel="stylesheet"/>
<link rel="stylesheet" href="about.css"/>
<script defer src="/_vercel/insights/script.js"></script>
<script defer src="/_vercel/speed-insights/script.js"></script>
</head>
<!-- ── Body ─────────────────────────────────────────────────────── -->
<body>
<!-- ── Cursor ─────────────────────────────────────────────────────── -->
<div id="cur"><div class="cur-dot"></div></div>
<a href="#main" class="skip-nav">Skip to main content</a>
<!-- ── Nav ─────────────────────────────────────────────────────── -->
<nav aria-label="Main navigation">
<a href="https://portfolio-kevin-fowler.vercel.app/index.html" class="nav-logo">Kevin Fowler</a>
<a href="resume.pdf" class="nav-resume" target="_blank" aria-label="Open resume PDF">
<span>Resume (PDF)</span>
</a>
</nav>
<main id="main">
<!-- ── Header ─────────────────────────────────────────────────────── -->
<section class="about-header" aria-label="About">
<div class="about-header-inner">
<div class="about-header-copy">
<h1 class="about-title" id="about-title">Designer</h1>
<p class="about-intro">I spent the first phase of my career solving operational chaos for millions of people in the real world. Now, I’m combining that front-line instinct with formal training in Human Systems Engineering to build digital experiences that actually make sense.</p>
<p class="about-cta-down">
<span>Here is how I got here</span>
<svg width="20" height="20" viewBox="0 0 15 15" fill="none" aria-hidden="true" class="cta-arrow">
<path d="M7 2V12M7 12L3 8M7 12L11 8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</p>
</div>
<div class="subject-card" aria-label="Subject file">
<div class="sc-corners" aria-hidden="true"></div>
<div class="subject-card-header">
<span class="subject-card-eyebrow">◈ Subject File</span>
<span class="subject-file-no">KF–415</span>
</div>
<div class="subject-card-body">
<div class="subject-mugshot">
<img src="images/Kevin-Headshot.png" alt="Kevin Fowler"/>
</div>
<div class="subject-right">
<p class="subject-name">Kevin Fowler</p>
<dl class="subject-fields">
<div class="subject-row">
<dt>Designation</dt>
<dd>Human</dd>
</div>
<div class="subject-row">
<dt>Origin</dt>
<dd>San Francisco, CA</dd>
</div>
<div class="subject-row">
<dt>Last Seen</dt>
<dd>Phoenix, AZ</dd>
</div>
<div class="subject-row">
<dt>Clearance</dt>
<dd>Research · Design</dd>
</div>
<div class="subject-row">
<dt>Operation</dt>
<dd>Human Systems Engineering · UX/UI</dd>
</div>
<div class="subject-row">
<dt>Status</dt>
<dd><span class="subject-status">Available</span></dd>
</div>
</dl>
</div>
</div>
</div>
</div>
</section>
<!-- ── The Long Version ─────────────────────────────────────────── -->
<section class="section s-border" id="the-long-version" aria-label="The long version">
<h2 class="sec-title reveal">The Long Version</h2>
<div class="story-list timeline-reveal">
<article class="story-entry reveal">
<div class="story-when">
2020 – 2024
<span>Phoenix Zoo</span>
</div>
<div class="story-body">
<h3>In the Beginning</h3>
<p>A zoo, like any sort of “themed park” is ultimately in the experience business. Yes of course people come to escape the city, make memories, and hopefully walk out actually caring about the natural world; which is the real mission. And the conservation work done at reputable organizations makes a real impact. But to keep all of that wonderful work funded, and the animals well fed and taken care of, you have to get people to keep coming and paying to get through those front gates. At a nonprofit, that care has a direct feedback loop to the overall experience that guests have. A great day becomes a return visit, which becomes gate revenue, which funds animal care and the next experience worth building, and so on from there. Every potential touchpoint in the guest experience had to be thought of, adjusted, and executed well.</p>
<p>Over four years I managed 100+ staff in our department and helped welcome roughly 1.4 million guests a year. I was writing weekly newsletters to reach part-timers spread across shifts from 8am to 11pm, redesigning training documents so new hires could learn fast and find answers faster, building guest-facing graphics on the fly, and putting together slide decks every time we wanted to change something. Nobody called it UX, but it was all UX all along.</p>
</div>
</article>
<article class="story-entry reveal">
<div class="story-when">
2024
<span>ASU · Human Systems Engineering</span>
</div>
<div class="story-body">
<h3>Connecting the Dots</h3>
<p>The turning point wasn’t a single moment… it was recognizing a pattern in work I’d already been doing for years. The weekly staff newsletters I was in charge of were communication design for a fragmented audience across vast demographics. Internal graphics for staff to use to help them interact more deeply with guests and present to them about our animals, history, and conservation work. The slide decks I created were stakeholder communication. I was designing for real users in real contexts. Overhaul of training documents for our multitude of venues to keep staff sharp and training insightful and engaging. I was thriving, but felt like there was more to all of this. Once I could finally name what I’d been doing all along, the next step was obvious.</p>
<p>Leaving the zoo was a hard call. I loved that job. Still do, if I’m being honest. I’m a nature boy at my core and know the importance that there are more and more like me with each new generation. Caretakers of our amazing, and fragile, biological home. However managing and caring for 100+ people while carrying a full school course load and raising my son made it clear something had to give. So I made the bet on myself. Trade the job I cared for, for the career I loved and future I wanted for me and my son. I switched from Conservation Biology and Ecology to Human Systems Engineering (with a focus on UX).</p>
</div>
</article>
<article class="story-entry reveal">
<div class="story-when">
2024 ‐ Present
<span>Precision Air & Plumbing</span>
</div>
<div class="story-body">
<h3>Launch Pad</h3>
<p>For the past 2+ years I’ve been an integral part of a local HVAC and plumbing company here in the Valley of the Sun. No, it’s not UX… and I won’t pretend it is, but it keeps the lights on while I finish my degree. They’ve been very flexible with my schedule; letting me handle school, coaching, and being there for my son, and know what my trajectory has been from the start. The camaraderie is great here (one of the perks working for mom and pop shops, everyone tends to feel like family), but I’m finally at the point where I feel ready to propel myself into the industry I’ve been studying for years. While I may not be gaining real-world UX/UI experience here, I have been able to keep all of my other professional skills sharp, while I work on school assignments and side projects to grow my craft. The instinct is still there. The passion and desire is still there. Like an astronaut preparing for years for their next mission, I’m ready to launch.</p>
</div>
</article>
</div>
</section>
<!-- ── Off the Clock ─────────────────────────────────────────────── -->
<section class="section s-border" aria-label="Off the clock">
<h2 class="sec-title reveal">Off the Clock</h2>
<div class="off-grid">
<div class="off-card">
<span class="off-label">Gaming</span>
<p>Most evenings end with a controller in hand. I’m drawn to massive, immersive worlds with strong character development. But my gaming taste is a bit of a chaotic mix of everything from Baldur’s Gate 3 to Crash Bandicoot to God of War to Horizon Racing.</p>
</div>
<div class="off-card">
<span class="off-label">Travel</span>
<p>Always plotting the next trip. I’ve hiked all over Arizona and road-tripped throughout multiple states, but these days my passport is getting hungry. I’ve only started to scratch the surface with places like Colombia, and my real goal is to experience as many new cultures and places as possible.</p>
</div>
<div class="off-card">
<span class="off-label">Family</span>
<p>Trying to keep up with my son as he heads into his teenage years. Whether we’re keeping up with sports schedules, exploring the outdoors, or just hanging out at home, being his dad is the best part of my day.</p>
</div>
<div class="off-card">
<span class="off-label">Coaching</span>
<p>5+ years of coaching my son’s teams. I’ve learned that drawing up a great play on a whiteboard is the easy part. The real challenge is communicating it clearly enough that a dozen kids can actually execute it in real-time under pressure.</p>
</div>
</div>
</section>
<!-- ── Toolkit ───────────────────────────────────────────────────── -->
<section class="section s-border" aria-label="Toolkit">
<h2 class="sec-title reveal">Toolkit</h2>
<div class="tool-grid">
<div class="tool-card">
<h3>Research</h3>
<div class="c-tags">
<span class="c-tag">User Interviews</span>
<span class="c-tag">Usability Testing</span>
<span class="c-tag">Heuristics</span>
<span class="c-tag">Personas</span>
<span class="c-tag">Journey Maps</span>
<span class="c-tag">Empathy Maps</span>
<span class="c-tag">Task Flows</span>
<span class="c-tag">Benchmarking</span>
</div>
</div>
<div class="tool-card">
<h3>Design</h3>
<div class="c-tags">
<span class="c-tag">Figma</span>
<span class="c-tag">Wireframing</span>
<span class="c-tag">Prototyping</span>
<span class="c-tag">Hi-Fi Design</span>
<span class="c-tag">Design Systems</span>
<span class="c-tag">Typography</span>
<span class="c-tag">Info Architecture</span>
<span class="c-tag">Microinteractions</span>
</div>
</div>
<div class="tool-card">
<h3>Frontend</h3>
<div class="c-tags">
<span class="c-tag">HTML</span>
<span class="c-tag">CSS</span>
<span class="c-tag">JavaScript</span>
<span class="c-tag">GSAP</span>
<span class="c-tag">Debugging</span>
<span class="c-tag">Accessibility</span>
<span class="c-tag">Responsive</span>
<span class="c-tag">GitHub</span>
</div>
</div>
</div>
</section>
<!-- ── Closing ───────────────────────────────────────────────────────── -->
<section class="section s-border about-closing" aria-label="Contact">
<div class="closing-above">
<span class="closing-kicker" id="eof-kicker" aria-label="End Of File"></span>
<p class="closing-status-line">
<span id="eof-status"></span><span class="status-cursor" aria-hidden="true"></span>
</p>
</div>
<div class="closing-card closing-card-reveal">
<p class="closing-invite">Thanks for getting to know me.<br>Now I’d love to get to know you!</p>
<div class="closing-cta">
<a href="mailto:krfowler415@gmail.com" class="c-establish-btn">
<span>Establish Contact</span>
<span class="c-establish-arrow">→</span>
</a>
</div>
<div class="closing-links">
<a href="https://portfolio-kevin-fowler.vercel.app/index.html" class="c-secondary-link">
<span>← Phone Home</span>
</a>
<a href="https://portfolio-kevin-fowler.vercel.app/index.html#work" class="c-secondary-link">
<span>Access Case Files →</span>
</a>
</div>
</div>
</section>
<!-- ── End of Main ─────────────────────────────────────────────────────── -->
</main>
<!-- ── Footer ─────────────────────────────────────────────────────── -->
<footer>
<span class="foot-l">Kevin Fowler</span>
<span class="foot-r">© 2026 · Made in AZ · 🌵🌵</span>
</footer>
<!-- ── BeamUp Button ─────────────────────────────────────────────────────── -->
<button id="beamUp" aria-label="Scroll to top">
<svg width="11" height="11" viewBox="0 0 11 11" fill="none" aria-hidden="true" class="beam-arrow">
<path d="M5.5 9V2M5.5 2L2 5.5M5.5 2L9 5.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
Beam Me Up
</button>
<div id="beam-streak"></div>
<div id="beam-flash"></div>
<!-- ── js script ─────────────────────────────────────────────────────── -->
<script src="about.js"></script>
<!-- ── vfx script ─────────────────────────────────────────────────────── -->
<script type="module">
/* ── VFX-JS pixel scan title rotation ─────────────────────────────
*
* u_t is a FUNCTION uniform — VFX-JS calls it every frame.
* animating u_t 0→1 = enter scan (pixels materialise left→right)
* animating u_t 1→0 = exit scan (pixels dissolve right→left)
* Same shader. Same pixels. Both directions.
*
* Native h1 stays opacity:0 throughout.
* VFX canvas is the only render path — eliminates all font/transition issues.
*
* FONT FIX: we draw text ourselves with canvas 2D (has loaded web fonts),
* pass that canvas to vfx.add() instead of the h1 element.
* dom2canvas/SVG-foreignObject never runs → no system-font fallback.
*/
const { VFX } = await import('./vfx.js');
const h1 = document.getElementById('about-title');
const words = ['Designer', 'Researcher', 'Humanist', 'Dad'];
let idx = 0;
if (!h1) throw new Error('about-title not found');
h1.style.animation = 'none';
h1.style.opacity = '0';
const vfx = new VFX({ zIndex: 50 });
const wait = ms => new Promise(r => setTimeout(r, ms));
await document.fonts.ready;
await document.fonts.load('400 1em Audiowide');
const SCAN_MS = 2000;
// u_t: the single animation value VFX reads every frame
let u_t = 0;
const shader = `
precision highp float;
uniform sampler2D src;
uniform vec2 resolution;
uniform vec2 offset;
uniform float enterTime;
uniform float leaveTime;
uniform float u_t;
uniform int mode;
uniform float width;
#define W width
vec4 readTex(vec2 uv){
if(uv.x<0.||uv.x>1.||uv.y<0.||uv.y>1.)return vec4(0);
return texture2D(src,uv);
}
float hash(vec2 p){return fract(sin(dot(p,vec2(4859.,3985.)))*3984.);}
float sdBox(vec2 p,float r){vec2 q=abs(p)-r;return min(length(q),max(q.y,q.x));}
float toRangeT(vec2 p,float scale){
float d;
if(mode==0)d=p.x/(scale*2.)+.5;
else if(mode==1)d=1.-(p.y/(scale*2.)+.5);
else d=length(p)/scale;
return d;
}
vec4 cell(vec2 p,vec2 pi,float scale,float t,float edge){
vec2 pc=pi+.5;
vec2 uvc=pc/scale;uvc.y/=resolution.y/resolution.x;uvc=uvc*.5+.5;
if(uvc.x<0.||uvc.x>1.||uvc.y<0.||uvc.y>1.)return vec4(0);
float alpha=smoothstep(.0,.1,texture2D(src,uvc,3.).a);
float sel=fract(hash(pi+vec2(47.3,23.7)));
vec3 pal;
if(sel<.50)pal=vec3(.039,.765,.604);
else if(sel<.85)pal=vec3(.373,.145,.624);
else pal=vec3(.784,.094,.345);
vec4 color=vec4(pal,1.);
float x=toRangeT(pi,scale);float n=hash(pi);
float anim=smoothstep(W*2.,.0,abs(x+n*W-t));
color*=anim;
color*=mix(1.,clamp(.3/abs(sdBox(p-pc,.5)),0.,10.),edge*pow(anim,10.));
return color*alpha;
}
vec4 cellsColor(vec2 p,float scale,float t){
vec2 pi=floor(p);vec2 d=vec2(0,1);vec4 cc=vec4(0);
cc+=cell(p,pi,scale,t,.2)*4.;
cc+=cell(p,pi+d.xy,scale,t,.9);cc+=cell(p,pi-d.xy,scale,t,.9);
cc+=cell(p,pi+d.yx,scale,t,.9);cc+=cell(p,pi-d.yx,scale,t,.9);
return cc/8.;
}
vec4 draw(vec2 uv,vec2 p,float t,float scale){
vec4 c=readTex(uv);vec2 pi=floor(p*scale);float n=hash(pi);
t=t*(1.+W*4.)-W*2.;
float x=toRangeT(pi,scale);
float a1=smoothstep(t,t-W,x+n*W);c*=a1;
c+=cellsColor(p*scale,scale,t)*1.5;return c;
}
void main(){
vec2 uv=(gl_FragCoord.xy-offset)/resolution;
vec2 p=uv*2.-1.;p.y*=resolution.y/resolution.x;
// u_t: 0→1 enter (left→right), 1→0 exit (right→left, same shader)
float t=(fract(u_t*.99999)-.5)+.5;
for(int i=0;i<2;i++){float s=cos(float(i))*7.3+10.;gl_FragColor+=draw(uv,p,t,abs(s));}
gl_FragColor/=2.;
gl_FragColor*=smoothstep(0.,.01,t);
}`;
// Smooth ease-in-out for animation
function easeInOut(x) {
return x < 0.5 ? 2*x*x : 1 - Math.pow(-2*x+2,2)/2;
}
function animateT(from, to, ms) {
return new Promise(resolve => {
const t0 = performance.now();
(function tick(now) {
const raw = Math.min((now - t0) / ms, 1);
const progress = easeInOut(raw);
u_t = from + (to - from) * progress;
if (raw < 1) requestAnimationFrame(tick);
else { u_t = to; resolve(); }
})(t0);
});
}
// Draw word to canvas using canvas 2D — correct Audiowide font, no SVG fallback
function makeCanvas(word) {
const rect = h1.getBoundingClientRect();
const dpr = Math.min(window.devicePixelRatio || 1, 2);
const W = Math.ceil(rect.width);
const H = Math.ceil(rect.height);
const cv = document.createElement('canvas');
cv.width = W * dpr;
cv.height = H * dpr;
Object.assign(cv.style, {
position: 'absolute',
left: (rect.left + window.scrollX) + 'px',
top: (rect.top + window.scrollY) + 'px',
width: W + 'px', height: H + 'px', pointerEvents: 'none', opacity: '1',
});
const ctx = cv.getContext('2d');
ctx.scale(dpr, dpr);
ctx.font = '400 ' + getComputedStyle(h1).fontSize + ' Audiowide';
ctx.textBaseline = 'middle';
const g = ctx.createLinearGradient(0, 0, W, H);
g.addColorStop(0, '#F8F5FF');
g.addColorStop(1, '#E6FFF9');
ctx.fillStyle = g;
ctx.fillText(word, 0, H / 2);
document.body.appendChild(cv);
return cv;
}
async function run() {
await wait(400);
while (true) {
h1.textContent = words[idx]; // keep DOM in sync for a11y
const cv = makeCanvas(words[idx]);
u_t = 0;
await vfx.add(cv, {
shader,
overflow: 40,
intersection: { threshold: 0.1 },
uniforms: {
u_t: () => u_t, // function uniform — called every frame
mode: 0,
width: 0.22,
},
});
// Enter: scan in left→right
await animateT(0, 1, SCAN_MS);
// Hold word
await wait(1200);
// Exit: dissolve right→left (same shader, u_t reversed)
await animateT(1, 0, SCAN_MS);
try { vfx.remove(cv); } catch (_) {}
cv.remove();
idx = (idx + 1) % words.length;
}
}
run();
</script>
<!-- ── end ─────────────────────────────────────────────────────── -->
</body>
</html>
/*
* =====================================================================
* SONORAN COSMOS — ABOUT PAGE
* Kevin Fowler | krfowler415.github.io/portfolio
* =====================================================================
*
* § 1 Variables & Reset
* § 2 Body & Global
* § 3 Navigation
* § 4 Cursor
* § 5 Header
* § 6 The Long Version
* § 7 Off the Clock
* § 8 Toolkit
* § 9 Closing
* § 10 Footer
* § 11 Reveal & Animations
* § 12 Media Queries
* =====================================================================
*/
/* =====================================================================
* § 1 VARIABLES & RESET
* ===================================================================== */
:root {
--pulsar-50: #FFE8EE;
--pulsar-100: #FFB0C8;
--pulsar-200: #F87098;
--pulsar-400: #C81858;
--pulsar-600: #900840;
--pulsar-800: #580428;
--pulsar-900: #2C0114;
--cosmos-50: #F0EAF8;
--cosmos-100: #D4BAF0;
--cosmos-200: #B080E0;
--cosmos-300: #8B45D4;
--cosmos-400: #5F259F;
--cosmos-600: #431878;
--cosmos-800: #2A0E50;
--cosmos-900: #160828;
--aurora-50: #E3FDF8;
--aurora-100: #ADFAEC;
--aurora-200: #7FF6E4;
--aurora-400: #0AC39A;
--aurora-600: #17A487;
--aurora-800: #0F5042;
--aurora-900: #0C1916;
--plasma-50: #FFE8FA;
--plasma-100: #FFB0F0;
--plasma-200: #F870D8;
--plasma-400: #C818A8;
--plasma-600: #900878;
--plasma-800: #580448;
--plasma-900: #2C0124;
--aether-50: #F0F2FA;
--aether-100: #C8D0EC;
--aether-200: #98A8D4;
--aether-400: #5868A8;
--aether-600: #384880;
--aether-800: #202858;
--aether-900: #101430;
--bg: #100820;
--bg-dark: #100820;
--bg-surface: #1C1232;
--bg-raised: #281842;
--bg-tint: #5F259F47;
--text: #F4F2FF;
--text-muted: #C8D0EC;
--text-light: #7FF6E4;
--text-inv: #1C1210;
--primary: #0AC39A;
--primary-hover: #17A487;
--primary-lt: #7FF6E4;
--primary-subtle: #0C1916;
--accent-pulsar: #C81858;
--accent-pulsar-subtle: #2C0114;
--accent-cosmos: #5F259F;
--accent-cosmos-subtle: #160828;
--accent-aurora: #0AC39A;
--accent-aurora-subtle: #0C1916;
--accent-plasma: #C818A8;
--accent-plasma-subtle: #2C0124;
--aether: #98A8D4;
--border: #98A8D45A;
--border-subtle: #98A8D42D;
--aurora-glass: #0AC39A14;
--aurora-glow: #0AC39A40;
--aurora-inset: #0AC39A0D;
--display: 'Audiowide', sans-serif;
--Ox: 'Oxanium', system-ui, sans-serif;
--Orb: 'Orbitron', sans-serif;
--max: 1100px;
--max-text: 640px;
--px: clamp(1.25rem, 5vw, 3rem);
}
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; }
:focus-visible {
outline: 2px solid var(--accent-aurora);
outline-offset: 3px;
border-radius: 3px;
}
/* =====================================================================
* § 2 BODY & GLOBAL
* ===================================================================== */
body {
background:
radial-gradient(circle, #98A8D428 1px, transparent 1px) center / 28px 28px,
var(--bg);
background-attachment: fixed;
color: var(--text);
font-family: var(--Orb);
line-height: 1.6;
-webkit-font-smoothing: antialiased;
cursor: none;
overflow-x: hidden;
}
a { color: inherit; text-decoration: none; }
img { display: block; max-width: 100%; }
a, button { cursor: none; }
.skip-nav {
position: absolute;
top: -100%;
left: var(--px);
background: var(--primary);
color: var(--text);
font-family: var(--display);
font-size: 0.78rem;
font-weight: 600;
letter-spacing: 0.08em;
text-transform: uppercase;
padding: 0.6rem 1.2rem;
border-radius: 0 0 7px 7px;
z-index: 9999;
transition: top 0.2s ease;
}
.skip-nav:focus { top: 0; }
.section {
max-width: var(--max);
margin: 0 auto;
padding: 3rem var(--px) 5rem;
}
.section + .section { border-top: 1px solid var(--border); }
.sec-title {
font-family: var(--display);
font-size: clamp(1.75rem, 3.8vw, 2.6rem);
font-weight: 400;
letter-spacing: -0.025em;
line-height: 1.1;
background: linear-gradient(135deg, var(--text) 0%, var(--aurora-200) 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
color: transparent;
}
/* =====================================================================
* § 3 NAVIGATION
* ===================================================================== */
nav {
position: fixed;
top: 0; left: 0; right: 0;
z-index: 100;
height: 54px;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 var(--px);
background: rgba(16, 8, 32, 0.6);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
border-bottom: 1px solid #FFFFFF0A;
transition: background 0.4s ease, border-color 0.4s ease, box-shadow 0.4s ease;
}
nav.scrolled {
background: var(--bg-dark);
backdrop-filter: blur(16px);
-webkit-backdrop-filter: blur(16px);
border-bottom: 1px solid #0AC39A25;
box-shadow: 0 1px 20px #0AC39A10;
}
.nav-logo {
font-family: var(--display);
font-style: italic;
font-size: 1.5rem;
color: var(--text);
text-shadow: 0 0 25px #F4F2FF35;
}
.nav-logo:hover { opacity: 0.8; color: var(--aurora-200); }
/* Resume pill — right side of nav */
.nav-resume {
position: relative;
display: inline-block;
padding: 0.3rem;
font-family: var(--Orb);
font-size: 0.68rem;
font-weight: 500;
letter-spacing: 0.1em;
text-transform: uppercase;
color: var(--aurora-200);
text-decoration: underline;
text-decoration-color: #0AC39A40;
transition: color 0.2s ease;
}
.nav-resume:hover {
color: var(--text);
text-decoration: none;
text-shadow: 0 0 12px var(--accent-aurora);
}
.nav-resume::before,
.nav-resume::after {
position: absolute;
content: '';
right: 0; top: 0;
background: var(--text);
transition: all 0.3s ease;
}
.nav-resume::before { height: 0%; width: 1.5px; }
.nav-resume::after { width: 0%; height: 1.5px; }
.nav-resume:hover::before { height: 100%; }
.nav-resume:hover::after { width: 100%; }
.nav-resume span::before,
.nav-resume span::after {
position: absolute;
content: '';
left: 0; bottom: 0;
background: var(--text);
transition: all 0.3s ease;
}
.nav-resume span::before { width: 1.5px; height: 0%; }
.nav-resume span::after { width: 0%; height: 1.5px; }
.nav-resume:hover span::before { height: 100%; }
.nav-resume:hover span::after { width: 100%; }
/* =====================================================================
* § 4 CURSOR
* ===================================================================== */
#cur {
position: fixed;
z-index: 9999;
pointer-events: none;
top: 0; left: 0;
transform: translate(-50%, -50%);
}
.cur-dot {
position: absolute;
width: 11px; height: 11px;
background: var(--accent-aurora);
border-radius: 50%;
top: 50%; left: 50%;
transform: translate(-50%, -50%);
transition: transform 0.12s ease;
box-shadow:
0 0 8px 2px var(--aurora-400),
0 0 20px 4px #0AC39A60;
}
body.clicking .cur-dot { transform: translate(-50%, -50%) scale(0.5); }
/* =====================================================================
* § 5 HEADER
* ===================================================================== */
.about-header {
padding: calc(54px + 5rem) var(--px) 3rem;
position: relative;
overflow: hidden;
}
.about-header::before {
content: '';
position: absolute; inset: 0;
background: radial-gradient(ellipse 80% 60% at 50% 0%, #5F259F38 0%, transparent 70%);
pointer-events: none;
}
.about-header-inner {
max-width: var(--max);
margin: 0 auto;
position: relative; z-index: 1;
display: grid;
grid-template-columns: 1.2fr 1fr;
gap: 4rem;
align-items: center;
}
.about-title {
font-family: var(--display);
font-size: clamp(2.25rem, 5vw, 3.75rem);
font-weight: 400;
letter-spacing: -0.025em;
line-height: 1.15;
margin-bottom: 1.5rem;
background: linear-gradient(135deg, var(--text) 0%, var(--aurora-100) 100%);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
opacity: 0;
animation: up 0.6s ease forwards 0.2s;
}
.about-intro {
font-family: var(--Ox);
font-size: 1rem;
line-height: 1.9;
color: var(--text-muted);
max-width: var(--max-text);
opacity: 0;
animation: up 0.6s ease forwards 0.35s;
}
.about-intro strong { color: var(--accent-cosmos); font-weight: 600; }
.about-cta-down {
display: inline-flex;
align-items: center;
gap: 0.5rem;
margin-top: 1.75rem;
font-family: var(--Ox);
font-size: 1rem;
color: var(--text-muted);
opacity: 0;
animation: up 0.6s ease forwards 0.5s;
transition: none;
}
.cta-arrow {
animation: arrowBounceDown 1.8s ease-in-out infinite;
animation-delay: 1.2s;
color: var(--aether-400);
}
@keyframes arrowBounceDown {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(4px); }
}
/* Subject card */
.subject-card {
position: relative;
border-radius: 14px;
border: 2px solid var(--accent-aurora);
background: var(--bg-surface);
box-shadow:
0 20px 60px -20px #00000060,
0 0 18px -4px rgba(10,195,154,0.45),
0 0 40px -8px rgba(10,195,154,0.2),
inset 0 1px 0 #FFFFFF0A;
max-width: 440px;
margin: 0 auto;
overflow: hidden;
opacity: 0;
animation: up 0.7s ease forwards 0.3s;
transition: transform 0.25s ease, box-shadow 0.3s ease;
}
.subject-card:hover {
transform: translateY(-3px);
box-shadow:
0 24px 60px -16px #00000070,
0 0 0 1px var(--accent-aurora),
0 0 30px -2px rgba(10,195,154,0.6),
0 0 60px -8px rgba(10,195,154,0.25),
inset 0 1px 0 #FFFFFF14;
}
.subject-card-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 1.1rem 1.4rem 1rem;
border-bottom: 1px solid var(--border-subtle);
}
.subject-card::after {
content: '';
position: absolute;
left: 0; right: 0;
top: -80px;
height: 80px;
background: linear-gradient(
to bottom,
transparent 0%,
rgba(10, 195, 154, 0.07) 25%,
rgba(10, 195, 154, 0.2) 50%,
rgba(10, 195, 154, 0.07) 75%,
transparent 100%
);
pointer-events: none;
z-index: 10;
}
.subject-card:hover::after {
animation: scanBeam 1.5s ease-in-out infinite;
}
.subject-card-eyebrow {
font-family: var(--Orb);
font-size: 0.62rem;
font-weight: 600;
letter-spacing: 0.14em;
text-transform: uppercase;
color: var(--accent-aurora);
}
.subject-file-no {
font-family: var(--Orb);
font-size: 0.6rem;
font-weight: 600;
letter-spacing: 0.1em;
color: var(--aether-400);
}
.subject-card-body {
display: grid;
grid-template-columns: 180px 1fr;
overflow: hidden;
border-radius: 0 0 12.5px 12.5px;
}
.sc-corners {
position: absolute;
inset: 7px;
pointer-events: none;
z-index: 3;
}
.sc-corners::before {
content: '';
position: absolute;
top: 0; left: 0;
width: 14px; height: 14px;
border-top: 1.5px solid var(--accent-aurora);
border-left: 1.5px solid var(--accent-aurora);
}
.sc-corners::after {
content: '';
position: absolute;
bottom: 0; right: 0;
width: 14px; height: 14px;
border-bottom: 1.5px solid var(--accent-aurora);
border-right: 1.5px solid var(--accent-aurora);
}
.subject-mugshot {
position: relative;
background: var(--bg-dark);
border-right: 1px solid var(--border-subtle);
border-bottom-left-radius: 12.5px;
overflow: hidden;
display: flex;
flex-direction: column;
-webkit-mask-image: linear-gradient(to bottom, black 0%, black 58%, transparent 96%);
mask-image: linear-gradient(to bottom, black 0%, black 58%, transparent 96%);
}
.subject-mugshot img {
width: 100%;
flex: 1;
object-fit: cover;
object-position: center top;
display: block;
filter: grayscale(20%) contrast(1.02);
}
.subject-mugshot::before {
content: '';
position: absolute;
inset: 0;
background: radial-gradient(ellipse at 50% 40%, transparent 35%, rgba(0,0,0,0.6) 100%);
pointer-events: none;
z-index: 2;
}
.subject-mugshot::after {
content: '';
position: absolute;
inset: 0;
background: repeating-linear-gradient(
0deg,
rgba(0, 0, 0, 0.28) 0px,
rgba(0, 0, 0, 0.28) 1px,
transparent 1px,
transparent 3px
);
pointer-events: none;
z-index: 1;
}
.subject-mugshot img {
animation: crtGlitch 2s steps(1) infinite;
}
.subject-mugshot::after {
animation: scanlineShift 0.18s linear infinite;
}
.subject-right {
display: flex;
flex-direction: column;
min-width: 0;
}
.subject-name {
font-family: var(--display);
font-size: 0.9rem;
font-weight: 400;
letter-spacing: 0.04em;
text-transform: uppercase;
color: var(--text);
padding: 0.85rem 1.1rem 0.7rem;
border-bottom: 1px solid var(--border-subtle);
flex-shrink: 0;
}
.subject-fields {
display: flex;
flex-direction: column;
gap: 0.7rem;
padding: 0.8rem 1.1rem 1rem;
flex: 1;
}
.subject-row {
display: grid;
grid-template-columns: 80px 1fr;
gap: 0.5rem;
align-items: baseline;
}
.subject-row dt {
font-family: var(--Orb);
font-size: 0.6rem;
font-weight: 600;
letter-spacing: 0.1em;
text-transform: uppercase;
color: var(--aether-400);
}
.subject-row dd {
font-family: var(--Ox);
font-size: 0.88rem;
color: var(--text-muted);
}
.subject-status {
display: inline-flex;
align-items: center;
gap: 0.45rem;
color: var(--accent-aurora);
}
.subject-status::before {
content: '';
flex-shrink: 0;
width: 6px; height: 6px;
border-radius: 50%;
background: var(--accent-aurora);
box-shadow: 0 0 6px var(--aurora-400);
animation: statusPulse 2.2s ease-in-out infinite;
}
/* =====================================================================
* § 6 THE LONG VERSION
* ===================================================================== */
.story-list {
display: flex;
flex-direction: column;
gap: 3.5rem;
margin-top: 3rem;
position: relative;
padding-left: 2.5rem;
}
.story-entry {
display: grid;
grid-template-columns: 180px 1fr;
gap: 2.5rem;
position: relative;
}
.story-when {
font-family: var(--Orb);
font-size: 0.7rem;
font-weight: 600;
letter-spacing: 0.12em;
text-transform: uppercase;
color: var(--aether-200);
line-height: 1.7;
}
.story-when span {
display: block;
font-family: var(--Ox);
font-size: 0.85rem;
font-weight: 400;
letter-spacing: 0;
text-transform: none;
color: var(--text-muted);
margin-top: 0.4rem;
}
.story-entry h3 {
font-family: var(--Orb);
font-size: clamp(1.2rem, 2.4vw, 1.55rem);
font-weight: 600;
letter-spacing: 0;
line-height: 1.3;
margin-bottom: 0.75rem;
}
/* Entry 1 — aurora */
.story-entry:nth-child(1) h3 {
color: var(--accent-aurora);
}
/* Entry 2 — cosmos */
.story-entry:nth-child(2) h3 {
color: var(--cosmos-300);
}
/* Entry 3 — pulsar */
.story-entry:nth-child(3) h3 {
color: var(--accent-pulsar);
}
.story-entry p {
font-family: var(--Ox);
font-size: 1rem;
line-height: 1.9;
color: var(--text-muted);
max-width: var(--max-text);
}
.story-entry p + p { margin-top: 1rem; }
/* Vertical glowing timeline line */
.story-list::before {
content: '';
position: absolute;
left: 7px;
top: 0.4rem;
bottom: 0.4rem;
width: 2px;
background: linear-gradient(
to bottom,
var(--accent-aurora) 0%,
var(--accent-cosmos) 50%,
var(--accent-pulsar) 100%
);
border-radius: 2px;
box-shadow:
0 0 6px var(--accent-aurora),
0 0 18px rgba(10,195,154,0.25);
transform-origin: top center;
transform: scaleY(var(--line-progress, 0));
transition: transform 0.12s linear;
animation: timelineGlow 5s ease-in-out infinite;
}
@keyframes timelineGlow {
0%, 100% { opacity: 0.55; }
50% { opacity: 0.9; }
}
/* Node dots */
.story-entry::before {
content: '';
position: absolute;
left: calc(-2.5rem + 2px);
top: 0.3em;
width: 12px;
height: 12px;
border-radius: 50%;
border: 2.5px solid var(--bg);
background: var(--accent-aurora);
box-shadow:
0 0 0 1.5px var(--accent-aurora),
0 0 8px var(--accent-aurora),
0 0 20px rgba(10,195,154,0.3);
animation: pulseAurora 3s ease-in-out infinite;
}
.story-entry:nth-child(2)::before {
background: var(--accent-cosmos);
box-shadow:
0 0 0 1.5px var(--accent-cosmos),
0 0 8px var(--accent-cosmos),
0 0 20px rgba(95,37,159,0.35);
animation: pulseCosmos 3s ease-in-out 1s infinite;
}
.story-entry:nth-child(3)::before {
background: var(--accent-pulsar);
box-shadow:
0 0 0 1.5px var(--accent-pulsar),
0 0 8px var(--accent-pulsar),
0 0 20px rgba(200,24,88,0.3);
animation: pulsePulsar 3s ease-in-out 2s infinite;
}
@keyframes pulseAurora {
0%, 100% {
transform: scale(1);
box-shadow:
0 0 0 1.5px var(--accent-aurora),
0 0 8px var(--accent-aurora),
0 0 20px rgba(10,195,154,0.3);
}
50% {
transform: scale(1.4);
box-shadow:
0 0 0 3px var(--accent-aurora),
0 0 20px var(--accent-aurora),
0 0 50px rgba(10,195,154,0.8),
0 0 90px rgba(10,195,154,0.35);
}
}
@keyframes pulseCosmos {
0%, 100% {
transform: scale(1);
box-shadow:
0 0 0 1.5px var(--accent-cosmos),
0 0 8px var(--accent-cosmos),
0 0 20px rgba(95,37,159,0.35);
}
50% {
transform: scale(1.4);
box-shadow:
0 0 0 3px var(--accent-cosmos),
0 0 20px var(--accent-cosmos),
0 0 50px rgba(95,37,159,0.85),
0 0 90px rgba(95,37,159,0.4);
}
}
@keyframes pulsePulsar {
0%, 100% {
transform: scale(1);
box-shadow:
0 0 0 1.5px var(--accent-pulsar),
0 0 8px var(--accent-pulsar),
0 0 20px rgba(200,24,88,0.3);
}
50% {
transform: scale(1.4);
box-shadow:
0 0 0 3px var(--accent-pulsar),
0 0 20px var(--accent-pulsar),
0 0 50px rgba(200,24,88,0.8),
0 0 90px rgba(200,24,88,0.35);
}
}
/* =====================================================================
* § 7 OFF THE CLOCK
* ===================================================================== */
.off-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1.25rem;
margin-top: 3rem;
}
.off-card {
background:
linear-gradient(135deg, var(--cosmos-900), var(--cosmos-800)) padding-box,
linear-gradient(135deg, var(--accent-pulsar) 0%, var(--accent-cosmos) 100%) border-box;
border: 1.5px solid transparent;
border-radius: 10px;
padding: 1.4rem;
position: relative;
overflow: hidden;
box-shadow:
0 0 0 1px #98A8D418,
0 0 15px rgba(200,24,88,0.1),
inset 0 1px 0 rgba(200,24,88,0.15);
transition: transform 0.25s ease, box-shadow 0.3s ease;
will-change: transform;
}
.off-card::before {
content: '';
position: absolute;
top: 0; left: 0;
width: 3px; height: 100%;
background: var(--accent-pulsar);
border-radius: 3px 0 0 3px;
box-shadow: 2px 0 12px rgba(200,24,88,0.5);
}
.off-card::after {
content: '';
position: absolute;
bottom: 8px; right: 8px;
width: 10px; height: 10px;
border-bottom: 1.5px solid var(--accent-aurora);
border-right: 1.5px solid var(--accent-aurora);
opacity: 0.45;
pointer-events: none;
}
.off-card:hover {
transform: translateY(-3px);
box-shadow:
0 0 0 1px rgba(200,24,88,0.3),
0 0 20px rgba(200,24,88,0.12),
inset 0 1px 0 rgba(200,24,88,0.2);
}
.off-label {
display: block;
font-family: var(--Orb);
font-size: 0.7rem;
font-weight: 600;
letter-spacing: 0.14em;
text-transform: uppercase;
color: var(--accent-pulsar);
margin-bottom: 0.6rem;
}
.off-card p {
font-family: var(--Ox);
font-size: 0.92rem;
line-height: 1.7;
color: var(--text-muted);
}
/* =====================================================================
* § 8 TOOLKIT
* ===================================================================== */
.tool-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1.25rem;
margin-top: 2rem;
align-items: stretch;
}
.tool-card {
background:
linear-gradient(135deg, var(--cosmos-900), var(--cosmos-800)) padding-box,
linear-gradient(135deg, var(--accent-pulsar) 0%, var(--accent-cosmos) 100%) border-box;
border: 1.5px solid transparent;
border-radius: 10px;
padding: 1.4rem;
position: relative;
overflow: hidden;
box-shadow:
0 0 0 1px #98A8D418,
0 0 15px rgba(200,24,88,0.1),
inset 0 1px 0 rgba(200,24,88,0.2);
transition: transform 0.25s ease, box-shadow 0.3s ease;
will-change: transform;
}
.tool-card::before {
content: '';
position: absolute;
top: 0; left: 0;
width: 3px; height: 100%;
background: var(--accent-pulsar);
border-radius: 3px 0 0 3px;
box-shadow: 2px 0 12px rgba(200,24,88,0.5);
}
.tool-card::after {
content: '';
position: absolute;
bottom: 8px; right: 8px;
width: 10px; height: 10px;
border-bottom: 1.5px solid var(--accent-aurora);
border-right: 1.5px solid var(--accent-aurora);
opacity: 0.45;
pointer-events: none;
}
.tool-card:hover {
transform: translateY(-3px);
box-shadow:
0 0 0 1px rgba(200,24,88,0.25),
0 0 20px rgba(200,24,88,0.12),
inset 0 1px 0 rgba(200,24,88,0.3);
}
.tool-card h3 {
font-family: var(--Orb);
font-size: 0.7rem;
font-weight: 600;
letter-spacing: 0.14em;
text-transform: uppercase;
color: var(--accent-pulsar);
margin-bottom: 1rem;
}
.c-tags {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 0.5rem;
}
.c-tag {
font-family: var(--Ox);
font-size: 0.8rem;
padding: 0.3rem 0.75rem;
border-radius: 20px;
background: var(--bg-tint);
border: 1px solid rgba(200,24,88,0.2);
color: var(--text-muted);
transition: transform 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease;
}
.c-tag:hover {
transform: translateY(-2px);
border-color: var(--accent-pulsar);
box-shadow: 0 0 8px rgba(200,24,88,0.3);
}
/* =====================================================================
* § 9 CLOSING
* ===================================================================== */
.about-closing {
text-align: center;
padding-top: 3rem;
padding-bottom: 5rem;
}
/* ── Above-card block: kicker + status ── */
.closing-above {
display: flex;
flex-direction: column;
align-items: center;
gap: 0.6rem;
margin-bottom: 1.75rem;
padding-bottom: 1.5rem;
}
.closing-kicker {
font-family: var(--Orb);
font-size: 0.85rem;
font-weight: 500;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--accent-pulsar);
display: inline-block;
white-space: nowrap;
border-right: 2px solid transparent;
}
.closing-kicker.cursor-active {
border-right-color: var(--accent-pulsar);
animation: eofKickerBlink 1s step-end infinite;
}
@keyframes eofKickerBlink {
0%, 100% { border-right-color: var(--accent-pulsar); }
50% { border-right-color: transparent; }
}
.closing-status-line {
font-family: var(--Orb);
font-size: 0.62rem;
line-height: 1.7;
letter-spacing: 0.1em;
text-transform: uppercase;
color: var(--accent-pulsar);
display: inline-flex;
align-items: center;
flex-wrap: wrap;
justify-content: center;
gap: 0.3em;
}
.closing-status-line strong {
color: var(--accent-pulsar);
font-weight: 500;
}
/* Blinking cursor — sits at end of status text */
.status-cursor {
display: inline-block;
width: 2px;
height: 1.5em;
background: var(--accent-pulsar);
margin-left: 1px;
vertical-align: middle;
opacity: 0;
}
.status-cursor.active {
opacity: 1;
animation: eofCursorBlink 1s step-end infinite;
}
@keyframes eofCursorBlink {
0%, 100% { opacity: 1; }
50% { opacity: 0; }
}
/* ── Card ── */
.closing-card {
background: linear-gradient(135deg, var(--cosmos-900), var(--cosmos-800));
border: 1px solid var(--border);
border-radius: 14px;
padding: 3.5rem;
display: flex;
flex-direction: column;
gap: 1.5rem;
align-items: center;
text-align: center;
width: 100%;
position: relative;
box-shadow:
0 0 0 1px #98A8D420,
0 0 50px #5F259F30,
inset 0 1px 0 #5F259F60;
}
/* Top-left corner bracket */
.closing-card::before {
content: '';
position: absolute;
top: 16px; left: 16px;
width: 14px; height: 14px;
border-top: 1.5px solid var(--accent-aurora);
border-left: 1.5px solid var(--accent-aurora);
opacity: 0.5;
pointer-events: none;
}
/* Bottom-right corner bracket */
.closing-card::after {
content: '';
position: absolute;
bottom: 16px; right: 16px;
width: 14px; height: 14px;
border-bottom: 1.5px solid var(--accent-aurora);
border-right: 1.5px solid var(--accent-aurora);
opacity: 0.5;
pointer-events: none;
}
/* Card fade-in — triggered by JS after status finishes typing */
.closing-card-reveal {
opacity: 0;
transform: translateY(10px);
transition: opacity 1s ease-out, transform 1s ease-out;
}
.closing-card-reveal.in {
opacity: 1;
transform: none;
}
/* ── Invite text ── */
.closing-invite {
font-family: var(--display);
font-size: clamp(1.2rem, 2vw, 1.55rem);
background: linear-gradient(135deg, var(--text) 0%, var(--aurora-100) 100%);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
}
/* ── Establish Contact CTA ── */
.closing-cta {
display: flex;
justify-content: center;
}
.c-establish-btn {
display: flex;
align-items: center;
justify-content: center;
width: fit-content;
padding: 1.25rem 3rem;
gap: 1rem;
background: linear-gradient(135deg, var(--aurora-400) 0%, var(--cosmos-600) 100%);
border-radius: 10px;
color: var(--text);
font-family: var(--Orb);
font-size: clamp(1rem, 2vw, 1.4rem);
font-weight: 600;
letter-spacing: 0.05em;
text-transform: uppercase;
text-decoration: none;
position: relative;
z-index: 1;
cursor: none;
transition: box-shadow 0.3s ease;
box-shadow:
0 0 25px #0AC39A50,
0 0 60px #0AC39A25;
}
.c-establish-btn::after {
position: absolute;
content: "";
width: 100%; height: 0;
bottom: 0; left: 0;
z-index: -1;
border-radius: 10px;
background: linear-gradient(135deg, var(--cosmos-600) 0%, var(--aurora-400) 100%);
transition: all 0.3s ease;
}
.c-establish-btn:hover::after { top: 0; height: 100%; }
.c-establish-btn:hover {
box-shadow:
0 0 35px #0AC39A70,
0 0 80px #0AC39A35;
}
.c-establish-arrow {
font-size: 2rem;
transition: transform 0.2s ease;
}
.c-establish-btn:hover .c-establish-arrow { transform: translateX(4px); }
/* ── Ghost links ── */
.closing-links {
display: flex;
justify-content: center;
gap: 2.5rem;
flex-wrap: wrap;
}
.c-secondary-link {
position: relative;
display: inline-block;
padding: 0.3rem;
font-family: var(--Orb);
font-size: 0.68rem;
font-weight: 500;
letter-spacing: 0.1em;
text-transform: uppercase;
color: var(--aurora-200);
text-decoration: underline;
text-decoration-color: #0AC39A40;
transition: color 0.2s ease;
}
.c-secondary-link:hover {
color: var(--text);
text-decoration: none;
text-shadow: 0 0 12px var(--accent-aurora);
}
.c-secondary-link::before,
.c-secondary-link::after {
position: absolute;
content: '';
right: 0; top: 0;
background: var(--text);
transition: all 0.3s ease;
}
.c-secondary-link::before { height: 0%; width: 1.5px; }
.c-secondary-link::after { width: 0%; height: 1.5px; }
.c-secondary-link:hover::before { height: 100%; }
.c-secondary-link:hover::after { width: 100%; }
.c-secondary-link span::before,
.c-secondary-link span::after {
position: absolute;
content: '';
left: 0; bottom: 0;
background: var(--text);
transition: all 0.3s ease;
}
.c-secondary-link span::before { width: 1.5px; height: 0%; }
.c-secondary-link span::after { width: 0%; height: 1.5px; }
.c-secondary-link:hover span::before { height: 100%; }
.c-secondary-link:hover span::after { width: 100%; }
/* =====================================================================
* § 10 FOOTER
* ===================================================================== */
footer {
border-top: 1px solid var(--border);
max-width: var(--max);
margin: 0 auto;
padding: 1.6rem var(--px);
display: flex;
align-items: center;
justify-content: space-between;
}
.foot-l {
font-family: var(--display);
font-style: italic;
font-size: 0.92rem;
color: var(--aurora-200);
}
.foot-r {
font-family: var(--display);
font-size: 0.72rem;
color: #C8185870;
}
/* ── Beam Me Up ── */
#beamUp {
position: fixed;
bottom: 2rem;
right: var(--px);
z-index: 500;
display: inline-flex;
align-items: center;
gap: 0.5rem;
padding: 0.6rem 1.1rem;
background: linear-gradient(135deg, var(--aurora-400) 0%, var(--cosmos-600) 100%);
border: none;
border-radius: 100px;
color: var(--text);
font-family: var(--Orb);
font-size: 0.68rem;
font-weight: 600;
letter-spacing: 0.08em;
text-transform: uppercase;
white-space: nowrap;
opacity: 0;
transform: translateY(10px);
pointer-events: none;
transition: opacity 0.4s ease, transform 0.4s ease, filter 0.25s ease, box-shadow 0.3s ease;
box-shadow:
inset 0 1.5px 0 rgba(255,255,255,0.45),
inset 0 -3px 5px rgba(0,0,0,0.3),
0 4px 14px rgba(0,0,0,0.35),
0 0 20px #0AC39A40,
0 0 50px #0AC39A20;
cursor: none;
}
#beamUp::before {
content: '';
position: absolute;
inset: 0;
border-radius: 100px;
background: linear-gradient(to bottom, rgba(255,255,255,0.35) 0%, rgba(255,255,255,0) 55%);
pointer-events: none;
}
#beamUp.visible {
opacity: 1;
transform: translateY(0);
pointer-events: auto;
}
#beamUp:hover {
filter: brightness(1.12);
transform: translateY(-2px);
box-shadow:
inset 0 1px 0 rgba(255,255,255,0.3),
inset 0 -2px 4px rgba(0,0,0,0.15),
0 6px 18px rgba(0,0,0,0.4),
0 0 30px #0AC39A60,
0 0 70px #0AC39A30;
}
#beamUp:active {
transform: translateY(1px);
box-shadow:
inset 0 1px 0 rgba(255,255,255,0.15),
inset 0 2px 4px rgba(0,0,0,0.3),
0 1px 4px rgba(0,0,0,0.3),
0 0 20px #0AC39A40,
0 0 50px #0AC39A20;
}
#beamUp.visible .beam-arrow { animation: arrowBounce 1.8s ease-in-out infinite; }
#beamUp:hover .beam-arrow { animation-play-state: paused; }
#beam-streak {
position: fixed;
width: 3px;
height: 0;
background: linear-gradient(to top, var(--aurora-400) 0%, rgba(10,195,154,0.5) 50%, transparent 100%);
z-index: 9998;
pointer-events: none;
opacity: 0;
border-radius: 3px;
box-shadow: 0 0 8px var(--aurora-400), 0 0 20px #0AC39A60;
}
#beam-flash {
position: fixed;
inset: 0;
background: var(--aurora-400);
opacity: 0;
z-index: 9999;
pointer-events: none;
}
/* ── Title scan wipe ── */
.about-title.scan-wipe {
animation: scanWipe 0.45s cubic-bezier(0.4, 0, 0.2, 1) both;
}
@keyframes scanWipe {
0% { clip-path: inset(0 100% 0 0); opacity: 0.4; }
40% { clip-path: inset(0 45% 0 0); opacity: 0.9; }
100% { clip-path: inset(0 0% 0 0); opacity: 1; }
}
/* =====================================================================
* § 11 REVEAL & ANIMATIONS
* ===================================================================== */
.reveal {
opacity: 0;
transform: translateY(22px);
transition: opacity 0.7s ease, transform 0.7s ease;
}
.reveal.in { opacity: 1; transform: none; }
.reveal-left {
opacity: 0;
transform: translateX(-24px);
transition: opacity 0.7s ease, transform 0.7s ease;
}
.reveal-left.in { opacity: 1; transform: none; }
.reveal-right {
opacity: 0;
transform: translateX(24px);
transition: opacity 0.7s ease, transform 0.7s ease;
}
.reveal-right.in { opacity: 1; transform: none; }
@keyframes up {
from { opacity: 0; transform: translateY(14px); }
to { opacity: 1; transform: translateY(0); }
}
@keyframes rippleOut {
to { transform: translate(-50%, -50%) scale(8); opacity: 0; }
}
@keyframes scanBeam {
from { top: -80px; }
to { top: 110%; }
}
@keyframes crtGlitch {
0%, 100% { filter: grayscale(20%) contrast(1.02) brightness(1); transform: translateX(0); }
8% { filter: grayscale(20%) contrast(1.02) brightness(0.85); }
9% { filter: grayscale(20%) contrast(1.02) brightness(1); }
38% { filter: grayscale(20%) contrast(1.02) brightness(1); transform: translateX(0); }
39% { filter: grayscale(5%) contrast(1.06) brightness(1.04) hue-rotate(155deg) saturate(0.5); transform: translateX(1px); }
40% { filter: grayscale(5%) contrast(1.06) brightness(1.04) hue-rotate(155deg) saturate(0.5); transform: translateX(-1px); }
41% { filter: grayscale(20%) contrast(1.02) brightness(1); transform: translateX(0); }
72% { filter: grayscale(20%) contrast(1.02) brightness(1); }
73% { filter: grayscale(25%) contrast(0.98) brightness(0.9); }
74% { filter: grayscale(20%) contrast(1.02) brightness(1); }
}
@keyframes scanlineShift {
from { background-position: 0 0; }
to { background-position: 0 3px; }
}
@keyframes statusPulse {
0%, 100% { opacity: 1; box-shadow: 0 0 6px var(--aurora-400); }
50% { opacity: 0.4; box-shadow: none; }
}
@keyframes arrowBounce {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-3px); }
}
/* =====================================================================
* § 12 MEDIA QUERIES
* ===================================================================== */
@media (max-width: 900px) {
.about-header-inner { grid-template-columns: 1fr; gap: 2.5rem; }
.subject-card { max-width: 400px; }
}
@media (max-width: 700px) {
.section { padding: 4rem var(--px); }
.about-header { padding: calc(54px + 3.5rem) var(--px) 3.5rem; }
.story-entry { grid-template-columns: 1fr; gap: 0.75rem; }
.story-when { display: flex; align-items: baseline; gap: 0.6rem; }
.story-when span { margin-top: 0; }
.story-list { padding-left: 1.75rem; }
.story-list::before { left: 5px; }
.story-entry::before { left: calc(-1.75rem + 2px); width: 10px; height: 10px; }
.off-grid { grid-template-columns: 1fr; }
.tool-grid { grid-template-columns: 1fr; }
.c-tags { grid-template-columns: 1fr 1fr; }
.closing-links { gap: 1.5rem 2rem; }
}
@media (max-width: 480px) {
.c-tags { grid-template-columns: 1fr; }
.c-tag { width: fit-content; }
.c-establish-btn { padding: 1rem 1.5rem; font-size: 0.9rem; }
}
@media (prefers-reduced-motion: reduce) {
.about-eyebrow, .about-title, .about-intro, .subject-card {
animation: none;
opacity: 1;
}
.subject-mugshot img,
.subject-mugshot::after { animation: none; }
.subject-card:hover::after { animation: none; }
#beamUp { display: none; }
.closing-kicker { animation: none !important; }
.status-cursor { display: none !important; }
.closing-card-reveal { opacity: 1 !important; transform: none !important; }
}
Error code
ERRW:0.86:K1.0:AS
Were you logged in?
Yes
Your username (if logged in)
krfowler415
Your HTML
Your JavaScript
Your CSS