Refactor design elements and enhance animations for improved user experience. Updated color palette in dev/design.json to feature a more vibrant orange accent. Revamped footer, navigation, and section layouts for better aesthetics and responsiveness. Introduced new animation classes for scroll-triggered effects, enhancing visual engagement across the site.

This commit is contained in:
Nicholai 2025-12-06 14:23:00 -07:00
parent 3096a4dabb
commit d6411f4dd1
12 changed files with 481 additions and 255 deletions

View File

@ -40,22 +40,22 @@
"usage": "Secondary backgrounds, panels, cards"
},
"brand_accent": {
"hex": "#FFB84C",
"rgb": "255, 184, 76",
"name": "Orange/Yellow",
"hex": "#ff4d00",
"rgb": "255, 77, 0",
"name": "Vibrant Orange",
"usage": "Primary accent, CTAs, highlights, interactive elements",
"opacity_variants": [
{
"name": "brand_accent_5",
"value": "rgba(255, 184, 76, 0.05)"
"value": "rgba(255, 77, 0, 0.05)"
},
{
"name": "brand_accent_20",
"value": "rgba(255, 184, 76, 0.2)"
"value": "rgba(255, 77, 0, 0.2)"
},
{
"name": "brand_accent_50",
"value": "rgba(255, 184, 76, 0.5)"
"value": "rgba(255, 77, 0, 0.5)"
}
]
},
@ -439,7 +439,7 @@
"accent_glow": "shadow-lg shadow-brand-accent/20",
"cyan_glow": "shadow-lg shadow-brand-cyan/20",
"red_glow": "shadow-lg shadow-brand-red/20",
"custom_glow": "shadow-[0_0_10px_rgba(255,184,76,0.5)]",
"custom_glow": "shadow-[0_0_10px_rgba(255,77,0,0.5)]",
"drop_shadow": "drop-shadow-2xl"
},
"blur": {
@ -626,7 +626,7 @@
},
"status_indicator": {
"dot": "w-2 h-2 bg-brand-accent rounded-full animate-pulse",
"glow": "shadow-[0_0_10px_rgba(255,184,76,0.5)]",
"glow": "shadow-[0_0_10px_rgba(255,77,0,0.5)]",
"label": "text-xs font-bold text-slate-500 tracking-widest uppercase font-mono"
}
},
@ -798,7 +798,7 @@
"design_tokens_summary": {
"primary_background": "#0B0D11",
"secondary_background": "#151921",
"primary_accent": "#FFB84C",
"primary_accent": "#ff4d00",
"primary_text": "#FFFFFF",
"secondary_text": "#94A3B8",
"border_subtle": "rgba(255, 255, 255, 0.1)",
@ -806,7 +806,7 @@
"font_primary": "Inter, sans-serif",
"font_mono": "monospace",
"radius_minimal": "0 or 2px (rarely used)",
"shadow_glow": "0 0 10px rgba(255,184,76,0.5)",
"shadow_glow": "0 0 10px rgba(255,77,0,0.5)",
"transition_fast": "300ms",
"transition_medium": "500ms",
"transition_slow": "700ms"

View File

@ -2,44 +2,51 @@
const today = new Date();
---
<footer class="container mx-auto px-6 lg:px-12 py-32 relative overflow-hidden">
<div class="grid grid-cols-1 md:grid-cols-2 gap-12 items-end">
<div>
<h2
class="text-6xl md:text-8xl font-bold uppercase leading-none tracking-tighter mb-8 text-white group cursor-pointer">
<footer class="container mx-auto px-6 lg:px-12 py-32 lg:py-40 relative overflow-hidden border-t border-white/5">
<div class="grid grid-cols-1 md:grid-cols-2 gap-16 lg:gap-24 items-end relative z-10">
<div class="animate-on-scroll slide-right">
<h2 class="text-5xl md:text-7xl lg:text-8xl font-bold uppercase leading-[0.95] tracking-tighter mb-10 text-white group cursor-pointer">
Let's<br>
<span
class="text-stroke group-hover:text-brand-accent transition-colors duration-300">Build</span><br>
<span class="text-stroke group-hover:text-brand-accent transition-all duration-500 ease-out">Build</span><br>
Reality.
</h2>
<div class="flex flex-wrap gap-6 mt-12">
<div class="flex flex-wrap gap-4 lg:gap-6 mt-12">
<a href="mailto:nicholai@nicholai.work" class="btn-primary">nicholai@nicholai.work</a>
<a href="tel:7196604281" class="btn-ghost">719 660 4281</a>
</div>
</div>
<div class="md:text-right">
<div class="mb-12">
<p class="text-xs font-bold uppercase text-slate-500 mb-4 tracking-widest">Social Uplink</p>
<ul class="space-y-2">
<li><a href="https://nicholai.work"
class="text-white hover:text-brand-accent text-lg font-mono">nicholai.work</a></li>
<li><a href="#"
class="text-white hover:text-brand-accent text-lg font-mono">@nicholai.exe</a></li>
<li><a href="#" class="text-white hover:text-brand-accent text-lg font-mono">LinkedIn</a>
<div class="md:text-right animate-on-scroll slide-left stagger-2">
<div class="mb-14">
<p class="text-xs font-bold uppercase text-slate-500 mb-6 tracking-widest">Social Uplink</p>
<ul class="space-y-3">
<li>
<a href="https://nicholai.work" class="text-white hover:text-brand-accent text-lg font-mono transition-colors duration-300 inline-block">
nicholai.work
</a>
</li>
<li>
<a href="#" class="text-white hover:text-brand-accent text-lg font-mono transition-colors duration-300 inline-block">
@nicholai.exe
</a>
</li>
<li>
<a href="#" class="text-white hover:text-brand-accent text-lg font-mono transition-colors duration-300 inline-block">
LinkedIn
</a>
</li>
</ul>
</div>
<div class="flex justify-end items-end gap-2 text-[10px] text-slate-600 font-mono uppercase">
<div class="flex md:justify-end items-end gap-3 text-[10px] text-slate-600 font-mono uppercase tracking-wide">
<span>&copy; {today.getFullYear()} Nicholai Vogel</span>
<span>/</span>
<span class="text-slate-700">/</span>
<span>V7 SYSTEM</span>
</div>
</div>
</div>
<!-- Decorative huge text bg -->
<div class="absolute -bottom-10 left-0 w-full text-center pointer-events-none opacity-5">
<span class="text-[15rem] font-bold text-white uppercase leading-none whitespace-nowrap">VOGEL</span>
<div class="absolute -bottom-8 lg:-bottom-12 left-1/2 -translate-x-1/2 w-full text-center pointer-events-none select-none">
<span class="text-[12rem] md:text-[18rem] lg:text-[22rem] font-extrabold text-white/[0.02] uppercase leading-none whitespace-nowrap tracking-tighter">VOGEL</span>
</div>
</footer>

View File

@ -1,19 +1,36 @@
---
---
<nav
class="fixed top-0 left-0 w-full z-50 px-6 lg:px-12 py-8 flex justify-end items-center gap-12 backdrop-blur-sm border-b border-white/5">
<div class="hidden md:flex gap-12">
<a href="/"
class="text-xs font-bold uppercase tracking-widest text-slate-500 hover:text-white transition-colors">01.
Home</a>
<a href="/blog"
class="text-xs font-bold uppercase tracking-widest text-slate-500 hover:text-white transition-colors">02.
Blog</a>
</div>
<nav class="fixed top-0 left-0 w-full z-50 px-6 lg:px-12 py-6 lg:py-8 flex justify-between items-center backdrop-blur-md bg-brand-dark/80 border-b border-white/5">
<!-- Left side - can be empty or have subtle branding -->
<div class="hidden md:block">
<span class="text-[10px] font-mono text-slate-600 tracking-widest uppercase">NV / 2026</span>
</div>
<a href="/contact"
class="border border-slate-600 px-6 py-3 text-xs font-bold uppercase tracking-widest hover:border-brand-accent hover:bg-brand-accent/10 transition-all cursor-none-target">
Let's Talk
</a>
<!-- Right side navigation -->
<div class="flex items-center gap-8 lg:gap-12 ml-auto">
<div class="hidden md:flex items-center gap-10 lg:gap-12">
<a href="/"
class="relative text-xs font-semibold uppercase tracking-[0.15em] text-slate-500 hover:text-white transition-all duration-300 py-2 group">
<span class="relative z-10">Home</span>
<span class="absolute bottom-0 left-0 w-0 h-[1px] bg-brand-accent transition-all duration-300 ease-out group-hover:w-full"></span>
</a>
<a href="/blog"
class="relative text-xs font-semibold uppercase tracking-[0.15em] text-slate-500 hover:text-white transition-all duration-300 py-2 group">
<span class="relative z-10">Blog</span>
<span class="absolute bottom-0 left-0 w-0 h-[1px] bg-brand-accent transition-all duration-300 ease-out group-hover:w-full"></span>
</a>
</div>
<a href="/contact"
class="border border-slate-600 px-5 lg:px-6 py-2.5 lg:py-3 text-xs font-bold uppercase tracking-[0.15em] text-white hover:border-brand-accent hover:bg-brand-accent hover:text-brand-dark transition-all duration-300">
Let's Talk
</a>
</div>
<!-- Mobile menu button (optional, for future) -->
<button class="md:hidden p-2 text-slate-400 hover:text-white transition-colors" aria-label="Menu">
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"></path>
</svg>
</button>
</nav>

View File

@ -1,50 +1,46 @@
---
---
<section id="experience" class="container mx-auto px-6 lg:px-12 py-24">
<div class="grid grid-cols-1 lg:grid-cols-12 gap-12">
<div class="lg:col-span-4">
<h2 class="text-4xl font-bold uppercase tracking-tight mb-2 text-stroke">Experience</h2>
<h2 class="text-4xl font-bold uppercase tracking-tight mb-8">History</h2>
<p class="text-slate-400 mb-8 max-w-sm">
<section id="experience" class="container mx-auto px-6 lg:px-12 py-32">
<div class="grid grid-cols-1 lg:grid-cols-12 gap-12 lg:gap-16">
<div class="lg:col-span-4 animate-on-scroll slide-right">
<h2 class="text-3xl md:text-4xl font-bold uppercase tracking-tight mb-2 text-stroke">Experience</h2>
<h2 class="text-3xl md:text-4xl font-bold uppercase tracking-tight mb-10">History</h2>
<p class="text-slate-400 text-base leading-relaxed mb-10 max-w-sm font-light">
From founding my own VFX house to supervising global campaigns. I bridge the gap between
creative vision and technical execution.
</p>
<a href="https://biohazardvfx.com" target="_blank"
class="inline-flex items-center gap-2 text-xs font-mono uppercase text-brand-accent hover:underline">
Visit Biohazard VFX <i data-lucide="arrow-up-right" class="w-4 h-4"></i>
class="inline-flex items-center gap-3 text-xs font-mono uppercase text-brand-accent hover:text-white transition-colors duration-300 group">
Visit Biohazard VFX
<i data-lucide="arrow-up-right" class="w-4 h-4 transition-transform duration-300 group-hover:translate-x-0.5 group-hover:-translate-y-0.5"></i>
</a>
</div>
<div class="lg:col-span-8 relative">
<!-- Vertical line -->
<div
class="absolute left-0 top-0 bottom-0 w-[1px] bg-gradient-to-b from-brand-accent via-slate-800 to-transparent">
</div>
<div class="absolute left-0 top-0 bottom-0 w-[1px] bg-gradient-to-b from-brand-accent via-slate-700/50 to-transparent"></div>
<!-- Item 1 -->
<div class="pl-12 mb-20 relative reveal-text">
<div
class="absolute left-[-5px] top-2 w-2.5 h-2.5 bg-brand-dark border border-brand-accent rounded-full">
<div class="pl-10 lg:pl-14 mb-20 relative animate-on-scroll slide-up stagger-1">
<div class="absolute left-[-5px] top-2 w-3 h-3 bg-brand-dark border-2 border-brand-accent rounded-full"></div>
<div class="flex flex-col md:flex-row md:items-baseline gap-3 md:gap-4 mb-5">
<h3 class="text-xl md:text-2xl font-bold text-white uppercase tracking-tight">Biohazard VFX</h3>
<span class="font-mono text-[10px] text-brand-accent bg-brand-accent/10 px-3 py-1.5 tracking-wide">FOUNDER / VFX SUPERVISOR</span>
<span class="font-mono text-xs text-slate-500 md:ml-auto">MAR 2022 — OCT 2025</span>
</div>
<div class="flex flex-col md:flex-row md:items-baseline gap-4 mb-4">
<h3 class="text-2xl font-bold text-white uppercase">Biohazard VFX</h3>
<span class="font-mono text-xs text-brand-accent bg-brand-accent/10 px-2 py-1">FOUNDER / VFX
SUPERVISOR</span>
<span class="font-mono text-xs text-slate-500 ml-auto">MAR 2022 - OCT 2025</span>
</div>
<p class="text-slate-400 mb-6 leading-relaxed">
<p class="text-slate-400 mb-8 leading-relaxed font-light">
Founded and led a VFX studio specializing in high-end commercial and music video work for
Post Malone, ENHYPEN, and Nike. Architected a custom pipeline combining cloud and
self-hosted infrastructure.
</p>
<ul class="space-y-2 mb-6">
<li class="flex items-start gap-3 text-sm text-slate-300">
<span class="text-brand-accent mt-1">▹</span>
<ul class="space-y-3">
<li class="flex items-start gap-4 text-sm text-slate-300 font-light">
<span class="text-brand-accent mt-0.5 text-xs">▹</span>
Designed 7-plate reconciliation workflows for ENHYPEN (projection mapping live action
onto CAD).
</li>
<li class="flex items-start gap-3 text-sm text-slate-300">
<span class="text-brand-accent mt-1">▹</span>
<li class="flex items-start gap-4 text-sm text-slate-300 font-light">
<span class="text-brand-accent mt-0.5 text-xs">▹</span>
Developed QA systems for AI-generated assets, transforming mid-tier output into
production-ready deliverables.
</li>
@ -52,43 +48,42 @@
</div>
<!-- Item 2 -->
<div class="pl-12 mb-20 relative reveal-text">
<div class="absolute left-[-5px] top-2 w-2.5 h-2.5 bg-slate-700 rounded-full"></div>
<div class="flex flex-col md:flex-row md:items-baseline gap-4 mb-4">
<h3 class="text-2xl font-bold text-white uppercase">Stinkfilms</h3>
<span class="font-mono text-xs text-slate-400 border border-slate-700 px-2 py-1">GLOBAL
PRODUCTION STUDIO</span>
<span class="font-mono text-xs text-slate-500 ml-auto">SUMMER 2024</span>
<div class="pl-10 lg:pl-14 mb-20 relative animate-on-scroll slide-up stagger-2">
<div class="absolute left-[-5px] top-2 w-3 h-3 bg-slate-700 rounded-full transition-colors duration-300"></div>
<div class="flex flex-col md:flex-row md:items-baseline gap-3 md:gap-4 mb-5">
<h3 class="text-xl md:text-2xl font-bold text-white uppercase tracking-tight">Stinkfilms</h3>
<span class="font-mono text-[10px] text-slate-400 border border-slate-700 px-3 py-1.5 tracking-wide">GLOBAL PRODUCTION STUDIO</span>
<span class="font-mono text-xs text-slate-500 md:ml-auto">SUMMER 2024</span>
</div>
<p class="text-slate-400 mb-6 leading-relaxed">
<p class="text-slate-400 mb-8 leading-relaxed font-light">
Led Biohazard VFX team (60+ artists) alongside director Felix Brady to create a brand film
for G-Star Raw.
</p>
<div
class="border border-white/5 bg-white/5 p-6 backdrop-blur-sm hover:border-brand-accent/50 transition-colors cursor-pointer group">
<h4 class="text-sm font-bold uppercase text-white mb-2 flex justify-between">
<div class="border border-white/10 bg-white/[0.02] p-6 lg:p-8 backdrop-blur-sm hover:border-brand-accent/30 transition-all duration-500 cursor-pointer group">
<h4 class="text-sm font-bold uppercase text-white mb-3 flex justify-between items-center tracking-wide">
Project: G-Star Raw Olympics Campaign
<i data-lucide="arrow-right"
class="w-4 h-4 opacity-0 group-hover:opacity-100 transition-opacity text-brand-accent"></i>
class="w-4 h-4 opacity-0 group-hover:opacity-100 transition-all duration-300 text-brand-accent transform group-hover:translate-x-1"></i>
</h4>
<p class="text-xs text-slate-400 mb-4">Managed full CG environments in Blender/Houdini and
integrated AI/ML workflows (Stable Diffusion reference gen, Copycat cleanup).</p>
<p class="text-sm text-slate-400 mb-5 leading-relaxed font-light">
Managed full CG environments in Blender/Houdini and integrated AI/ML workflows (Stable Diffusion reference gen, Copycat cleanup).
</p>
<a href="https://stinkfilms.com"
class="text-[10px] font-bold text-brand-accent uppercase tracking-widest">View Case
Study</a>
class="text-[10px] font-bold text-brand-accent uppercase tracking-widest hover:text-white transition-colors duration-300">
View Case Study
</a>
</div>
</div>
<!-- Item 3 -->
<div class="pl-12 relative reveal-text">
<div class="absolute left-[-5px] top-2 w-2.5 h-2.5 bg-slate-700 rounded-full"></div>
<div class="flex flex-col md:flex-row md:items-baseline gap-4 mb-4">
<h3 class="text-2xl font-bold text-white uppercase">Freelance</h3>
<span class="font-mono text-xs text-slate-400 border border-slate-700 px-2 py-1">2D/3D
ARTIST</span>
<span class="font-mono text-xs text-slate-500 ml-auto">2015 - PRESENT</span>
<div class="pl-10 lg:pl-14 relative animate-on-scroll slide-up stagger-3">
<div class="absolute left-[-5px] top-2 w-3 h-3 bg-slate-700 rounded-full"></div>
<div class="flex flex-col md:flex-row md:items-baseline gap-3 md:gap-4 mb-5">
<h3 class="text-xl md:text-2xl font-bold text-white uppercase tracking-tight">Freelance</h3>
<span class="font-mono text-[10px] text-slate-400 border border-slate-700 px-3 py-1.5 tracking-wide">2D/3D ARTIST</span>
<span class="font-mono text-xs text-slate-500 md:ml-auto">2015 — PRESENT</span>
</div>
<p class="text-slate-400 mb-4 leading-relaxed">
<p class="text-slate-400 leading-relaxed font-light">
Compositor for Abyss Digital and major labels (Atlantic, Interscope). Clients: David
Kushner, Opium, Lil Durk, Don Toliver.
</p>
@ -96,4 +91,3 @@
</div>
</div>
</section>

View File

@ -1,55 +1,47 @@
---
---
<section id="work" class="py-24">
<div class="container mx-auto px-6 lg:px-12 mb-12">
<span class="text-xs font-mono text-brand-accent mb-2 block">/// HIGHLIGHT</span>
<h2 class="text-5xl md:text-7xl font-bold uppercase text-white mb-4">G-Star Raw <span
class="text-stroke">Olympics</span></h2>
<section id="work" class="py-32">
<div class="container mx-auto px-6 lg:px-12 mb-14 animate-on-scroll slide-up">
<span class="text-xs font-mono text-brand-accent mb-4 block tracking-wide">/// HIGHLIGHT</span>
<h2 class="text-4xl md:text-6xl lg:text-7xl font-bold uppercase text-white tracking-tight">
G-Star Raw <span class="text-stroke">Olympics</span>
</h2>
</div>
<!-- Full Width Project Card -->
<div class="w-full h-[80vh] relative group overflow-hidden border-y border-white/10">
<div class="w-full h-[75vh] lg:h-[80vh] relative group overflow-hidden border-y border-white/10 animate-on-scroll scale-in">
<!-- Abstract Background representing the project -->
<div
class="absolute inset-0 bg-[url('https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?q=80&w=2564&auto=format&fit=crop')] bg-cover bg-center transition-transform duration-1000 group-hover:scale-105">
</div>
<div class="absolute inset-0 bg-brand-dark/80 mix-blend-multiply"></div>
<div class="absolute inset-0 bg-gradient-to-t from-brand-dark via-brand-dark/20 to-transparent"></div>
<div class="absolute inset-0 bg-[url('https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?q=80&w=2564&auto=format&fit=crop')] bg-cover bg-center transition-transform duration-[1.5s] ease-out group-hover:scale-105"></div>
<div class="absolute inset-0 bg-brand-dark/75 mix-blend-multiply transition-colors duration-700 group-hover:bg-brand-dark/60"></div>
<div class="absolute inset-0 bg-gradient-to-t from-brand-dark via-brand-dark/30 to-transparent opacity-95"></div>
<!-- Grid Overlay on image -->
<div
class="absolute inset-0 bg-[url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDAiIGhlaWdodD0iNDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PHBhdHRlcm4gaWQ9ImEiIHdpZHRoPSI0MCIgaGVpZ2h0PSI0MCIgcGF0dGVyblVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+PHBhdHRlcm4gaWQ9ImIiIHdpZHRoPSI0MCIgaGVpZ2h0PSI0MCIgcGF0dGVyblVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+PGNpcmNsZSBjeD0iMiIgY3k9IjIiIHI9IjEiIGZpbGw9InJnYmEoMjU1LDI1NSwyNTUsMC4xKSIvPjwvcGF0dGVybj48cmVjdCB3aWR0aD0iNDAiIGhlaWdodD0iNDAiIGZpbGw9InVybCgjYikiLz48L3BhdHRlcm4+PC9kZWZzPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjYSkiLz48L3N2Zz4=')] opacity-30">
</div>
<div class="absolute inset-0 bg-[url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDAiIGhlaWdodD0iNDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PHBhdHRlcm4gaWQ9ImEiIHdpZHRoPSI0MCIgaGVpZ2h0PSI0MCIgcGF0dGVyblVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+PHBhdHRlcm4gaWQ9ImIiIHdpZHRoPSI0MCIgaGVpZ2h0PSI0MCIgcGF0dGVyblVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+PGNpcmNsZSBjeD0iMiIgY3k9IjIiIHI9IjEiIGZpbGw9InJnYmEoMjU1LDI1NSwyNTUsMC4xKSIvPjwvcGF0dGVybj48cmVjdCB3aWR0aD0iNDAiIGhlaWdodD0iNDAiIGZpbGw9InVybCgjYikiLz48L3BhdHRlcm4+PC9kZWZzPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjYSkiLz48L3N2Zz4=')] opacity-20"></div>
<div
class="absolute bottom-0 left-0 w-full p-6 lg:p-12 flex flex-col md:flex-row items-end justify-between">
<div
class="max-w-2xl transform translate-y-8 group-hover:translate-y-0 transition-transform duration-500">
<div class="flex gap-2 mb-4">
<span class="bg-brand-accent text-brand-dark text-[10px] font-bold uppercase px-2 py-1">VFX
Supervision</span>
<span
class="border border-white/30 text-white text-[10px] font-bold uppercase px-2 py-1">AI/ML</span>
<span
class="border border-white/30 text-white text-[10px] font-bold uppercase px-2 py-1">Houdini</span>
<div class="absolute bottom-0 left-0 w-full p-6 lg:p-14 flex flex-col md:flex-row items-end justify-between gap-8">
<div class="max-w-2xl transform translate-y-6 group-hover:translate-y-0 transition-transform duration-700 ease-out">
<div class="flex flex-wrap gap-2 mb-6">
<span class="bg-brand-accent text-brand-dark text-[10px] font-bold uppercase px-3 py-1.5 tracking-wide">VFX Supervision</span>
<span class="border border-white/30 text-white text-[10px] font-bold uppercase px-3 py-1.5 tracking-wide transition-colors duration-300 hover:border-white/50">AI/ML</span>
<span class="border border-white/30 text-white text-[10px] font-bold uppercase px-3 py-1.5 tracking-wide transition-colors duration-300 hover:border-white/50">Houdini</span>
</div>
<p class="text-xl md:text-2xl text-white font-medium mb-6">
<p class="text-lg md:text-xl lg:text-2xl text-white font-normal mb-8 leading-relaxed">
Managed full CG environment builds, procedural city generation, and integrated AI-generated
normal maps for relighting in Nuke.
</p>
<a href="https://f.io/7ijf23Wm"
class="inline-flex items-center gap-3 text-sm font-bold uppercase tracking-widest text-white hover:text-brand-accent transition-colors">
Watch Making Of <i data-lucide="play-circle" class="w-5 h-5"></i>
class="inline-flex items-center gap-4 text-xs font-bold uppercase tracking-widest text-white hover:text-brand-accent transition-all duration-300 group/link">
Watch Making Of
<i data-lucide="play-circle" class="w-5 h-5 transition-transform duration-300 group-hover/link:scale-110"></i>
</a>
</div>
<div class="hidden md:block text-right">
<span class="block text-[10px] uppercase text-slate-500 tracking-widest mb-1">Year</span>
<span class="block text-2xl font-bold text-white mb-4">2024</span>
<span class="block text-[10px] uppercase text-slate-500 tracking-widest mb-1">Client</span>
<span class="block text-xl font-bold text-white">Stinkfilms</span>
<div class="hidden md:block text-right opacity-80 group-hover:opacity-100 transition-opacity duration-500">
<span class="block text-[10px] uppercase text-slate-500 tracking-widest mb-2">Year</span>
<span class="block text-2xl font-bold text-white mb-6 tracking-tight">2024</span>
<span class="block text-[10px] uppercase text-slate-500 tracking-widest mb-2">Client</span>
<span class="block text-xl font-bold text-white tracking-tight">Stinkfilms</span>
</div>
</div>
</div>
</section>

View File

@ -1,30 +1,26 @@
---
---
<section id="about" class="container mx-auto px-6 lg:px-12 min-h-[70vh] flex flex-col justify-center relative">
<div class="grid grid-cols-1 md:grid-cols-12 gap-6">
<section id="about" class="container mx-auto px-6 lg:px-12 min-h-[80vh] flex flex-col justify-center relative pb-24">
<div class="grid grid-cols-1 md:grid-cols-12 gap-8 lg:gap-12">
<div class="col-span-12">
<p class="font-mono text-brand-accent mb-4 ml-1 reveal-text">/// TECHNICAL GENERALIST & VFX
SUPERVISOR</p>
<h1
class="text-6xl md:text-8xl lg:text-[10rem] font-bold text-massive uppercase leading-none tracking-tighter mb-8 text-white">
<span class="reveal-text block delay-100">Visual</span>
<span
class="reveal-text block delay-200 text-transparent bg-clip-text bg-gradient-to-tr from-brand-accent to-white">Alchemist</span>
<p class="font-mono text-brand-accent text-sm mb-6 tracking-wide animate-on-scroll fade-in">
/// TECHNICAL GENERALIST & VFX SUPERVISOR
</p>
<h1 class="text-5xl sm:text-6xl md:text-7xl lg:text-8xl xl:text-[9rem] font-extrabold text-massive uppercase leading-none tracking-tighter mb-10 text-white">
<span class="animate-on-scroll slide-up block stagger-1">Visual</span>
<span class="animate-on-scroll slide-up block stagger-2 text-transparent bg-clip-text bg-gradient-to-r from-brand-accent via-orange-400 to-white">Alchemist</span>
</h1>
</div>
<div
class="col-span-12 md:col-span-6 lg:col-span-5 lg:col-start-8 mt-12 border-l border-brand-accent/30 pl-8 reveal-text delay-300">
<p class="text-slate-400 text-lg leading-relaxed mb-8">
<div class="col-span-12 md:col-span-7 lg:col-span-5 lg:col-start-8 mt-8 lg:mt-4 border-l-2 border-brand-accent/40 pl-8 animate-on-scroll slide-left stagger-3">
<p class="text-slate-400 text-base lg:text-lg leading-relaxed mb-10 font-light">
I am a problem solver who loves visual effects. With 10 years of experience creating end-to-end
visual content for clients like <span class="text-white font-semibold">Post Malone</span>, <span
class="text-white font-semibold">Stinkfilms</span>, and <span
class="text-white font-semibold">Adidas</span>. Comfortable managing teams while staying
visual content for clients like <span class="text-white font-medium">Post Malone</span>, <span class="text-white font-medium">Stinkfilms</span>, and <span class="text-white font-medium">Adidas</span>. Comfortable managing teams while staying
knee-deep in hands-on shot work.
</p>
<div class="flex gap-4">
<div class="flex gap-6">
<a href="#work"
class="group flex items-center gap-3 text-xs font-bold uppercase tracking-widest text-white hover:text-brand-accent transition-colors">
<span class="w-8 h-[1px] bg-brand-accent group-hover:w-12 transition-all"></span>
class="group flex items-center gap-4 text-xs font-bold uppercase tracking-widest text-white hover:text-brand-accent transition-all duration-300">
<span class="w-10 h-[2px] bg-brand-accent group-hover:w-16 transition-all duration-500 ease-out"></span>
View Selected Works
</a>
</div>
@ -32,15 +28,18 @@
</div>
<!-- Hero Footer -->
<div
class="absolute bottom-0 w-full left-0 px-6 lg:px-12 pb-12 hidden md:flex justify-between items-end opacity-50">
<div class="font-mono text-xs text-slate-500">
LOC: COLORADO SPRINGS<br>
TIME: <span id="clock">00:00:00</span>
<div class="absolute bottom-8 w-full left-0 px-6 lg:px-12 hidden md:flex justify-between items-end opacity-60 animate-on-scroll fade-in stagger-5">
<div class="font-mono text-xs text-slate-500 tracking-wide">
<span class="block text-slate-600 mb-1">LOCATION</span>
COLORADO SPRINGS, CO<br>
<span id="clock" class="text-slate-400">00:00:00</span>
</div>
<div class="font-mono text-xs text-slate-500 text-right">
SCROLL<br>
<div class="font-mono text-xs text-slate-500 text-right tracking-wide">
<span class="block text-slate-600 mb-1">EXPLORE</span>
<span class="inline-flex flex-col items-center">
SCROLL
<span class="block mt-2 w-[1px] h-6 bg-gradient-to-b from-slate-500 to-transparent"></span>
</span>
</div>
</div>
</section>
@ -57,4 +56,3 @@
setInterval(updateClock, 1000);
updateClock();
</script>

View File

@ -1,16 +1,17 @@
---
---
<section id="skills" class="container mx-auto px-6 lg:px-12 py-24 bg-brand-panel border-y border-white/5">
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-12">
<div class="col-span-1 md:col-span-2 lg:col-span-4 mb-8">
<h2 class="text-4xl font-bold uppercase mb-2">Technical Arsenal</h2>
<p class="text-slate-400 font-mono text-sm">/// SOFTWARE & LANGUAGES</p>
<section id="skills" class="container mx-auto px-6 lg:px-12 py-32 bg-brand-panel border-y border-white/5">
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-10 lg:gap-12">
<div class="col-span-1 md:col-span-2 lg:col-span-4 mb-6 animate-on-scroll slide-up">
<h2 class="text-3xl md:text-4xl font-bold uppercase mb-3 tracking-tight">Technical Arsenal</h2>
<p class="text-slate-500 font-mono text-sm tracking-wide">/// SOFTWARE & LANGUAGES</p>
</div>
<!-- Compositing -->
<div>
<h3 class="text-lg font-bold text-white uppercase mb-6 flex items-center gap-2">
<i data-lucide="layers" class="w-4 h-4 text-brand-accent"></i> Compositing
<div class="animate-on-scroll slide-up stagger-1">
<h3 class="text-base font-bold text-white uppercase mb-6 flex items-center gap-3 tracking-wide">
<i data-lucide="layers" class="w-4 h-4 text-brand-accent"></i>
Compositing
</h3>
<div class="flex flex-wrap gap-2">
<span class="skill-tag">Nuke/NukeX</span>
@ -23,9 +24,10 @@
</div>
<!-- 3D -->
<div>
<h3 class="text-lg font-bold text-white uppercase mb-6 flex items-center gap-2">
<i data-lucide="box" class="w-4 h-4 text-brand-accent"></i> 3D Generalist
<div class="animate-on-scroll slide-up stagger-2">
<h3 class="text-base font-bold text-white uppercase mb-6 flex items-center gap-3 tracking-wide">
<i data-lucide="box" class="w-4 h-4 text-brand-accent"></i>
3D Generalist
</h3>
<div class="flex flex-wrap gap-2">
<span class="skill-tag">Houdini</span>
@ -40,13 +42,13 @@
</div>
<!-- AI/ML -->
<div>
<h3 class="text-lg font-bold text-white uppercase mb-6 flex items-center gap-2">
<i data-lucide="cpu" class="w-4 h-4 text-brand-accent"></i> AI/ML Integration
<div class="animate-on-scroll slide-up stagger-3">
<h3 class="text-base font-bold text-white uppercase mb-6 flex items-center gap-3 tracking-wide">
<i data-lucide="cpu" class="w-4 h-4 text-brand-accent"></i>
AI/ML Integration
</h3>
<div class="flex flex-wrap gap-2">
<span class="skill-tag bg-brand-accent/10 border-brand-accent/50 text-brand-accent">Stable
Diffusion</span>
<span class="skill-tag bg-brand-accent/10 border-brand-accent/40 text-brand-accent hover:bg-brand-accent/20">Stable Diffusion</span>
<span class="skill-tag">LoRA Training</span>
<span class="skill-tag">Dataset Prep</span>
<span class="skill-tag">Synthetic Data</span>
@ -55,9 +57,10 @@
</div>
<!-- Dev -->
<div>
<h3 class="text-lg font-bold text-white uppercase mb-6 flex items-center gap-2">
<i data-lucide="code" class="w-4 h-4 text-brand-accent"></i> Development
<div class="animate-on-scroll slide-up stagger-4">
<h3 class="text-base font-bold text-white uppercase mb-6 flex items-center gap-3 tracking-wide">
<i data-lucide="code" class="w-4 h-4 text-brand-accent"></i>
Development
</h3>
<div class="flex flex-wrap gap-2">
<span class="skill-tag">Python</span>
@ -70,4 +73,3 @@
</div>
</div>
</section>

View File

@ -38,23 +38,54 @@ const { title = SITE_TITLE, description = SITE_DESCRIPTION } = Astro.props;
window.lucide.createIcons();
}
// Intersection Observer for Reveal Animations
const observerOptions = {
threshold: 0.1,
rootMargin: "0px"
};
// ===== SCROLL ANIMATION SYSTEM =====
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('active');
}
});
}, observerOptions);
// Observer for scroll-triggered animations
const scrollObserverOptions = {
threshold: 0.15,
rootMargin: "0px 0px -50px 0px"
};
document.querySelectorAll('.reveal-text').forEach(el => {
observer.observe(el);
const scrollObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('is-visible');
// Optionally unobserve after animation
// scrollObserver.unobserve(entry.target);
}
});
}, scrollObserverOptions);
// Observe all animate-on-scroll elements
document.querySelectorAll('.animate-on-scroll').forEach(el => {
scrollObserver.observe(el);
});
// Observer for legacy reveal-text animations
const revealObserverOptions = {
threshold: 0.1,
rootMargin: "0px"
};
const revealObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('active');
}
});
}, revealObserverOptions);
document.querySelectorAll('.reveal-text').forEach(el => {
revealObserver.observe(el);
});
// Auto-stagger children in containers with .stagger-children class
document.querySelectorAll('.stagger-children').forEach(container => {
const children = container.querySelectorAll('.animate-on-scroll');
children.forEach((child, index) => {
child.classList.add(`stagger-${Math.min(index + 1, 8)}`);
});
});
</script>
</body>
</html>

View File

@ -12,41 +12,43 @@ const posts = (await getCollection('blog')).sort(
<BaseLayout title={SITE_TITLE} description={SITE_DESCRIPTION}>
<section class="container mx-auto px-6 lg:px-12">
<div class="mb-16">
<h1 class="text-6xl md:text-8xl font-bold uppercase text-white mb-4 tracking-tighter">Blog</h1>
<p class="text-slate-400 font-mono">/// THOUGHTS & PROCESS</p>
<div class="mb-20 animate-on-scroll slide-up">
<h1 class="text-5xl md:text-7xl lg:text-8xl font-bold uppercase text-white mb-5 tracking-tighter">Blog</h1>
<p class="text-slate-500 font-mono text-sm tracking-wide">/// THOUGHTS & PROCESS</p>
</div>
<ul class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-x-8 gap-y-16">
<ul class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-x-8 lg:gap-x-10 gap-y-16 lg:gap-y-20 stagger-children">
{
posts.map((post) => (
<li class="group">
posts.map((post, index) => (
<li class={`group animate-on-scroll slide-up stagger-${Math.min(index + 1, 6)}`}>
<a href={`/blog/${post.id}/`} class="block">
<div class="relative aspect-[16/9] mb-6 overflow-hidden border border-white/10 group-hover:border-brand-accent/50 transition-colors">
<div class="relative aspect-[16/9] mb-6 overflow-hidden border border-white/10 group-hover:border-brand-accent/40 transition-all duration-500">
{post.data.heroImage && (
<Image
width={720}
height={360}
src={post.data.heroImage}
alt=""
class="w-full h-full object-cover transition-transform duration-700 group-hover:scale-105"
class="w-full h-full object-cover transition-transform duration-[1s] ease-out group-hover:scale-105"
/>
)}
<div class="absolute inset-0 bg-brand-dark/20 group-hover:bg-transparent transition-colors"></div>
<div class="absolute inset-0 bg-brand-dark/30 group-hover:bg-brand-dark/10 transition-colors duration-500"></div>
<div class="absolute inset-0 bg-gradient-to-t from-brand-dark/50 to-transparent opacity-60"></div>
</div>
<div class="flex flex-col">
<div class="flex items-center gap-2 mb-3">
<span class="text-xs font-mono text-brand-accent uppercase tracking-widest">
<div class="flex items-center gap-2 mb-4">
<span class="text-[10px] font-mono text-brand-accent uppercase tracking-widest">
<FormattedDate date={post.data.pubDate} />
</span>
</div>
<h4 class="text-2xl font-bold text-white uppercase mb-2 group-hover:text-brand-accent transition-colors leading-tight">
<h4 class="text-xl lg:text-2xl font-bold text-white uppercase mb-3 group-hover:text-brand-accent transition-colors duration-300 leading-tight tracking-tight">
{post.data.title}
</h4>
<p class="text-slate-400 line-clamp-2">
{/* We could add a description field to blog posts or just show title */}
<p class="text-slate-400 text-sm line-clamp-2 font-light leading-relaxed">
{post.data.description || ''}
</p>
<span class="mt-4 text-xs font-bold uppercase tracking-widest text-slate-500 group-hover:text-white transition-colors flex items-center gap-2">
Read Article <span class="block w-4 h-[1px] bg-slate-500 group-hover:bg-brand-accent transition-colors"></span>
<span class="mt-6 text-xs font-bold uppercase tracking-widest text-slate-500 group-hover:text-white transition-all duration-300 flex items-center gap-3">
Read Article
<span class="block w-6 h-[1px] bg-slate-600 group-hover:bg-brand-accent group-hover:w-10 transition-all duration-300"></span>
</span>
</div>
</a>

View File

@ -5,48 +5,48 @@ import { SITE_TITLE, SITE_DESCRIPTION } from '../consts';
<BaseLayout title={`Contact | ${SITE_TITLE}`} description="Get in touch for collaboration or inquiries.">
<section class="container mx-auto px-6 lg:px-12">
<div class="mb-16">
<h1 class="text-6xl md:text-8xl font-bold uppercase text-white mb-4 tracking-tighter">
Let's <span class="text-transparent bg-clip-text bg-gradient-to-tr from-brand-accent to-white">Talk</span>
<div class="mb-20 animate-on-scroll slide-up">
<h1 class="text-5xl md:text-7xl lg:text-8xl font-bold uppercase text-white mb-5 tracking-tighter">
Let's <span class="text-transparent bg-clip-text bg-gradient-to-r from-brand-accent via-orange-400 to-white">Talk</span>
</h1>
<p class="text-slate-400 font-mono">/// GET IN TOUCH</p>
<p class="text-slate-500 font-mono text-sm tracking-wide">/// GET IN TOUCH</p>
</div>
<div class="grid grid-cols-1 lg:grid-cols-12 gap-12 lg:gap-24">
<div class="grid grid-cols-1 lg:grid-cols-12 gap-12 lg:gap-20">
<!-- Contact Form -->
<div class="lg:col-span-8">
<form class="space-y-6" action="#" method="POST">
<div class="lg:col-span-7 animate-on-scroll slide-up stagger-1">
<form class="space-y-8" action="#" method="POST">
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div class="space-y-2">
<label for="name" class="text-xs font-bold uppercase tracking-widest text-slate-500">Name</label>
<div class="space-y-3">
<label for="name" class="text-xs font-bold uppercase tracking-widest text-slate-500 block">Name</label>
<input
type="text"
id="name"
name="name"
placeholder="Your Name"
class="w-full bg-white/5 border border-slate-700 text-white px-4 py-4 focus:border-brand-accent focus:outline-none transition-colors placeholder:text-slate-600"
class="w-full bg-white/[0.03] border border-slate-700 text-white px-5 py-4 focus:border-brand-accent focus:bg-white/[0.05] focus:outline-none transition-all duration-300 placeholder:text-slate-600"
required
/>
</div>
<div class="space-y-2">
<label for="email" class="text-xs font-bold uppercase tracking-widest text-slate-500">Email</label>
<div class="space-y-3">
<label for="email" class="text-xs font-bold uppercase tracking-widest text-slate-500 block">Email</label>
<input
type="email"
id="email"
name="email"
placeholder="name@example.com"
class="w-full bg-white/5 border border-slate-700 text-white px-4 py-4 focus:border-brand-accent focus:outline-none transition-colors placeholder:text-slate-600"
class="w-full bg-white/[0.03] border border-slate-700 text-white px-5 py-4 focus:border-brand-accent focus:bg-white/[0.05] focus:outline-none transition-all duration-300 placeholder:text-slate-600"
required
/>
</div>
</div>
<div class="space-y-2">
<label for="subject" class="text-xs font-bold uppercase tracking-widest text-slate-500">Subject</label>
<div class="space-y-3">
<label for="subject" class="text-xs font-bold uppercase tracking-widest text-slate-500 block">Subject</label>
<select
id="subject"
name="subject"
class="w-full bg-white/5 border border-slate-700 text-white px-4 py-4 focus:border-brand-accent focus:outline-none transition-colors appearance-none"
class="w-full bg-white/[0.03] border border-slate-700 text-white px-5 py-4 focus:border-brand-accent focus:bg-white/[0.05] focus:outline-none transition-all duration-300 appearance-none cursor-pointer"
>
<option value="general" class="bg-brand-dark">General Inquiry</option>
<option value="project" class="bg-brand-dark">Project Collaboration</option>
@ -55,39 +55,39 @@ import { SITE_TITLE, SITE_DESCRIPTION } from '../consts';
</select>
</div>
<div class="space-y-2">
<label for="message" class="text-xs font-bold uppercase tracking-widest text-slate-500">Message</label>
<div class="space-y-3">
<label for="message" class="text-xs font-bold uppercase tracking-widest text-slate-500 block">Message</label>
<textarea
id="message"
name="message"
rows="6"
placeholder="Tell me about your project..."
class="w-full bg-white/5 border border-slate-700 text-white px-4 py-4 focus:border-brand-accent focus:outline-none transition-colors placeholder:text-slate-600 resize-none"
class="w-full bg-white/[0.03] border border-slate-700 text-white px-5 py-4 focus:border-brand-accent focus:bg-white/[0.05] focus:outline-none transition-all duration-300 placeholder:text-slate-600 resize-none"
required
></textarea>
</div>
<div class="pt-4">
<div class="pt-6">
<button type="submit" class="btn-primary group relative overflow-hidden">
<span class="relative z-10">Send Message</span>
<div class="absolute inset-0 bg-white opacity-0 group-hover:opacity-20 transition-opacity"></div>
<div class="absolute inset-0 bg-white opacity-0 group-hover:opacity-20 transition-opacity duration-300"></div>
</button>
</div>
</form>
</div>
<!-- Sidebar Info -->
<div class="lg:col-span-4 space-y-12">
<div class="lg:col-span-5 space-y-12 animate-on-scroll slide-left stagger-2">
<div>
<h3 class="text-xs font-bold uppercase tracking-widest text-slate-500 mb-6">Contact Info</h3>
<ul class="space-y-4">
<li>
<a href="mailto:nicholai@nicholai.work" class="text-xl text-white hover:text-brand-accent transition-colors font-mono block">
<a href="mailto:nicholai@nicholai.work" class="text-lg lg:text-xl text-white hover:text-brand-accent transition-colors duration-300 font-mono block">
nicholai@nicholai.work
</a>
</li>
<li>
<a href="tel:7196604281" class="text-xl text-white hover:text-brand-accent transition-colors font-mono block">
<a href="tel:7196604281" class="text-lg lg:text-xl text-white hover:text-brand-accent transition-colors duration-300 font-mono block">
719 660 4281
</a>
</li>
@ -96,22 +96,22 @@ import { SITE_TITLE, SITE_DESCRIPTION } from '../consts';
<div>
<h3 class="text-xs font-bold uppercase tracking-widest text-slate-500 mb-6">Location</h3>
<p class="text-lg text-slate-300">
<p class="text-base lg:text-lg text-slate-300 leading-relaxed font-light">
Colorado Springs, CO<br/>
Mountain Standard Time (MST)
</p>
</div>
<div class="pt-8 border-t border-white/10">
<div class="pt-10 border-t border-white/10">
<h3 class="text-xs font-bold uppercase tracking-widest text-slate-500 mb-6">Availability</h3>
<div class="flex items-center gap-3">
<span class="relative flex h-3 w-3">
<div class="flex items-center gap-3 mb-4">
<span class="relative flex h-2.5 w-2.5">
<span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-brand-accent opacity-75"></span>
<span class="relative inline-flex rounded-full h-3 w-3 bg-brand-accent"></span>
<span class="relative inline-flex rounded-full h-2.5 w-2.5 bg-brand-accent"></span>
</span>
<span class="text-sm font-bold text-brand-accent uppercase tracking-wide">Open to opportunities</span>
</div>
<p class="mt-4 text-slate-400 text-sm leading-relaxed">
<p class="text-slate-400 text-sm leading-relaxed font-light">
Currently accepting new projects for Q3 2026. Reach out to schedule a discovery call.
</p>
</div>
@ -119,4 +119,3 @@ import { SITE_TITLE, SITE_DESCRIPTION } from '../consts';
</div>
</section>
</BaseLayout>

View File

@ -8,11 +8,19 @@ import Skills from '../components/sections/Skills.astro';
<BaseLayout>
<Hero />
<div class="w-full h-[1px] bg-white/10 my-24"></div>
<Experience />
<div class="container mx-auto px-6 lg:px-12">
<div class="w-full h-[1px] bg-white/10"></div>
<!-- Gradient Divider -->
<div class="w-full my-16 lg:my-24">
<div class="h-[1px] divider-gradient"></div>
</div>
<Experience />
<!-- Container Divider with accent hint -->
<div class="container mx-auto px-6 lg:px-12 my-8">
<div class="h-[1px] divider-gradient"></div>
</div>
<FeaturedProject />
<Skills />
</BaseLayout>

View File

@ -10,18 +10,77 @@
--font-sans: "Inter", sans-serif;
--font-mono: "Space Mono", monospace;
/* Animation keyframes */
--animate-reveal: reveal 0.8s cubic-bezier(0.16, 1, 0.3, 1) forwards;
--animate-fade-in: fade-in 0.6s cubic-bezier(0.16, 1, 0.3, 1) forwards;
--animate-slide-up: slide-up 0.7s cubic-bezier(0.16, 1, 0.3, 1) forwards;
--animate-slide-left: slide-left 0.7s cubic-bezier(0.16, 1, 0.3, 1) forwards;
--animate-slide-right: slide-right 0.7s cubic-bezier(0.16, 1, 0.3, 1) forwards;
--animate-scale-in: scale-in 0.5s cubic-bezier(0.16, 1, 0.3, 1) forwards;
@keyframes reveal {
from {
opacity: 0;
transform: translateY(20px);
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes fade-in {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes slide-up {
from {
opacity: 0;
transform: translateY(40px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes slide-left {
from {
opacity: 0;
transform: translateX(40px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
@keyframes slide-right {
from {
opacity: 0;
transform: translateX(-40px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
@keyframes scale-in {
from {
opacity: 0;
transform: scale(0.95);
}
to {
opacity: 1;
transform: scale(1);
}
}
}
@utility text-massive {
@ -30,20 +89,20 @@
}
@utility text-stroke {
-webkit-text-stroke: 1px rgba(255, 255, 255, 0.1);
-webkit-text-stroke: 1px rgba(255, 255, 255, 0.15);
color: transparent;
}
@utility skill-tag {
@apply text-[10px] font-mono font-bold uppercase tracking-wider px-2 py-2 border border-slate-700 text-slate-400 hover:border-brand-accent hover:text-white transition-colors cursor-default select-none;
@apply text-[10px] font-mono font-bold uppercase tracking-wider px-3 py-2 border border-slate-700 text-slate-400 hover:border-brand-accent hover:text-white transition-all duration-300 cursor-default select-none;
}
@utility btn-primary {
@apply bg-brand-accent text-brand-dark px-8 py-4 text-xs font-bold uppercase tracking-widest hover:bg-white transition-colors inline-block;
@apply bg-brand-accent text-brand-dark px-8 py-4 text-xs font-bold uppercase tracking-widest hover:bg-white transition-all duration-300 inline-block;
}
@utility btn-ghost {
@apply border border-slate-600 text-white px-8 py-4 text-xs font-bold uppercase tracking-widest hover:border-brand-accent hover:bg-brand-accent/5 transition-colors inline-block;
@apply border border-slate-600 text-white px-8 py-4 text-xs font-bold uppercase tracking-widest hover:border-brand-accent hover:bg-brand-accent/5 transition-all duration-300 inline-block;
}
@utility grid-overlay {
@ -58,7 +117,11 @@ body {
background-color: var(--color-brand-dark);
color: #ffffff;
overflow-x: hidden;
/* cursor: none; Handled by CustomCursor component logic, but we might want it here if we implement the custom cursor fully */
}
/* Smooth scroll behavior */
html {
scroll-behavior: smooth;
}
/* Custom Scrollbar */
@ -72,16 +135,67 @@ body {
::-webkit-scrollbar-thumb {
background: #334155;
transition: background 0.3s ease;
}
::-webkit-scrollbar-thumb:hover {
background: var(--color-brand-accent);
}
/* Reveal Animation Class (handled by JS intersection observer usually, but basic class here) */
/* ===== SCROLL ANIMATION SYSTEM ===== */
/* Base animation classes - elements start hidden */
.animate-on-scroll {
opacity: 0;
transition: opacity 0.6s cubic-bezier(0.16, 1, 0.3, 1),
transform 0.7s cubic-bezier(0.16, 1, 0.3, 1);
}
/* Slide up variant */
.animate-on-scroll.slide-up {
transform: translateY(40px);
}
/* Slide left variant (comes from right) */
.animate-on-scroll.slide-left {
transform: translateX(40px);
}
/* Slide right variant (comes from left) */
.animate-on-scroll.slide-right {
transform: translateX(-40px);
}
/* Scale in variant */
.animate-on-scroll.scale-in {
transform: scale(0.95);
}
/* Fade only */
.animate-on-scroll.fade-in {
transform: none;
}
/* Active state - when element is in view */
.animate-on-scroll.is-visible {
opacity: 1;
transform: translateY(0) translateX(0) scale(1);
}
/* Stagger delay classes for sequential animations */
.stagger-1 { transition-delay: 0.1s; }
.stagger-2 { transition-delay: 0.2s; }
.stagger-3 { transition-delay: 0.3s; }
.stagger-4 { transition-delay: 0.4s; }
.stagger-5 { transition-delay: 0.5s; }
.stagger-6 { transition-delay: 0.6s; }
.stagger-7 { transition-delay: 0.7s; }
.stagger-8 { transition-delay: 0.8s; }
/* Legacy reveal-text support */
.reveal-text {
opacity: 0;
transform: translateY(20px);
transform: translateY(30px);
transition: all 0.8s cubic-bezier(0.16, 1, 0.3, 1);
}
@ -90,7 +204,14 @@ body {
transform: translateY(0);
}
/* Cursor Styles */
/* Delay variants for reveal-text */
.reveal-text.delay-100 { transition-delay: 0.1s; }
.reveal-text.delay-200 { transition-delay: 0.2s; }
.reveal-text.delay-300 { transition-delay: 0.3s; }
.reveal-text.delay-400 { transition-delay: 0.4s; }
.reveal-text.delay-500 { transition-delay: 0.5s; }
/* ===== CURSOR STYLES ===== */
.cursor-dot,
.cursor-outline {
position: fixed;
@ -111,8 +232,10 @@ body {
.cursor-outline {
width: 40px;
height: 40px;
border: 1px solid rgba(255, 184, 76, 0.5);
transition: width 0.2s, height 0.2s, background-color 0.2s;
border: 1px solid rgba(255, 77, 0, 0.5);
transition: width 0.3s cubic-bezier(0.16, 1, 0.3, 1),
height 0.3s cubic-bezier(0.16, 1, 0.3, 1),
background-color 0.3s ease;
}
/* Interactive Elements Cursor Hover Effect */
@ -121,6 +244,59 @@ a:hover ~ .cursor-outline,
button:hover ~ .cursor-outline {
width: 60px;
height: 60px;
background-color: rgba(255, 184, 76, 0.05);
background-color: rgba(255, 77, 0, 0.05);
border-color: var(--color-brand-accent);
}
/* ===== ENHANCED TRANSITIONS ===== */
/* Smooth link transitions */
a {
transition: color 0.3s ease, border-color 0.3s ease;
}
/* Image hover zoom - smoother */
.hover-zoom {
transition: transform 1s cubic-bezier(0.16, 1, 0.3, 1);
}
.hover-zoom:hover,
.group:hover .hover-zoom {
transform: scale(1.05);
}
/* Line expand animation */
.line-expand {
transition: width 0.4s cubic-bezier(0.16, 1, 0.3, 1);
}
/* Border glow on hover - subtle */
.hover-border-glow {
transition: border-color 0.3s ease, box-shadow 0.3s ease;
}
.hover-border-glow:hover {
border-color: var(--color-brand-accent);
box-shadow: 0 0 20px rgba(255, 77, 0, 0.1);
}
/* Gradient divider */
.divider-gradient {
background: linear-gradient(
to right,
transparent,
rgba(255, 255, 255, 0.1) 20%,
rgba(255, 255, 255, 0.1) 80%,
transparent
);
}
/* Divider with accent hint */
.divider-accent {
background: linear-gradient(
to right,
transparent,
rgba(255, 77, 0, 0.2) 50%,
transparent
);
}