Nicholai 2ca66ccc6d Update theme variable usage and add ThemeToggle component
- Refactor component styles to use CSS custom properties for colors and backgrounds.
- Replace hard‑coded Tailwind classes with theme variables across BlogCard, BlogFilters, Footer, GridOverlay, Navigation, PostNavigation, ReadingProgress, RelatedPosts, TableOfContents, ThemeToggle, sections, layouts, pages, and global.css.
- Add ThemeToggle component for user‑controlled theme switching.
- Update global styles to define new theme variables.
- Ensure all components respect theme changes and maintain accessibility.

Hubert The Eunuch
2025-12-18 17:08:52 -07:00

107 lines
5.8 KiB
Plaintext

---
import { Image } from 'astro:assets';
interface Props {
sectionTitle: string;
sectionSubtitle: string;
description: string;
skills: Array<{
id: string;
domain: string;
tools: string;
proficiency: string;
}>;
}
const { sectionTitle, sectionSubtitle, description, skills } = Astro.props;
// Image map for skill data attributes
const imageMap: Record<string, string> = {
"01": "compositing",
"02": "3d",
"03": "ai",
"04": "dev"
};
---
<section id="skills" class="bg-[var(--theme-bg-primary)] py-32 lg:py-48 overflow-hidden relative cursor-default">
<div class="container mx-auto px-6 lg:px-12 relative z-10">
<!-- Header Section -->
<div class="mb-24 lg:mb-32 grid grid-cols-1 lg:grid-cols-12 gap-12">
<div class="lg:col-span-8 group cursor-default">
<div class="flex items-center gap-3 mb-6 intro-element animate-on-scroll fade-in">
<div class="w-2 h-2 bg-brand-accent animate-pulse"></div>
<span class="font-mono text-[10px] uppercase tracking-[0.3em] text-brand-accent">SYS.TOOLSET /// PIPELINE_CAPABILITIES</span>
</div>
<h2 class="text-5xl md:text-7xl lg:text-8xl font-bold uppercase tracking-tighter leading-[0.85] text-[var(--theme-text-primary)]">
<span class="block">{sectionTitle}</span>
<span class="block text-brand-accent">{sectionSubtitle}</span>
</h2>
</div>
<div class="lg:col-span-4 flex flex-col justify-end">
<div class="font-mono text-[10px] text-[var(--theme-text-subtle)] uppercase tracking-widest mb-4 flex items-center gap-2">
<span class="w-8 h-px bg-brand-accent/30"></span>
TECH_STACK_MANIFEST
</div>
<p class="text-[var(--theme-text-secondary)] text-lg leading-relaxed border-l border-brand-accent/30 pl-6">
{description}
</p>
</div>
</div>
<!-- Skills Data Grid -->
<div class="w-full border-t border-[var(--theme-border-primary)]" id="skills-table">
<!-- Table Header -->
<div class="grid grid-cols-12 gap-4 py-8 border-b border-[var(--theme-border-primary)] text-[10px] font-mono uppercase tracking-[0.2em] text-[var(--theme-text-muted)] select-none">
<div class="col-span-2 md:col-span-1">/// ID.TAG</div>
<div class="col-span-10 md:col-span-4">DOMAIN.SPECIALIZATION</div>
<div class="col-span-12 md:col-span-5 hidden md:block">PIP.TOOLSET</div>
<div class="col-span-6 md:col-span-2 hidden md:block text-right">LVL.STATUS</div>
</div>
{skills.map((skill, index) => {
const proficiencyClass = skill.proficiency === "Expert" || skill.proficiency === "Specialist"
? "border-brand-accent/50 text-brand-accent bg-brand-accent/5"
: "border-[var(--theme-border-strong)] text-[var(--theme-text-secondary)]";
return (
<div class={`skill-row group relative grid grid-cols-12 gap-4 py-10 border-b border-[var(--theme-border-primary)] items-center transition-colors duration-300 hover:border-brand-accent/30 overflow-hidden`} data-image={imageMap[skill.id] || "default"}>
<!-- Hover Background Effect -->
<div class="absolute inset-0 bg-brand-accent/5 opacity-0 group-hover:opacity-100 transition-opacity duration-300 pointer-events-none"></div>
<!-- ID Column -->
<div class="col-span-2 md:col-span-1 text-brand-accent font-mono text-sm relative overflow-hidden z-10">
<span class="block group-hover:-translate-y-full transition-transform duration-500">{skill.id}</span>
<span class="absolute top-0 left-0 translate-y-full group-hover:translate-y-0 transition-transform duration-500">{skill.id}</span>
</div>
<!-- Main Content (Domain) -->
<div class="col-span-10 md:col-span-4 relative z-10">
<h3 class="text-3xl md:text-5xl font-bold text-[var(--theme-text-primary)] uppercase tracking-tighter group-hover:text-brand-accent transition-colors duration-300">{skill.domain}</h3>
<!-- Scan line effect for ALL items on hover -->
<div class="absolute bottom-0 left-0 h-[1px] w-full bg-brand-accent transform scale-x-0 group-hover:scale-x-100 transition-transform duration-700 ease-out origin-left opacity-0 group-hover:opacity-100"></div>
</div>
<!-- Tools Stack -->
<div class="col-span-12 md:col-span-5 text-[var(--theme-text-secondary)] font-mono text-xs md:text-sm tracking-wide group-hover:text-[var(--theme-text-primary)] transition-colors duration-300 z-10">
{skill.tools}
</div>
<!-- Proficiency Badge -->
<div class="col-span-6 md:col-span-2 text-right hidden md:block z-10">
<span class={`inline-block px-3 py-1 border text-[10px] font-bold uppercase tracking-widest ${proficiencyClass} group-hover:bg-brand-accent group-hover:text-brand-dark transition-all duration-300`}>{skill.proficiency}</span>
</div>
<!-- Decorative "Scan" Sweep Overlay -->
<div class="absolute inset-0 bg-gradient-to-r from-transparent via-brand-accent/10 to-transparent -translate-x-full group-hover:animate-scan-sweep pointer-events-none"></div>
</div>
);
})}
</div>
</div>
</section>