Update design system to version 2.0, enhancing methodology and characteristics for a more technical aesthetic. Added new color palette variants and refined typography usage. Introduced new animations and interactions for improved user engagement. Updated favicon and apple touch icon assets. Revamped sections for better layout and visual hierarchy, including the Experience and Featured Project sections. Enhanced contact page with improved form handling and custom dropdown functionality.
This commit is contained in:
parent
aae6f7a25a
commit
4689332679
688
dev/design.json
688
dev/design.json
@ -1,20 +1,20 @@
|
|||||||
{
|
{
|
||||||
"design_system": {
|
"design_system": {
|
||||||
"name": "V7 Industrial Dark Mode System",
|
"name": "V7 Industrial Dark Mode System",
|
||||||
"version": "1.0",
|
"version": "2.0",
|
||||||
"methodology": {
|
"methodology": {
|
||||||
"approach": "Brutalist/Industrial Dark UI",
|
"approach": "Brutalist/Industrial Dark UI with System/Terminal Aesthetics",
|
||||||
"philosophy": "Grid-visible, high-contrast, typography-forward design with layered content and subtle glassmorphism",
|
"philosophy": "Grid-visible, high-contrast, typography-forward design. Interfaces should feel like high-end technical equipment (F1 telemetry, server racks, terminals).",
|
||||||
"characteristics": [
|
"characteristics": [
|
||||||
"Dark mode native (not an option, the default)",
|
"Dark mode native (not an option, the default)",
|
||||||
"Visible grid structure as design element",
|
"Visible grid structure as design element (10x10 interactive or 12-col static)",
|
||||||
"Massive typography as primary visual hierarchy",
|
"Massive typography as primary visual hierarchy (2-line stacks)",
|
||||||
"Minimal rounded corners (sharp, industrial aesthetic)",
|
"Minimal rounded corners (sharp, industrial aesthetic)",
|
||||||
"Heavy use of borders and dividers",
|
"Heavy use of borders, dividers, and technical labels (SYS.01, ///)",
|
||||||
"Layered content with overlays and blend modes",
|
"Layered content with overlays, video backgrounds, and blend modes",
|
||||||
"Subtle animations and smooth transitions",
|
"System-like animations: boot-up sequences, grid trails, status pulses",
|
||||||
"Opacity-based depth system",
|
"Opacity-based depth system (glass panels)",
|
||||||
"Technical/monospace accents"
|
"Technical/monospace accents for metadata (coordinates, time, IDs)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"color_palette": {
|
"color_palette": {
|
||||||
@ -43,7 +43,7 @@
|
|||||||
"hex": "#ff4d00",
|
"hex": "#ff4d00",
|
||||||
"rgb": "255, 77, 0",
|
"rgb": "255, 77, 0",
|
||||||
"name": "Vibrant Orange",
|
"name": "Vibrant Orange",
|
||||||
"usage": "Primary accent, CTAs, highlights, interactive elements",
|
"usage": "Primary accent, CTAs, highlights, interactive elements, status indicators",
|
||||||
"opacity_variants": [
|
"opacity_variants": [
|
||||||
{
|
{
|
||||||
"name": "brand_accent_5",
|
"name": "brand_accent_5",
|
||||||
@ -74,6 +74,7 @@
|
|||||||
"white": {
|
"white": {
|
||||||
"hex": "#FFFFFF",
|
"hex": "#FFFFFF",
|
||||||
"opacity_scale": {
|
"opacity_scale": {
|
||||||
|
"2": "rgba(255, 255, 255, 0.02)",
|
||||||
"5": "rgba(255, 255, 255, 0.05)",
|
"5": "rgba(255, 255, 255, 0.05)",
|
||||||
"10": "rgba(255, 255, 255, 0.1)",
|
"10": "rgba(255, 255, 255, 0.1)",
|
||||||
"20": "rgba(255, 255, 255, 0.2)",
|
"20": "rgba(255, 255, 255, 0.2)",
|
||||||
@ -125,37 +126,6 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"gradients": {
|
|
||||||
"primary_hero": {
|
|
||||||
"type": "linear-gradient",
|
|
||||||
"direction": "to top right",
|
|
||||||
"stops": [
|
|
||||||
"brand_accent",
|
|
||||||
"orange-500 (via)",
|
|
||||||
"brand_panel"
|
|
||||||
],
|
|
||||||
"css": "bg-gradient-to-tr from-brand-accent via-orange-500 to-brand-panel"
|
|
||||||
},
|
|
||||||
"fade_top": {
|
|
||||||
"type": "linear-gradient",
|
|
||||||
"direction": "to top",
|
|
||||||
"stops": [
|
|
||||||
"brand_dark",
|
|
||||||
"transparent (via)",
|
|
||||||
"transparent"
|
|
||||||
],
|
|
||||||
"usage": "Image overlays"
|
|
||||||
},
|
|
||||||
"card_dramatic": {
|
|
||||||
"type": "linear-gradient",
|
|
||||||
"direction": "to bottom right",
|
|
||||||
"stops": [
|
|
||||||
"orange-600",
|
|
||||||
"rose-700"
|
|
||||||
],
|
|
||||||
"usage": "Feature cards"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"typography": {
|
"typography": {
|
||||||
@ -163,43 +133,16 @@
|
|||||||
"primary": {
|
"primary": {
|
||||||
"name": "Inter",
|
"name": "Inter",
|
||||||
"type": "sans-serif",
|
"type": "sans-serif",
|
||||||
"weights": [
|
|
||||||
300,
|
|
||||||
400,
|
|
||||||
500,
|
|
||||||
600,
|
|
||||||
700,
|
|
||||||
800
|
|
||||||
],
|
|
||||||
"usage": "Primary UI font",
|
"usage": "Primary UI font",
|
||||||
"fallback": "sans-serif"
|
"fallback": "sans-serif"
|
||||||
},
|
},
|
||||||
"mono": {
|
"mono": {
|
||||||
"name": "system-ui monospace",
|
"name": "system-ui monospace",
|
||||||
"usage": "Numbers, technical details, small labels",
|
"usage": "Numbers, technical details, small labels, coordinates, clock",
|
||||||
"examples": [
|
"examples": [
|
||||||
"font-mono"
|
"font-mono"
|
||||||
]
|
]
|
||||||
},
|
}
|
||||||
"available_alternatives": [
|
|
||||||
"Geist",
|
|
||||||
"Roboto",
|
|
||||||
"Montserrat",
|
|
||||||
"Poppins",
|
|
||||||
"Playfair Display",
|
|
||||||
"Instrument Serif",
|
|
||||||
"Merriweather",
|
|
||||||
"Bricolage Grotesque",
|
|
||||||
"Plus Jakarta Sans",
|
|
||||||
"Manrope",
|
|
||||||
"Space Grotesk",
|
|
||||||
"Work Sans",
|
|
||||||
"PT Serif",
|
|
||||||
"Geist Mono",
|
|
||||||
"Space Mono",
|
|
||||||
"Quicksand",
|
|
||||||
"Nunito"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"scale": {
|
"scale": {
|
||||||
"xs": {
|
"xs": {
|
||||||
@ -242,582 +185,119 @@
|
|||||||
"line_height": "2.5rem",
|
"line_height": "2.5rem",
|
||||||
"usage": "Page headings"
|
"usage": "Page headings"
|
||||||
},
|
},
|
||||||
"5xl": {
|
|
||||||
"size": "3rem",
|
|
||||||
"line_height": "1",
|
|
||||||
"usage": "Large headings"
|
|
||||||
},
|
|
||||||
"6xl": {
|
"6xl": {
|
||||||
"size": "3.75rem",
|
"size": "3.75rem",
|
||||||
"line_height": "1",
|
"line_height": "1",
|
||||||
"usage": "Hero headings"
|
"usage": "Hero headings"
|
||||||
},
|
},
|
||||||
"7xl": {
|
|
||||||
"size": "4.5rem",
|
|
||||||
"line_height": "1",
|
|
||||||
"usage": "Display text (md)"
|
|
||||||
},
|
|
||||||
"8xl": {
|
"8xl": {
|
||||||
"size": "6rem",
|
"size": "6rem",
|
||||||
"line_height": "1",
|
"line_height": "1",
|
||||||
"usage": "Display text (lg)"
|
"usage": "Display text"
|
||||||
},
|
},
|
||||||
"massive": {
|
"9xl": {
|
||||||
"sizes": [
|
"size": "8rem",
|
||||||
"12rem",
|
"line_height": "0.85",
|
||||||
"18rem (md)",
|
"usage": "Massive Headers (2-line stacks)"
|
||||||
"22rem (lg)"
|
|
||||||
],
|
|
||||||
"line_height": "none",
|
|
||||||
"usage": "Hero display, massive branding"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"weights": {
|
|
||||||
"light": 300,
|
|
||||||
"normal": 400,
|
|
||||||
"medium": 500,
|
|
||||||
"semibold": 600,
|
|
||||||
"bold": 700,
|
|
||||||
"extrabold": 800
|
|
||||||
},
|
|
||||||
"letter_spacing": {
|
|
||||||
"tighter": "-0.05em",
|
|
||||||
"tight": "-0.025em",
|
|
||||||
"normal": "0",
|
|
||||||
"wide": "0.025em",
|
|
||||||
"wider": "0.05em",
|
|
||||||
"widest": "0.1em"
|
|
||||||
},
|
|
||||||
"text_transforms": {
|
|
||||||
"uppercase": {
|
|
||||||
"usage": "Labels, navigation, tags, metadata",
|
|
||||||
"typical_size": "xs or sm",
|
|
||||||
"typical_tracking": "widest or wider",
|
|
||||||
"typical_weight": "semibold or bold"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"line_heights": {
|
|
||||||
"none": "1",
|
|
||||||
"tight": "1.25",
|
|
||||||
"relaxed": "1.625"
|
|
||||||
},
|
|
||||||
"patterns": {
|
"patterns": {
|
||||||
"small_label": {
|
"technical_label": {
|
||||||
"size": "text-xs",
|
"size": "text-[10px]",
|
||||||
"weight": "font-bold",
|
"weight": "font-bold or font-medium",
|
||||||
|
"family": "font-mono",
|
||||||
"transform": "uppercase",
|
"transform": "uppercase",
|
||||||
"tracking": "tracking-widest",
|
"tracking": "tracking-widest",
|
||||||
"example": "text-xs font-bold uppercase tracking-widest"
|
"color": "text-slate-500 or text-brand-accent",
|
||||||
|
"example": "SYS.01 /// ACTIVE"
|
||||||
},
|
},
|
||||||
"hero_title": {
|
"massive_stack": {
|
||||||
"size": "text-[12rem] md:text-[18rem] lg:text-[22rem]",
|
"size": "text-6xl md:text-8xl lg:text-9xl",
|
||||||
"weight": "font-bold",
|
"weight": "font-bold",
|
||||||
"line_height": "leading-none",
|
"line_height": "leading-[0.85]",
|
||||||
"tracking": "tracking-tighter",
|
"tracking": "tracking-tighter",
|
||||||
"example_modifiers": "text-transparent bg-clip-text bg-gradient-to-tr"
|
"structure": "Two or three lines, mixture of solid white and text-stroke or accent color"
|
||||||
},
|
|
||||||
"section_heading": {
|
|
||||||
"size": "text-4xl md:text-5xl lg:text-6xl",
|
|
||||||
"weight": "font-semibold",
|
|
||||||
"tracking": "tracking-tight",
|
|
||||||
"color": "text-white"
|
|
||||||
},
|
|
||||||
"body_text": {
|
|
||||||
"size": "text-sm md:text-base",
|
|
||||||
"color": "text-slate-400",
|
|
||||||
"line_height": "leading-relaxed",
|
|
||||||
"weight": "font-normal or font-medium"
|
|
||||||
},
|
|
||||||
"mono_detail": {
|
|
||||||
"family": "font-mono",
|
|
||||||
"size": "text-xs or text-sm",
|
|
||||||
"weight": "font-medium or font-semibold",
|
|
||||||
"usage": "Numbers, codes, technical info"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"spacing": {
|
|
||||||
"scale": {
|
|
||||||
"0": "0px",
|
|
||||||
"1": "0.25rem",
|
|
||||||
"2": "0.5rem",
|
|
||||||
"3": "0.75rem",
|
|
||||||
"4": "1rem",
|
|
||||||
"6": "1.5rem",
|
|
||||||
"8": "2rem",
|
|
||||||
"10": "2.5rem",
|
|
||||||
"12": "3rem",
|
|
||||||
"16": "4rem",
|
|
||||||
"20": "5rem",
|
|
||||||
"24": "6rem",
|
|
||||||
"32": "8rem",
|
|
||||||
"48": "12rem"
|
|
||||||
},
|
|
||||||
"layout_padding": {
|
|
||||||
"mobile": "px-6",
|
|
||||||
"desktop": "lg:px-12",
|
|
||||||
"standard": "px-6 lg:px-12"
|
|
||||||
},
|
|
||||||
"section_spacing": {
|
|
||||||
"small": "py-8",
|
|
||||||
"medium": "py-12 md:py-16",
|
|
||||||
"large": "py-24",
|
|
||||||
"xlarge": "py-32 lg:py-48"
|
|
||||||
},
|
|
||||||
"component_spacing": {
|
|
||||||
"tight": "gap-2 or gap-3",
|
|
||||||
"normal": "gap-4 or gap-6",
|
|
||||||
"loose": "gap-8 or gap-12",
|
|
||||||
"extra_loose": "gap-12 md:gap-24"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"grid_system": {
|
"grid_system": {
|
||||||
"overlay": {
|
"interactive_overlay": {
|
||||||
"enabled": true,
|
"type": "10x10 Grid",
|
||||||
"purpose": "Visible design element",
|
"interaction": "mousemove trail effect",
|
||||||
"implementation": "Fixed position, pointer-events-none, opacity-10",
|
"style": "border border-white/5",
|
||||||
"columns": {
|
"active_state": "bg-brand-accent opacity-15",
|
||||||
"mobile": 4,
|
"fade_out": "duration-800 ease-out"
|
||||||
"tablet": 6,
|
|
||||||
"desktop": 12
|
|
||||||
},
|
},
|
||||||
"styling": "border-r border-slate-500 h-full"
|
"data_table": {
|
||||||
},
|
"columns": 12,
|
||||||
"content_grid": {
|
"headers": "text-[10px] font-mono uppercase tracking-widest",
|
||||||
"base": "grid grid-cols-1",
|
"rows": "border-b border-white/10 py-10 hover:border-brand-accent/30"
|
||||||
"tablet": "md:grid-cols-2 or md:grid-cols-4",
|
|
||||||
"desktop": "lg:grid-cols-12 or lg:grid-cols-2",
|
|
||||||
"gap": "gap-6 or gap-8 or gap-12"
|
|
||||||
},
|
|
||||||
"column_spans": {
|
|
||||||
"usage": "lg:col-span-{number}",
|
|
||||||
"common_patterns": [
|
|
||||||
"lg:col-span-3 (sidebar)",
|
|
||||||
"lg:col-span-9 (main content)",
|
|
||||||
"lg:col-span-4 / lg:col-span-8 (2:1 ratio)",
|
|
||||||
"lg:col-span-2 / lg:col-span-5 (asymmetric)"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"borders": {
|
|
||||||
"widths": {
|
|
||||||
"thin": "border or border-[1px]",
|
|
||||||
"medium": "border-2",
|
|
||||||
"thick": "border-[40px] (decorative)"
|
|
||||||
},
|
|
||||||
"colors": {
|
|
||||||
"subtle": "border-white/5",
|
|
||||||
"standard": "border-white/10 or border-white/20",
|
|
||||||
"visible": "border-white/30",
|
|
||||||
"slate_system": "border-slate-700 or border-slate-800",
|
|
||||||
"accent": "border-brand-accent"
|
|
||||||
},
|
|
||||||
"positions": {
|
|
||||||
"all": "border",
|
|
||||||
"top": "border-t or border-t-2",
|
|
||||||
"right": "border-r",
|
|
||||||
"bottom": "border-b",
|
|
||||||
"left": "border-l",
|
|
||||||
"horizontal": "border-x",
|
|
||||||
"vertical": "border-y"
|
|
||||||
},
|
|
||||||
"usage_patterns": {
|
|
||||||
"section_divider": "border-t border-slate-800",
|
|
||||||
"card": "border border-white/10 or border border-slate-800",
|
|
||||||
"active_state": "border-t-2 border-brand-accent",
|
|
||||||
"hover_state": "hover:border-brand-accent transition-colors"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"effects": {
|
|
||||||
"glassmorphism": {
|
|
||||||
"background": "bg-white/3 or rgba(255, 255, 255, 0.03)",
|
|
||||||
"backdrop": "backdrop-filter: blur(10px)",
|
|
||||||
"border": "border border-white/10",
|
|
||||||
"class_example": ".glass { background: rgba(255, 255, 255, 0.03); backdrop-filter: blur(10px); }"
|
|
||||||
},
|
|
||||||
"shadows": {
|
|
||||||
"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,77,0,0.5)]",
|
|
||||||
"drop_shadow": "drop-shadow-2xl"
|
|
||||||
},
|
|
||||||
"blur": {
|
|
||||||
"small": "blur-sm",
|
|
||||||
"backdrop": "backdrop-blur-sm"
|
|
||||||
},
|
|
||||||
"blend_modes": {
|
|
||||||
"multiply": "mix-blend-multiply",
|
|
||||||
"overlay": "mix-blend-overlay",
|
|
||||||
"luminosity": "mix-blend-luminosity"
|
|
||||||
},
|
|
||||||
"opacity": {
|
|
||||||
"scale": [
|
|
||||||
0,
|
|
||||||
5,
|
|
||||||
10,
|
|
||||||
20,
|
|
||||||
30,
|
|
||||||
40,
|
|
||||||
60,
|
|
||||||
90,
|
|
||||||
100
|
|
||||||
],
|
|
||||||
"usage": "opacity-{value}",
|
|
||||||
"common": {
|
|
||||||
"invisible": "opacity-0",
|
|
||||||
"barely_visible": "opacity-5 or opacity-10",
|
|
||||||
"subtle": "opacity-20 or opacity-30",
|
|
||||||
"medium": "opacity-40",
|
|
||||||
"visible": "opacity-60 or opacity-90",
|
|
||||||
"full": "opacity-100"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"animations": {
|
|
||||||
"transitions": {
|
|
||||||
"fast": "duration-300 or transition-all duration-300",
|
|
||||||
"medium": "duration-500",
|
|
||||||
"slow": "duration-700 or duration-1000",
|
|
||||||
"properties": {
|
|
||||||
"all": "transition-all",
|
|
||||||
"colors": "transition-colors",
|
|
||||||
"opacity": "transition-opacity",
|
|
||||||
"transform": "transition-transform"
|
|
||||||
},
|
|
||||||
"easing": {
|
|
||||||
"standard": "ease-out",
|
|
||||||
"smooth": "ease-in-out"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"transforms": {
|
|
||||||
"scale_subtle": "scale-100 hover:scale-105 transition-transform",
|
|
||||||
"scale_medium": "group-hover:scale-105 transition-all duration-700",
|
|
||||||
"scale_bold": "group-hover:scale-110",
|
|
||||||
"translate_x": "group-hover:translate-x-1 or group-hover:translate-x-0.5",
|
|
||||||
"translate_y": "translate-y-4 group-hover:translate-y-0"
|
|
||||||
},
|
|
||||||
"hover_states": {
|
|
||||||
"opacity_fade": "opacity-0 group-hover:opacity-100 transition-opacity duration-500",
|
|
||||||
"color_shift": "hover:text-white transition-colors",
|
|
||||||
"border_accent": "hover:border-brand-accent transition-all",
|
|
||||||
"background_lift": "hover:bg-white/5 transition-colors",
|
|
||||||
"combined": "hover:bg-brand-accent hover:text-brand-dark transition-all"
|
|
||||||
},
|
|
||||||
"keyframes": {
|
|
||||||
"pulse": {
|
|
||||||
"animation": "animate-pulse",
|
|
||||||
"usage": "Status indicators, live elements"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"delays": {
|
|
||||||
"stagger": "delay-100",
|
|
||||||
"usage": "Sequential reveals"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"components": {
|
"components": {
|
||||||
"buttons": {
|
"buttons": {
|
||||||
"primary": {
|
"terminal_action": {
|
||||||
"base": "bg-brand-accent text-brand-dark",
|
"base": "bg-transparent border border-white/20",
|
||||||
"padding": "px-8 py-4",
|
"hover": "hover:border-brand-accent hover:bg-brand-accent/5",
|
||||||
"typography": "text-xs font-bold uppercase tracking-widest",
|
"typography": "font-mono text-xs font-bold uppercase tracking-widest",
|
||||||
"hover": "hover:bg-amber-400 transition-colors",
|
"icon": "Arrow or chevron, translates on hover"
|
||||||
"full_class": "bg-brand-accent text-brand-dark text-xs font-bold uppercase px-8 py-4 tracking-widest hover:bg-amber-400 transition-colors"
|
|
||||||
},
|
|
||||||
"secondary": {
|
|
||||||
"base": "bg-white text-brand-dark",
|
|
||||||
"padding": "px-8 py-4",
|
|
||||||
"typography": "text-xs font-bold uppercase tracking-widest",
|
|
||||||
"hover": "hover:bg-slate-100 transition-colors"
|
|
||||||
},
|
|
||||||
"ghost": {
|
|
||||||
"base": "bg-transparent border border-slate-700",
|
|
||||||
"padding": "px-8 py-4 or p-4",
|
|
||||||
"typography": "text-xs font-bold uppercase tracking-widest",
|
|
||||||
"hover": "hover:border-brand-accent hover:bg-brand-accent/5 transition-all"
|
|
||||||
},
|
|
||||||
"icon": {
|
|
||||||
"size": "w-12 h-12",
|
|
||||||
"base": "border border-slate-700 flex items-center justify-center",
|
|
||||||
"hover": "hover:bg-white/5 transition-colors",
|
|
||||||
"rounded": "Can be rounded-full for circular buttons"
|
|
||||||
},
|
|
||||||
"cta_with_icon": {
|
|
||||||
"structure": "inline-flex items-center gap-3",
|
|
||||||
"example": "VIEW CASE STUDY [icon]"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cards": {
|
"cards": {
|
||||||
"glass_card": {
|
"rack_unit": {
|
||||||
"background": "bg-white/3 or rgba(255, 255, 255, 0.03)",
|
"base": "border border-white/10 bg-white/[0.02]",
|
||||||
|
"hover": "hover:border-brand-accent/50 hover:bg-white/[0.04]",
|
||||||
|
"header": "border-b border-white/5 px-8 py-4 flex justify-between",
|
||||||
|
"indicator": "left-border strip (solid or translucent)",
|
||||||
|
"content": "p-8 lg:p-12 grid layout"
|
||||||
|
},
|
||||||
|
"glass_panel": {
|
||||||
|
"background": "bg-white/[0.02]",
|
||||||
"backdrop": "backdrop-blur-sm",
|
"backdrop": "backdrop-blur-sm",
|
||||||
"border": "border border-white/5 or border-white/10",
|
"border": "border border-white/10",
|
||||||
"padding": "p-6 or p-8",
|
"hover": "hover:border-brand-accent/30"
|
||||||
"hover": "hover:border-brand-accent/50 transition-all"
|
|
||||||
},
|
|
||||||
"panel_card": {
|
|
||||||
"background": "bg-brand-panel",
|
|
||||||
"border": "border border-slate-800",
|
|
||||||
"padding": "p-12 lg:p-20"
|
|
||||||
},
|
|
||||||
"project_card": {
|
|
||||||
"structure": "relative overflow-hidden cursor-pointer",
|
|
||||||
"image": "absolute inset-0 bg-cover bg-center",
|
|
||||||
"overlay": "absolute inset-0 bg-brand-dark/80 group-hover:bg-brand-dark/20 transition-colors duration-500",
|
|
||||||
"gradient": "absolute inset-0 bg-gradient-to-t from-brand-dark via-transparent to-transparent",
|
|
||||||
"content": "absolute bottom-0 left-0 w-full p-8 transform translate-y-4 group-hover:translate-y-0",
|
|
||||||
"hover": "group-hover:scale-105 transition-transform duration-1000"
|
|
||||||
},
|
|
||||||
"feature_card": {
|
|
||||||
"background": "bg-gradient-to-br from-orange-600 to-rose-700",
|
|
||||||
"overlay": "absolute inset-0 opacity-20 bg-cover bg-center mix-blend-overlay",
|
|
||||||
"padding": "p-12 md:p-16",
|
|
||||||
"min_height": "min-h-[400px]"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"navigation": {
|
"inputs": {
|
||||||
"header": {
|
"terminal_input": {
|
||||||
"position": "fixed or relative",
|
"style": "border-b border-white/20 bg-transparent py-4 text-xl",
|
||||||
"padding": "px-6 lg:px-12 pt-8",
|
"focus": "focus:border-brand-accent focus:outline-none",
|
||||||
"structure": "flex items-center justify-between",
|
"label": "floating label (peer-focus:-top-6), font-mono, tracking-widest"
|
||||||
"logo": "w-10 h-10 border border-white/20 flex items-center justify-center font-bold text-white tracking-tighter"
|
|
||||||
},
|
},
|
||||||
"nav_links": {
|
"industrial_select": {
|
||||||
"base": "text-xs font-semibold tracking-widest uppercase text-slate-500",
|
"trigger": "custom div mimicking terminal input",
|
||||||
"hover": "hover:text-white transition-colors",
|
"menu": "bg-brand-dark border border-white/20 shadow-2xl",
|
||||||
"active": "text-brand-accent",
|
"option": "hover:bg-white/5 flex items-center gap-3",
|
||||||
"spacing": "gap-12"
|
"indicator": "accent dot reveals on hover"
|
||||||
},
|
|
||||||
"footer_nav": {
|
|
||||||
"grid": "grid grid-cols-4",
|
|
||||||
"item": "text-[10px] uppercase font-bold text-slate-400 tracking-wider text-center",
|
|
||||||
"hover": "hover:text-white hover:bg-slate-800 transition-colors",
|
|
||||||
"padding": "py-4"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tabs": {
|
"visualizations": {
|
||||||
"container": "grid grid-cols-2 md:grid-cols-4 border-b border-slate-800",
|
"telemetry_overlay": {
|
||||||
"tab_item": {
|
"usage": "Video backgrounds",
|
||||||
"base": "p-6 border-t-2 border-transparent cursor-pointer transition-colors group",
|
"elements": "Top/bottom data bars, grid overlays, F1-style stats",
|
||||||
"inactive": "hover:border-slate-700 bg-transparent",
|
"interaction": "Full card clickable, no modals"
|
||||||
"active": "border-brand-accent bg-white/5"
|
|
||||||
},
|
|
||||||
"tab_label": {
|
|
||||||
"number": "text-xs block mb-2",
|
|
||||||
"number_inactive": "text-slate-600",
|
|
||||||
"number_active": "text-brand-accent",
|
|
||||||
"text": "text-lg",
|
|
||||||
"text_inactive": "font-medium text-slate-400 group-hover:text-white",
|
|
||||||
"text_active": "font-semibold text-white"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"tags": {
|
|
||||||
"accent_tag": {
|
|
||||||
"base": "text-[10px] font-bold uppercase tracking-widest",
|
|
||||||
"background": "bg-brand-accent px-2 py-1",
|
|
||||||
"text": "text-brand-dark",
|
|
||||||
"extras": "rounded-sm shadow-lg shadow-brand-accent/20"
|
|
||||||
},
|
|
||||||
"category_tag": {
|
|
||||||
"base": "bg-black/20 or bg-slate-800",
|
|
||||||
"text": "text-white or text-slate-400",
|
|
||||||
"padding": "px-3 py-2",
|
|
||||||
"typography": "text-[10px] font-bold uppercase tracking-wider"
|
|
||||||
},
|
},
|
||||||
"status_indicator": {
|
"status_indicator": {
|
||||||
"dot": "w-2 h-2 bg-brand-accent rounded-full animate-pulse",
|
"dot": "w-2 h-2 bg-brand-accent rounded-full animate-pulse",
|
||||||
"glow": "shadow-[0_0_10px_rgba(255,77,0,0.5)]",
|
"label": "font-mono text-xs uppercase tracking-widest"
|
||||||
"label": "text-xs font-bold text-slate-500 tracking-widest uppercase font-mono"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"dividers": {
|
|
||||||
"line": "w-24 h-1 bg-white or bg-slate-600",
|
|
||||||
"hover_expand": "w-16 h-1 hover:w-24 transition-all",
|
|
||||||
"section": "border-t border-slate-800",
|
|
||||||
"decorative": "w-1 h-10 bg-brand-accent or w-0.5 h-12"
|
|
||||||
},
|
|
||||||
"image_treatments": {
|
|
||||||
"overlay_pattern": {
|
|
||||||
"dark_multiply": "absolute inset-0 bg-brand-dark/80 mix-blend-multiply",
|
|
||||||
"gradient_fade": "absolute inset-0 bg-gradient-to-t from-brand-dark via-transparent to-transparent opacity-90",
|
|
||||||
"texture": "absolute inset-0 opacity-20 bg-cover bg-center mix-blend-overlay"
|
|
||||||
},
|
|
||||||
"hover_zoom": "transition-transform duration-1000 group-hover:scale-105",
|
|
||||||
"aspect_ratios": "aspect-[4/3] or md:aspect-auto"
|
|
||||||
},
|
|
||||||
"metadata_display": {
|
|
||||||
"structure": "Border-t divider with label above content",
|
|
||||||
"label": "text-xs font-bold text-slate-500 uppercase mb-2",
|
|
||||||
"value": "text-white text-lg or text-sm",
|
|
||||||
"example": "<p class='text-xs font-bold text-slate-500 uppercase mb-2'>Year</p><p class='text-white text-lg'>2023 - 2024</p>"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"layout_patterns": {
|
|
||||||
"hero_section": {
|
|
||||||
"structure": "min-h-[90vh] flex flex-col justify-center",
|
|
||||||
"padding": "px-6 lg:px-12 pt-20",
|
|
||||||
"background": "Massive typography with background image at opacity-20",
|
|
||||||
"grid": "lg:grid-cols-12 with asymmetric column spans",
|
|
||||||
"title_treatment": "Text-transparent with gradient background-clip, drop-shadow",
|
|
||||||
"decorative_elements": "Blurred duplicate text layer beneath main text"
|
|
||||||
},
|
|
||||||
"two_column_split": {
|
|
||||||
"grid": "grid grid-cols-1 lg:grid-cols-2",
|
|
||||||
"borders": "border-t border-r border-b border-slate-800",
|
|
||||||
"min_height": "min-h-[600px] or min-h-[800px]",
|
|
||||||
"left_content": "Visual/image with overlays",
|
|
||||||
"right_content": "Details/text content with vertical padding"
|
|
||||||
},
|
|
||||||
"sidebar_layout": {
|
|
||||||
"grid": "lg:grid-cols-12",
|
|
||||||
"sidebar": "lg:col-span-3 border-r border-slate-800 p-8 lg:p-10 flex flex-col justify-between",
|
|
||||||
"main": "lg:col-span-9",
|
|
||||||
"sidebar_content": "Metadata, stats, navigation"
|
|
||||||
},
|
|
||||||
"masonry_grid": {
|
|
||||||
"base": "grid grid-cols-1 md:grid-cols-2",
|
|
||||||
"items": "aspect-[4/3] md:aspect-auto with hover effects",
|
|
||||||
"borders": "border-b border-r border-slate-800 pattern"
|
|
||||||
},
|
|
||||||
"full_width_section": {
|
|
||||||
"padding": "px-6 lg:px-12 py-24 or py-32 lg:py-48",
|
|
||||||
"border": "border-t border-slate-800",
|
|
||||||
"max_width": "max-w-7xl mx-auto (optional)"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"responsive_behavior": {
|
|
||||||
"breakpoints": {
|
|
||||||
"sm": "640px",
|
|
||||||
"md": "768px",
|
|
||||||
"lg": "1024px",
|
|
||||||
"xl": "1280px"
|
|
||||||
},
|
|
||||||
"patterns": {
|
|
||||||
"hide_mobile": "hidden md:block or hidden lg:flex",
|
|
||||||
"show_mobile_only": "lg:hidden",
|
|
||||||
"responsive_grid": "grid-cols-1 md:grid-cols-2 lg:grid-cols-12",
|
|
||||||
"responsive_text": "text-3xl md:text-5xl lg:text-6xl",
|
|
||||||
"responsive_spacing": "px-6 lg:px-12 or py-8 md:py-12 lg:py-16"
|
|
||||||
},
|
|
||||||
"mobile_considerations": {
|
|
||||||
"touch_targets": "Minimum 44px (h-12 w-12)",
|
|
||||||
"simplified_grids": "Single column on mobile, multi-column on tablet+",
|
|
||||||
"navigation": "Mobile controls shown below lg breakpoint",
|
|
||||||
"typography": "Scales down but maintains hierarchy"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"content_hierarchy": {
|
|
||||||
"levels": {
|
|
||||||
"1_mega_branding": {
|
|
||||||
"size": "text-[12rem] to text-[22rem]",
|
|
||||||
"treatment": "Gradient, transparent, decorative",
|
|
||||||
"purpose": "Brand presence, visual anchor"
|
|
||||||
},
|
|
||||||
"2_page_title": {
|
|
||||||
"size": "text-5xl to text-8xl",
|
|
||||||
"color": "text-white with optional text-slate-500 spans",
|
|
||||||
"weight": "font-semibold or font-bold"
|
|
||||||
},
|
|
||||||
"3_section_heading": {
|
|
||||||
"size": "text-4xl to text-6xl",
|
|
||||||
"color": "text-white",
|
|
||||||
"weight": "font-semibold"
|
|
||||||
},
|
|
||||||
"4_subsection": {
|
|
||||||
"size": "text-2xl to text-4xl",
|
|
||||||
"color": "text-white",
|
|
||||||
"weight": "font-medium to font-semibold"
|
|
||||||
},
|
|
||||||
"5_body": {
|
|
||||||
"size": "text-sm to text-lg",
|
|
||||||
"color": "text-slate-400 or text-slate-300",
|
|
||||||
"line_height": "leading-relaxed"
|
|
||||||
},
|
|
||||||
"6_metadata": {
|
|
||||||
"size": "text-xs or text-[10px]",
|
|
||||||
"transform": "uppercase",
|
|
||||||
"tracking": "tracking-widest or tracking-wider",
|
|
||||||
"color": "text-slate-500 or text-slate-600",
|
|
||||||
"weight": "font-bold or font-semibold"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"interactive_states": {
|
"animations": {
|
||||||
"hover": {
|
"intro_sequence": {
|
||||||
"color_shift": "hover:text-white hover:text-brand-accent",
|
"trigger": "window.load",
|
||||||
"background": "hover:bg-white/5 hover:bg-slate-700",
|
"order": [
|
||||||
"border": "hover:border-brand-accent hover:border-white",
|
"Grid ripple (diagonal)",
|
||||||
"scale": "hover:scale-105",
|
"Text slide up",
|
||||||
"opacity": "hover:opacity-100 (from lower opacity)"
|
"Metadata fade in",
|
||||||
},
|
"Portrait slow reveal"
|
||||||
"active": {
|
|
||||||
"indicators": "Border-t-2 border-brand-accent, bg-white/5, text color change",
|
|
||||||
"emphasis": "Brighter text, accent color borders"
|
|
||||||
},
|
|
||||||
"disabled": {
|
|
||||||
"opacity": "opacity-40 or opacity-60",
|
|
||||||
"cursor": "cursor-default",
|
|
||||||
"colors": "text-slate-600"
|
|
||||||
},
|
|
||||||
"focus": {
|
|
||||||
"treatment": "Follow hover states, no default focus rings visible in design"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"special_effects": {
|
|
||||||
"text_stroke": {
|
|
||||||
"css": "-webkit-text-stroke: 1px rgba(255,255,255,0.1); color: transparent;",
|
|
||||||
"usage": "Outlined text effect for decorative elements"
|
|
||||||
},
|
|
||||||
"gradient_text": {
|
|
||||||
"classes": "text-transparent bg-clip-text bg-gradient-to-tr from-brand-accent via-orange-500 to-brand-panel",
|
|
||||||
"usage": "Hero titles, emphasis text"
|
|
||||||
},
|
|
||||||
"animated_background": {
|
|
||||||
"transition": "duration-700 ease-out",
|
|
||||||
"hover": "opacity changes, scale transforms",
|
|
||||||
"example": "Image backgrounds that fade/zoom on interaction"
|
|
||||||
},
|
|
||||||
"layered_depth": {
|
|
||||||
"technique": "Multiple absolute positioned divs with different opacities, blend modes",
|
|
||||||
"layers": [
|
|
||||||
"Base image (bg-cover)",
|
|
||||||
"Multiply blend overlay (bg-brand-dark/80)",
|
|
||||||
"Gradient overlay (bg-gradient-to-t opacity-90)",
|
|
||||||
"Content layer (z-10 or z-20)"
|
|
||||||
]
|
]
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"accessibility_notes": {
|
"interactions": {
|
||||||
"contrast": "High contrast maintained throughout (white on dark backgrounds)",
|
"grid_trail": "Instant active, slow fade out (800ms)",
|
||||||
"focus_states": "Should be added for keyboard navigation",
|
"row_highlight": "Border color shift, text color shift",
|
||||||
"alt_text": "Images need descriptive alt text",
|
"social_arrow": "Translate X+1 Y-1 on hover"
|
||||||
"aria_labels": "Interactive elements need proper labels",
|
}
|
||||||
"semantic_html": "Use proper heading hierarchy (currently div-heavy)",
|
|
||||||
"color_alone": "Don't rely on color alone for information"
|
|
||||||
},
|
|
||||||
"design_tokens_summary": {
|
|
||||||
"primary_background": "#0B0D11",
|
|
||||||
"secondary_background": "#151921",
|
|
||||||
"primary_accent": "#ff4d00",
|
|
||||||
"primary_text": "#FFFFFF",
|
|
||||||
"secondary_text": "#94A3B8",
|
|
||||||
"border_subtle": "rgba(255, 255, 255, 0.1)",
|
|
||||||
"border_standard": "#334155",
|
|
||||||
"font_primary": "Inter, sans-serif",
|
|
||||||
"font_mono": "monospace",
|
|
||||||
"radius_minimal": "0 or 2px (rarely used)",
|
|
||||||
"shadow_glow": "0 0 10px rgba(255,77,0,0.5)",
|
|
||||||
"transition_fast": "300ms",
|
|
||||||
"transition_medium": "500ms",
|
|
||||||
"transition_slow": "700ms"
|
|
||||||
},
|
|
||||||
"implementation_notes": {
|
|
||||||
"framework": "Tailwind CSS with custom config",
|
|
||||||
"icons": "Iconify (solar, lucide sets primarily)",
|
|
||||||
"responsive_images": "Multiple sizes served, lazyload recommended",
|
|
||||||
"performance": "Optimize large background images, consider lazy loading for below-fold content",
|
|
||||||
"browser_support": "Modern browsers (backdrop-filter, blend modes require recent versions)",
|
|
||||||
"dark_mode_only": "No light mode variant in this system"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
public/apple-touch-icon.png
Normal file
BIN
public/apple-touch-icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 55 KiB |
BIN
public/favicon-192.png
Normal file
BIN
public/favicon-192.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 63 KiB |
BIN
public/favicon-32.png
Normal file
BIN
public/favicon-32.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.1 KiB |
BIN
public/favicon.ico
Normal file
BIN
public/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
@ -20,7 +20,10 @@ const { title, description, image = FallbackImage } = Astro.props;
|
|||||||
<!-- Global Metadata -->
|
<!-- Global Metadata -->
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32.png" />
|
||||||
|
<link rel="icon" type="image/png" sizes="192x192" href="/favicon-192.png" />
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
|
||||||
<link rel="sitemap" href="/sitemap-index.xml" />
|
<link rel="sitemap" href="/sitemap-index.xml" />
|
||||||
<link
|
<link
|
||||||
rel="alternate"
|
rel="alternate"
|
||||||
|
|||||||
@ -1,143 +1,140 @@
|
|||||||
---
|
---
|
||||||
---
|
---
|
||||||
<section id="experience" class="container mx-auto px-6 lg:px-12 py-32">
|
<section id="experience" class="container mx-auto px-6 lg:px-12 py-32 border-t border-white/10">
|
||||||
<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">
|
<!-- Section Header -->
|
||||||
<!-- Experience heading with scroll-driven fill effect -->
|
<div class="grid grid-cols-1 lg:grid-cols-12 gap-12 mb-20">
|
||||||
<h2 class="text-3xl md:text-4xl font-bold uppercase tracking-tight mb-2 relative">
|
<div class="lg:col-span-8">
|
||||||
<span class="text-stroke-fill" data-text="Experience">Experience</span>
|
<h2 class="text-6xl md:text-8xl lg:text-9xl font-bold uppercase tracking-tighter leading-[0.85] text-white">
|
||||||
|
<span class="block animate-on-scroll slide-up">Studio</span>
|
||||||
|
<span class="block text-transparent text-stroke animate-on-scroll slide-up stagger-1">History</span>
|
||||||
</h2>
|
</h2>
|
||||||
<h2 class="text-3xl md:text-4xl font-bold uppercase tracking-tight mb-10">History</h2>
|
</div>
|
||||||
<p class="text-slate-400 text-base leading-relaxed mb-10 max-w-sm font-light">
|
<div class="lg:col-span-4 flex flex-col justify-end pb-4">
|
||||||
Running my own VFX studio while taking on select freelance projects. I bridge the gap between
|
<div class="font-mono text-xs text-slate-500 uppercase tracking-widest mb-4">/// Career Timeline</div>
|
||||||
creative vision and technical execution.
|
<p class="text-slate-400 text-base leading-relaxed border-l border-brand-accent pl-6 animate-on-scroll fade-in stagger-2">
|
||||||
|
Bridging creative vision with technical execution. From running a dedicated VFX studio to high-end freelance supervision.
|
||||||
</p>
|
</p>
|
||||||
<a href="https://biohazardvfx.com" target="_blank"
|
</div>
|
||||||
class="inline-flex items-center gap-3 text-xs font-mono uppercase text-brand-accent hover:text-white transition-colors duration-300 group">
|
</div>
|
||||||
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>
|
<!-- "Rack Mount" Layout -->
|
||||||
|
<div class="flex flex-col gap-6">
|
||||||
|
|
||||||
|
<!-- Unit 01: Biohazard (Active System) -->
|
||||||
|
<div class="group relative border border-white/10 bg-white/[0.02] hover:border-brand-accent/50 hover:bg-white/[0.04] transition-all duration-500 overflow-hidden animate-on-scroll slide-up stagger-1">
|
||||||
|
<!-- Active Indicator Strip -->
|
||||||
|
<div class="absolute top-0 left-0 w-1 h-full bg-brand-accent opacity-100"></div>
|
||||||
|
<div class="absolute top-0 left-0 w-full h-1 bg-brand-accent opacity-0 group-hover:opacity-100 transition-opacity duration-500"></div>
|
||||||
|
|
||||||
|
<!-- Technical Header -->
|
||||||
|
<div class="flex items-center justify-between px-8 py-4 border-b border-white/5 bg-white/[0.02]">
|
||||||
|
<div class="flex items-center gap-4">
|
||||||
|
<span class="font-mono text-[10px] text-brand-accent uppercase tracking-widest">SYS.01 /// ACTIVE</span>
|
||||||
|
<div class="h-px w-12 bg-white/10"></div>
|
||||||
|
</div>
|
||||||
|
<span class="font-mono text-[10px] text-slate-500 uppercase tracking-widest">2022 — PRESENT</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="p-8 lg:p-12 grid grid-cols-1 lg:grid-cols-12 gap-12">
|
||||||
|
<div class="lg:col-span-4">
|
||||||
|
<h3 class="text-4xl font-bold text-white uppercase tracking-tight mb-2">Biohazard VFX</h3>
|
||||||
|
<span class="text-sm font-mono text-slate-400">Founder & Owner</span>
|
||||||
|
|
||||||
|
<div class="mt-8 flex flex-wrap gap-2">
|
||||||
|
<span class="px-2 py-1 text-[10px] font-mono uppercase border border-white/10 text-slate-400">Studio Lead</span>
|
||||||
|
<span class="px-2 py-1 text-[10px] font-mono uppercase border border-white/10 text-slate-400">Pipeline Arch</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="lg:col-span-8 flex flex-col justify-between">
|
||||||
|
<p class="text-slate-300 leading-relaxed font-light text-lg mb-8">
|
||||||
|
Founded and lead a VFX studio specializing in high-end commercial and music video work.
|
||||||
|
Delivered projects for Post Malone, ENHYPEN, and Nike. Architected a custom pipeline combining cloud and self-hosted infrastructure.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 border-t border-white/5 pt-8">
|
||||||
|
<div>
|
||||||
|
<h4 class="text-[10px] font-mono text-slate-500 uppercase tracking-widest mb-2">Key Achievement</h4>
|
||||||
|
<p class="text-sm text-slate-400">Designed 7-plate reconciliation workflows for ENHYPEN (projection mapping live action onto CAD).</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h4 class="text-[10px] font-mono text-slate-500 uppercase tracking-widest mb-2">System Impact</h4>
|
||||||
|
<p class="text-sm text-slate-400">Developed QA systems for AI-generated assets, transforming mid-tier output into production-ready deliverables.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-8 flex justify-end">
|
||||||
|
<a href="https://biohazardvfx.com" target="_blank" class="inline-flex items-center gap-3 text-xs font-bold uppercase tracking-widest text-white hover:text-brand-accent transition-colors">
|
||||||
|
Visit Studio Uplink <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14"/><path d="m12 5 7 7-7 7"/></svg>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</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-700/50 to-transparent"></div>
|
|
||||||
|
|
||||||
<!-- Item 1: Biohazard VFX -->
|
|
||||||
<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 & OWNER</span>
|
|
||||||
<span class="font-mono text-xs text-slate-500 md:ml-auto">2022 — PRESENT</span>
|
|
||||||
</div>
|
</div>
|
||||||
<p class="text-slate-400 mb-8 leading-relaxed font-light">
|
</div>
|
||||||
Founded and continue to lead a VFX studio specializing in high-end commercial and music video work.
|
|
||||||
Delivered projects for Post Malone, ENHYPEN, and Nike. Architected a custom pipeline combining cloud and
|
|
||||||
self-hosted infrastructure.
|
|
||||||
</p>
|
|
||||||
<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-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>
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Item 2: Stinkfilms / G-Star -->
|
<!-- Split Row for Stink & Freelance -->
|
||||||
<div class="pl-10 lg:pl-14 mb-20 relative animate-on-scroll slide-up stagger-2">
|
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
||||||
<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">
|
<!-- Unit 02: Stinkfilms -->
|
||||||
<h3 class="text-xl md:text-2xl font-bold text-white uppercase tracking-tight">Stinkfilms</h3>
|
<div class="group relative border border-white/10 bg-white/[0.02] hover:border-white/30 transition-all duration-500 overflow-hidden animate-on-scroll slide-up stagger-2">
|
||||||
<span class="font-mono text-[10px] text-slate-400 border border-slate-700 px-3 py-1.5 tracking-wide">GLOBAL PRODUCTION STUDIO</span>
|
<!-- Inactive Indicator Strip -->
|
||||||
<span class="font-mono text-xs text-slate-500 md:ml-auto">SUMMER 2024</span>
|
<div class="absolute top-0 left-0 w-1 h-full bg-slate-700 opacity-50 group-hover:bg-white transition-colors"></div>
|
||||||
|
|
||||||
|
<!-- Technical Header -->
|
||||||
|
<div class="flex items-center justify-between px-8 py-4 border-b border-white/5 bg-white/[0.02]">
|
||||||
|
<div class="flex items-center gap-4">
|
||||||
|
<span class="font-mono text-[10px] text-slate-500 uppercase tracking-widest">SYS.02 /// ARCHIVED</span>
|
||||||
</div>
|
</div>
|
||||||
<p class="text-slate-400 mb-8 leading-relaxed font-light">
|
<span class="font-mono text-[10px] text-slate-500 uppercase tracking-widest">SUMMER 2024</span>
|
||||||
Led Biohazard VFX team (60+ artists) alongside director Felix Brady to create a brand film
|
</div>
|
||||||
for G-Star Raw.
|
|
||||||
|
<div class="p-8 lg:p-10 flex flex-col h-full">
|
||||||
|
<div class="mb-6">
|
||||||
|
<h3 class="text-2xl font-bold text-white uppercase tracking-tight mb-1">Stinkfilms</h3>
|
||||||
|
<span class="text-xs font-mono text-slate-400">VFX Supervisor</span>
|
||||||
|
</div>
|
||||||
|
<p class="text-slate-400 leading-relaxed font-light text-sm mb-8 flex-grow">
|
||||||
|
Led Biohazard VFX team (60+ artists) alongside director Felix Brady to create a brand film for G-Star Raw.
|
||||||
|
Managed full CG environments in Blender/Houdini.
|
||||||
</p>
|
</p>
|
||||||
<a href="/blog/gstar-raw-olympics/" class="block 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">
|
<div class="pt-6 border-t border-white/5">
|
||||||
<h4 class="text-sm font-bold uppercase text-white mb-3 flex justify-between items-center tracking-wide">
|
<a href="/blog/gstar-raw-olympics/" class="inline-flex items-center gap-3 text-xs font-bold uppercase tracking-widest text-slate-300 hover:text-white transition-colors">
|
||||||
Project: G-Star Raw Olympics Campaign
|
Access Case Data <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14"/><path d="m12 5 7 7-7 7"/></svg>
|
||||||
<i data-lucide="arrow-right"
|
|
||||||
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-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>
|
|
||||||
<span class="text-[10px] font-bold text-brand-accent uppercase tracking-widest group-hover:text-white transition-colors duration-300">
|
|
||||||
Read Case Study
|
|
||||||
</span>
|
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Item 3: Freelance -->
|
|
||||||
<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">SELECT PROJECTS</span>
|
|
||||||
<span class="font-mono text-xs text-slate-500 md:ml-auto">ONGOING</span>
|
|
||||||
</div>
|
</div>
|
||||||
<p class="text-slate-400 leading-relaxed font-light">
|
</div>
|
||||||
|
|
||||||
|
<!-- Unit 03: Freelance -->
|
||||||
|
<div class="group relative border border-white/10 bg-white/[0.02] hover:border-white/30 transition-all duration-500 overflow-hidden animate-on-scroll slide-up stagger-3">
|
||||||
|
<!-- Background Process Indicator Strip -->
|
||||||
|
<div class="absolute top-0 left-0 w-1 h-full bg-slate-700 opacity-50 group-hover:bg-white transition-colors"></div>
|
||||||
|
|
||||||
|
<!-- Technical Header -->
|
||||||
|
<div class="flex items-center justify-between px-8 py-4 border-b border-white/5 bg-white/[0.02]">
|
||||||
|
<div class="flex items-center gap-4">
|
||||||
|
<span class="font-mono text-[10px] text-slate-500 uppercase tracking-widest">SYS.03 /// DAEMON</span>
|
||||||
|
</div>
|
||||||
|
<span class="font-mono text-[10px] text-slate-500 uppercase tracking-widest">2016 — PRESENT</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="p-8 lg:p-10 flex flex-col h-full">
|
||||||
|
<div class="mb-6">
|
||||||
|
<h3 class="text-2xl font-bold text-white uppercase tracking-tight mb-1">Freelance</h3>
|
||||||
|
<span class="text-xs font-mono text-slate-400">Senior Compositor</span>
|
||||||
|
</div>
|
||||||
|
<p class="text-slate-400 leading-relaxed font-light text-sm mb-8 flex-grow">
|
||||||
Taking on select freelance compositing and 3D work alongside studio operations.
|
Taking on select freelance compositing and 3D work alongside studio operations.
|
||||||
Previous clients include Abyss Digital and major labels (Atlantic, Interscope) —
|
Clients include Abyss Digital, Atlantic, Interscope.
|
||||||
David Kushner, Opium, Lil Durk, Don Toliver.
|
|
||||||
</p>
|
</p>
|
||||||
|
<div class="pt-6 border-t border-white/5 flex flex-wrap gap-2">
|
||||||
|
<span class="px-2 py-1 text-[10px] font-mono uppercase border border-white/10 text-slate-500">Nuke</span>
|
||||||
|
<span class="px-2 py-1 text-[10px] font-mono uppercase border border-white/10 text-slate-500">Flame</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<style>
|
|
||||||
/* Text stroke fill effect */
|
|
||||||
.text-stroke-fill {
|
|
||||||
position: relative;
|
|
||||||
-webkit-text-stroke: 1px rgba(255, 255, 255, 0.2);
|
|
||||||
color: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-stroke-fill::before {
|
|
||||||
content: attr(data-text);
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
color: var(--color-brand-accent);
|
|
||||||
-webkit-text-stroke: 0;
|
|
||||||
clip-path: inset(0 100% 0 0);
|
|
||||||
transition: clip-path 0.8s cubic-bezier(0.16, 1, 0.3, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-stroke-fill.filled::before {
|
|
||||||
clip-path: inset(0 0 0 0);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
// Scroll-driven fill effect for Experience heading
|
|
||||||
const experienceHeading = document.querySelector('.text-stroke-fill');
|
|
||||||
|
|
||||||
const fillObserver = new IntersectionObserver((entries) => {
|
|
||||||
entries.forEach(entry => {
|
|
||||||
if (entry.isIntersecting) {
|
|
||||||
// Add a slight delay for better effect
|
|
||||||
setTimeout(() => {
|
|
||||||
entry.target.classList.add('filled');
|
|
||||||
}, 200);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, {
|
|
||||||
threshold: 0.5,
|
|
||||||
rootMargin: "0px 0px -100px 0px"
|
|
||||||
});
|
|
||||||
|
|
||||||
if (experienceHeading) {
|
|
||||||
fillObserver.observe(experienceHeading);
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|||||||
@ -1,54 +1,100 @@
|
|||||||
---
|
---
|
||||||
---
|
---
|
||||||
<section id="work" class="py-32">
|
<section id="work" class="relative overflow-hidden group min-h-screen flex flex-col cursor-pointer">
|
||||||
<div class="container mx-auto px-6 lg:px-12 mb-14 animate-on-scroll slide-up">
|
<!-- Main Link Overlay -->
|
||||||
<span class="text-xs font-mono text-brand-accent mb-4 block tracking-wide">/// HIGHLIGHT</span>
|
<a href="/blog/gstar-raw-olympics/" class="absolute inset-0 z-30" aria-label="View G-Star Raw Olympics Case Study"></a>
|
||||||
<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>
|
<!-- Video Background -->
|
||||||
|
<div class="absolute inset-0 z-0">
|
||||||
|
<video
|
||||||
|
autoplay
|
||||||
|
loop
|
||||||
|
muted
|
||||||
|
playsinline
|
||||||
|
class="w-full h-full object-cover opacity-70 transition-opacity duration-700 group-hover:opacity-100"
|
||||||
|
>
|
||||||
|
<source src="/media/FF_PUFF_GStar_DC_v08_4608x3164.mp4" type="video/mp4" />
|
||||||
|
</video>
|
||||||
|
<!-- Cinematic Letterboxing / Gradient Vignette -->
|
||||||
|
<div class="absolute inset-0 bg-gradient-to-b from-brand-dark/80 via-transparent to-brand-dark/80 pointer-events-none"></div>
|
||||||
|
<div class="absolute inset-0 bg-gradient-to-r from-brand-dark/40 via-transparent to-brand-dark/40 pointer-events-none"></div>
|
||||||
|
|
||||||
|
<!-- Subtle Grid Overlay -->
|
||||||
|
<div class="absolute inset-0 bg-[linear-gradient(rgba(255,255,255,0.02)_1px,transparent_1px),linear-gradient(90deg,rgba(255,255,255,0.02)_1px,transparent_1px)] bg-[size:60px_60px] pointer-events-none opacity-30"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Main Content Container - Spaced to frame the video -->
|
||||||
|
<div class="container mx-auto px-6 lg:px-12 relative z-10 flex-1 flex flex-col justify-between py-12 lg:py-16 pointer-events-none">
|
||||||
|
|
||||||
|
<!-- TOP HUD: Telemetry Data -->
|
||||||
|
<div class="grid grid-cols-2 md:grid-cols-4 gap-8 border-t border-white/20 pt-6 animate-on-scroll slide-up">
|
||||||
|
<div>
|
||||||
|
<span class="text-[9px] font-mono text-brand-accent uppercase tracking-widest block mb-1">/// Role</span>
|
||||||
|
<span class="text-xl md:text-2xl font-bold text-white uppercase tracking-tight">VFX Sup</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span class="text-[9px] font-mono text-brand-accent uppercase tracking-widest block mb-1">/// Client</span>
|
||||||
|
<span class="text-xl md:text-2xl font-bold text-white uppercase tracking-tight">Stink</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span class="text-[9px] font-mono text-brand-accent uppercase tracking-widest block mb-1">/// Year</span>
|
||||||
|
<span class="text-xl md:text-2xl font-bold text-white uppercase tracking-tight">2024</span>
|
||||||
|
</div>
|
||||||
|
<div class="text-right md:text-left">
|
||||||
|
<span class="text-[9px] font-mono text-brand-accent uppercase tracking-widest block mb-1">/// Region</span>
|
||||||
|
<span class="text-xl md:text-2xl font-bold text-white uppercase tracking-tight">Global</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- CENTER AREA: Clear for Video -->
|
||||||
|
<div class="flex-1 relative">
|
||||||
|
<!-- Side Vertical Title (Optional, unobtrusive) -->
|
||||||
|
<div class="hidden lg:block absolute -left-8 top-1/2 -translate-y-1/2 origin-left -rotate-90">
|
||||||
|
<h2 class="text-6xl font-bold text-transparent text-stroke uppercase tracking-tighter opacity-20 select-none">
|
||||||
|
G-Star Raw
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Full Width Project Card -->
|
|
||||||
<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-[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-20"></div>
|
|
||||||
|
|
||||||
<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>
|
</div>
|
||||||
<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
|
<!-- BOTTOM HUD: Project Details & Stats -->
|
||||||
normal maps for relighting in Nuke.
|
<div class="border-b border-white/20 pb-6 animate-on-scroll slide-up stagger-1">
|
||||||
|
<div class="grid grid-cols-1 lg:grid-cols-12 gap-8 items-end">
|
||||||
|
|
||||||
|
<!-- Title & Description -->
|
||||||
|
<div class="lg:col-span-7">
|
||||||
|
<h2 class="text-5xl md:text-7xl font-bold uppercase text-white mb-4 tracking-tighter leading-none">
|
||||||
|
G-Star <span class="text-transparent text-stroke">Olympics</span>
|
||||||
|
</h2>
|
||||||
|
<p class="text-slate-300 font-light max-w-lg text-sm md:text-base leading-relaxed">
|
||||||
|
Full CG environment production for the 2024 Olympic Campaign.
|
||||||
|
Orchestrated procedural city generation and AI-enhanced lighting workflows.
|
||||||
</p>
|
</p>
|
||||||
<div class="flex flex-wrap items-center gap-6">
|
</div>
|
||||||
<a href="/blog/gstar-raw-olympics/"
|
|
||||||
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">
|
<!-- Technical Stats (Mini-Table) -->
|
||||||
Read Case Study
|
<div class="lg:col-span-5">
|
||||||
<i data-lucide="arrow-right" class="w-4 h-4 transition-transform duration-300 group-hover/link:translate-x-1"></i>
|
<div class="grid grid-cols-2 gap-x-8 gap-y-4 font-mono text-xs">
|
||||||
</a>
|
<div class="border-l border-brand-accent/30 pl-3">
|
||||||
<a href="https://f.io/7ijf23Wm" target="_blank" rel="noopener"
|
<span class="block text-slate-500 text-[10px] uppercase mb-1">Shot Count</span>
|
||||||
class="inline-flex items-center gap-4 text-xs font-bold uppercase tracking-widest text-slate-400 hover:text-white transition-all duration-300 group/link">
|
<span class="block text-white font-bold">12 Sequences</span>
|
||||||
Watch Making Of
|
</div>
|
||||||
<i data-lucide="play-circle" class="w-4 h-4 transition-transform duration-300 group-hover/link:scale-110"></i>
|
<div class="border-l border-brand-accent/30 pl-3">
|
||||||
</a>
|
<span class="block text-slate-500 text-[10px] uppercase mb-1">Resolution</span>
|
||||||
|
<span class="block text-white font-bold">4K DCI</span>
|
||||||
|
</div>
|
||||||
|
<div class="border-l border-brand-accent/30 pl-3">
|
||||||
|
<span class="block text-slate-500 text-[10px] uppercase mb-1">Pipeline</span>
|
||||||
|
<span class="block text-white font-bold">Houdini / Solaris</span>
|
||||||
|
</div>
|
||||||
|
<div class="border-l border-brand-accent/30 pl-3">
|
||||||
|
<span class="block text-slate-500 text-[10px] uppercase mb-1">Render</span>
|
||||||
|
<span class="block text-white font-bold">Karma XPU</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<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>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@ -1,77 +1,100 @@
|
|||||||
---
|
---
|
||||||
---
|
---
|
||||||
<section id="about" class="container mx-auto px-6 lg:px-12 min-h-[80vh] flex flex-col justify-center relative pb-24">
|
<section id="hero" class="relative w-full h-screen overflow-hidden bg-brand-dark">
|
||||||
<div class="grid grid-cols-1 md:grid-cols-12 gap-8 lg:gap-12">
|
<!-- Background Image (Portrait) -->
|
||||||
<div class="col-span-12">
|
<div class="absolute top-0 right-0 w-full md:w-1/2 h-full z-0">
|
||||||
<p class="font-mono text-brand-accent text-sm mb-6 tracking-wide animate-on-scroll fade-in">
|
<div class="relative w-full h-full">
|
||||||
/// TECHNICAL GENERALIST & VFX SUPERVISOR
|
<img
|
||||||
</p>
|
src="/media/nicholai-closeup-portrait.JPEG"
|
||||||
<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">
|
alt="Nicholai Portrait"
|
||||||
<span class="animate-on-scroll slide-up block stagger-1">Visual</span>
|
class="w-full h-full object-cover object-center opacity-0 mix-blend-luminosity md:opacity-0 transition-opacity duration-[2000ms] ease-out delay-500 intro-element"
|
||||||
<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>
|
id="hero-portrait"
|
||||||
|
/>
|
||||||
|
<div class="absolute inset-0 bg-gradient-to-l from-transparent via-brand-dark/50 to-brand-dark"></div>
|
||||||
|
<div class="absolute inset-0 bg-gradient-to-t from-brand-dark via-transparent to-transparent"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- The 100 Squares Grid Overlay -->
|
||||||
|
<div id="grid-container" class="absolute inset-0 z-10 w-full h-full grid grid-cols-10 grid-rows-10 pointer-events-none">
|
||||||
|
{Array.from({ length: 100 }).map((_, i) => (
|
||||||
|
<div class="grid-cell w-full h-full border border-white/5 opacity-0 transition-all duration-500 ease-out" data-index={i}></div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- The Content -->
|
||||||
|
<!-- Adjusted pt to clear fixed nav since BaseLayout padding is removed -->
|
||||||
|
<div class="absolute inset-0 z-20 flex flex-col justify-between p-6 md:p-12 lg:p-16 pt-32 lg:pt-40 pointer-events-auto">
|
||||||
|
|
||||||
|
<!-- Top Metadata -->
|
||||||
|
<div class="flex justify-between items-start w-full intro-element opacity-0 translate-y-4 transition-all duration-1000 ease-out delay-300">
|
||||||
|
<div class="font-mono text-xs uppercase tracking-widest text-slate-500">
|
||||||
|
Portfolio 2026
|
||||||
|
</div>
|
||||||
|
<div class="font-mono text-xs text-slate-500 text-right tracking-wide">
|
||||||
|
<span class="block text-slate-600 mb-1 uppercase tracking-widest">Location</span>
|
||||||
|
Colorado Springs, CO<br>
|
||||||
|
<span id="clock" class="text-brand-accent">00:00:00 MST</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Main Heading & Description -->
|
||||||
|
<div class="max-w-5xl">
|
||||||
|
<h1 class="text-6xl md:text-8xl lg:text-9xl tracking-tighter leading-[0.9] font-bold text-white mix-blend-overlay opacity-90 mb-8 perspective-text">
|
||||||
|
<span class="block intro-element opacity-0 translate-y-10 transition-all duration-1000 ease-out delay-100">VISUAL</span>
|
||||||
|
<span class="block text-brand-accent opacity-0 translate-y-10 transition-all duration-1000 ease-out delay-200 intro-element">ALCHEMIST</span>
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
|
||||||
<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="font-mono text-sm md:text-base max-w-lg text-slate-400 font-light leading-relaxed intro-element opacity-0 translate-y-6 transition-all duration-1000 ease-out delay-500">
|
||||||
<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. Creating end-to-end visual content for clients like Post Malone, Stinkfilms, and Adidas. Bridging creative vision with technical execution.
|
||||||
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-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>
|
</p>
|
||||||
<div class="flex gap-6">
|
</div>
|
||||||
<a href="#work"
|
|
||||||
class="group flex items-center gap-4 text-xs font-bold uppercase tracking-widest text-white hover:text-brand-accent transition-all duration-300">
|
<!-- Bottom Navigation -->
|
||||||
<span class="w-10 h-[2px] bg-brand-accent group-hover:w-16 transition-all duration-500 ease-out"></span>
|
<div class="flex justify-between items-end w-full intro-element opacity-0 transition-all duration-1000 ease-out delay-700">
|
||||||
View Selected Works
|
<a href="#experience" class="flex items-center justify-center w-12 h-12 border border-white/10 rounded-full text-brand-accent hover:bg-brand-accent hover:text-brand-dark transition-all duration-300 group">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="group-hover:animate-bounce">
|
||||||
|
<path d="M12 5v14M19 12l-7 7-7-7"/>
|
||||||
|
</svg>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Hero Footer -->
|
<div class="text-right font-mono text-xs text-slate-500 tracking-widest">
|
||||||
<div class="absolute bottom-8 w-full left-0 px-6 lg:px-12 hidden md:flex justify-between items-end animate-on-scroll fade-in stagger-5">
|
SCROLL TO EXPLORE
|
||||||
<div class="font-mono text-xs text-slate-500 tracking-wide opacity-60">
|
|
||||||
<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>
|
||||||
|
|
||||||
<!-- Scroll Indicator with animation -->
|
|
||||||
<div id="scroll-indicator" class="font-mono text-xs text-slate-500 text-right tracking-wide transition-all duration-500">
|
|
||||||
<span class="block text-slate-600 mb-1">EXPLORE</span>
|
|
||||||
<span class="inline-flex flex-col items-center">
|
|
||||||
SCROLL
|
|
||||||
<span class="scroll-arrow block mt-2 w-[1px] h-8 bg-gradient-to-b from-brand-accent to-transparent"></span>
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
/* Scroll arrow bounce animation */
|
.grid-cell.active {
|
||||||
.scroll-arrow {
|
background-color: var(--color-brand-accent);
|
||||||
animation: scrollBounce 2s ease-in-out infinite;
|
opacity: 0.15;
|
||||||
|
transition: opacity 0s, background-color 0s; /* Instant on */
|
||||||
|
}
|
||||||
|
/* Fade out */
|
||||||
|
.grid-cell {
|
||||||
|
transition: opacity 0.8s ease-out, background-color 0.8s ease-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes scrollBounce {
|
/* Initial Loaded State Classes */
|
||||||
0%, 100% {
|
.intro-visible {
|
||||||
transform: translateY(0);
|
opacity: 1 !important;
|
||||||
opacity: 1;
|
transform: translateY(0) !important;
|
||||||
}
|
|
||||||
50% {
|
|
||||||
transform: translateY(8px);
|
|
||||||
opacity: 0.6;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fade out on scroll */
|
/* Portrait Loaded State */
|
||||||
#scroll-indicator.scrolled {
|
.portrait-visible {
|
||||||
opacity: 0;
|
opacity: 0.4 !important; /* Mobile default */
|
||||||
transform: translateY(10px);
|
}
|
||||||
pointer-events: none;
|
@media (min-width: 768px) {
|
||||||
|
.portrait-visible {
|
||||||
|
opacity: 0.6 !important; /* Desktop default */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
// Clock
|
||||||
function updateClock() {
|
function updateClock() {
|
||||||
const clock = document.getElementById('clock');
|
const clock = document.getElementById('clock');
|
||||||
if (clock) {
|
if (clock) {
|
||||||
@ -83,27 +106,104 @@
|
|||||||
setInterval(updateClock, 1000);
|
setInterval(updateClock, 1000);
|
||||||
updateClock();
|
updateClock();
|
||||||
|
|
||||||
// Scroll-driven fade for scroll indicator
|
// Intro Animation Sequence
|
||||||
const scrollIndicator = document.getElementById('scroll-indicator');
|
window.addEventListener('load', () => {
|
||||||
|
// Trigger Intro Elements
|
||||||
|
const introElements = document.querySelectorAll('.intro-element');
|
||||||
|
introElements.forEach(el => {
|
||||||
|
el.classList.add('intro-visible');
|
||||||
|
});
|
||||||
|
|
||||||
function handleScroll() {
|
// Trigger Portrait
|
||||||
if (scrollIndicator) {
|
const portrait = document.getElementById('hero-portrait');
|
||||||
const scrollY = window.scrollY;
|
if (portrait) {
|
||||||
// Start fading at 50px, fully hidden at 200px
|
portrait.classList.add('portrait-visible');
|
||||||
const opacity = Math.max(0, 1 - (scrollY / 150));
|
|
||||||
const translateY = Math.min(20, scrollY / 10);
|
|
||||||
|
|
||||||
scrollIndicator.style.opacity = opacity.toString();
|
|
||||||
scrollIndicator.style.transform = `translateY(${translateY}px)`;
|
|
||||||
|
|
||||||
if (scrollY > 50) {
|
|
||||||
scrollIndicator.classList.add('scrolled');
|
|
||||||
} else {
|
|
||||||
scrollIndicator.classList.remove('scrolled');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
window.addEventListener('scroll', handleScroll, { passive: true });
|
// Trigger Grid Ripple
|
||||||
handleScroll(); // Initial check
|
const cells = document.querySelectorAll('.grid-cell');
|
||||||
|
// Diagonal sweep effect
|
||||||
|
cells.forEach((cell, i) => {
|
||||||
|
const row = Math.floor(i / 10);
|
||||||
|
const col = i % 10;
|
||||||
|
const delay = (row + col) * 50; // Diagonal delay
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
cell.classList.add('active');
|
||||||
|
setTimeout(() => {
|
||||||
|
cell.classList.remove('active');
|
||||||
|
}, 200);
|
||||||
|
}, delay);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// Robust Grid Interaction
|
||||||
|
const section = document.getElementById('hero');
|
||||||
|
const cells = document.querySelectorAll('.grid-cell');
|
||||||
|
|
||||||
|
if (section) {
|
||||||
|
section.addEventListener('mousemove', (e) => {
|
||||||
|
const rect = section.getBoundingClientRect();
|
||||||
|
// Calculate relative coordinates
|
||||||
|
const x = e.clientX - rect.left;
|
||||||
|
const y = e.clientY - rect.top;
|
||||||
|
|
||||||
|
// Calculate grid dimensions
|
||||||
|
const width = rect.width;
|
||||||
|
const height = rect.height;
|
||||||
|
|
||||||
|
// 10x10 grid
|
||||||
|
const col = Math.floor((x / width) * 10);
|
||||||
|
const row = Math.floor((y / height) * 10);
|
||||||
|
|
||||||
|
// Bounds check
|
||||||
|
if (col >= 0 && col < 10 && row >= 0 && row < 10) {
|
||||||
|
const index = row * 10 + col;
|
||||||
|
const cell = cells[index];
|
||||||
|
|
||||||
|
if (cell) {
|
||||||
|
// Remove active class from all others (optional, or let them fade)
|
||||||
|
// cell.classList.add('active');
|
||||||
|
|
||||||
|
// To prevent "sticking", we can use a timestamp or just let CSS transition handle fade out
|
||||||
|
// But we need to trigger the "hit"
|
||||||
|
|
||||||
|
// Logic: Add active, then remove it shortly after to trigger fade
|
||||||
|
cell.classList.add('active');
|
||||||
|
|
||||||
|
// Clear previous timeout if this cell was just hit?
|
||||||
|
// Simpler: Just add active. Use requestAnimationFrame to clear "old" active cells?
|
||||||
|
// Or just let the CSS transition handle the fade out when class is removed.
|
||||||
|
|
||||||
|
// Better approach for "trail":
|
||||||
|
// Add active class. Set a timeout to remove it.
|
||||||
|
|
||||||
|
if (cell.dataset.timeout) {
|
||||||
|
clearTimeout(Number(cell.dataset.timeout));
|
||||||
|
}
|
||||||
|
|
||||||
|
const timeoutId = setTimeout(() => {
|
||||||
|
cell.classList.remove('active');
|
||||||
|
}, 50); // Short "hold" time, then fade out via CSS
|
||||||
|
|
||||||
|
cell.dataset.timeout = String(timeoutId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Random pulse for liveliness
|
||||||
|
function pulseRandomSquare() {
|
||||||
|
// Only pulse if not currently interacting (optional, but keeps it cleaner)
|
||||||
|
const randomIndex = Math.floor(Math.random() * cells.length);
|
||||||
|
const cell = cells[randomIndex];
|
||||||
|
if(cell) {
|
||||||
|
cell.classList.add('active');
|
||||||
|
setTimeout(() => {
|
||||||
|
cell.classList.remove('active');
|
||||||
|
}, 200);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setInterval(pulseRandomSquare, 1500);
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -1,75 +1,111 @@
|
|||||||
---
|
---
|
||||||
|
import { Image } from 'astro:assets';
|
||||||
---
|
---
|
||||||
<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 -->
|
<section id="skills" class="bg-brand-dark py-32 lg:py-48 overflow-hidden relative cursor-default">
|
||||||
<div class="animate-on-scroll slide-up stagger-1">
|
<div class="container mx-auto px-6 lg:px-12 relative z-10">
|
||||||
<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>
|
<!-- Header Section -->
|
||||||
Compositing
|
<div class="mb-24 lg:mb-32 grid grid-cols-1 lg:grid-cols-12 gap-12">
|
||||||
</h3>
|
<div class="lg:col-span-8">
|
||||||
<div class="flex flex-wrap gap-2">
|
<h2 class="text-6xl md:text-8xl lg:text-9xl font-bold uppercase tracking-tighter leading-[0.85] text-white">
|
||||||
<span class="skill-tag">Nuke/NukeX</span>
|
<span class="block relative overflow-hidden">
|
||||||
<span class="skill-tag">ComfyUI</span>
|
<span class="animate-on-scroll slide-up block">Technical</span>
|
||||||
<span class="skill-tag">After Effects</span>
|
</span>
|
||||||
<span class="skill-tag">Photoshop</span>
|
<span class="block relative overflow-hidden">
|
||||||
<span class="skill-tag">Deep Compositing</span>
|
<span class="animate-on-scroll slide-up stagger-1 block text-stroke text-transparent">Arsenal</span>
|
||||||
<span class="skill-tag">Live Action VFX</span>
|
</span>
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<div class="lg:col-span-4 flex items-end">
|
||||||
|
<p class="text-slate-400 text-lg leading-relaxed animate-on-scroll slide-up stagger-2 border-l-2 border-brand-accent pl-6">
|
||||||
|
A comprehensive suite of tools and workflows designed for high-fidelity visual production and pipeline automation.
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 3D -->
|
<!-- Skills Data Grid -->
|
||||||
<div class="animate-on-scroll slide-up stagger-2">
|
<div class="w-full border-t border-white/10" id="skills-table">
|
||||||
<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>
|
<!-- Table Header -->
|
||||||
3D Generalist
|
<div class="grid grid-cols-12 gap-4 py-6 border-b border-white/10 text-[10px] font-mono uppercase tracking-widest text-slate-500 select-none">
|
||||||
</h3>
|
<div class="col-span-2 md:col-span-1">/// ID</div>
|
||||||
<div class="flex flex-wrap gap-2">
|
<div class="col-span-10 md:col-span-4">Domain</div>
|
||||||
<span class="skill-tag">Houdini</span>
|
<div class="col-span-12 md:col-span-5 hidden md:block">Stack</div>
|
||||||
<span class="skill-tag">Blender</span>
|
<div class="col-span-6 md:col-span-2 hidden md:block text-right">Proficiency</div>
|
||||||
<span class="skill-tag">Maya</span>
|
</div>
|
||||||
<span class="skill-tag">USD</span>
|
|
||||||
<span class="skill-tag">Solaris/Karma</span>
|
<!-- Row 1: Compositing -->
|
||||||
<span class="skill-tag">Unreal Engine</span>
|
<div class="skill-row group relative grid grid-cols-12 gap-4 py-10 border-b border-white/10 items-center transition-colors duration-300 hover:border-brand-accent/30" data-image="compositing">
|
||||||
<span class="skill-tag">Substance</span>
|
<div class="col-span-2 md:col-span-1 text-brand-accent font-mono text-sm relative overflow-hidden">
|
||||||
<span class="skill-tag">Procedural Gen</span>
|
<span class="block group-hover:-translate-y-full transition-transform duration-500">01</span>
|
||||||
|
<span class="absolute top-0 left-0 translate-y-full group-hover:translate-y-0 transition-transform duration-500">01</span>
|
||||||
|
</div>
|
||||||
|
<div class="col-span-10 md:col-span-4 relative overflow-hidden">
|
||||||
|
<h3 class="text-3xl md:text-5xl font-bold text-white uppercase tracking-tighter group-hover:text-brand-accent transition-colors duration-300">Compositing</h3>
|
||||||
|
<!-- Reveal Swipe Effect -->
|
||||||
|
<div class="absolute inset-0 bg-brand-accent transform scale-x-0 group-hover:scale-x-100 transition-transform duration-500 origin-left mix-blend-difference pointer-events-none opacity-0 group-hover:opacity-100"></div>
|
||||||
|
</div>
|
||||||
|
<div class="col-span-12 md:col-span-5 text-slate-400 font-mono text-xs md:text-sm tracking-wide group-hover:text-white transition-colors duration-300">
|
||||||
|
Nuke/NukeX • ComfyUI • After Effects • Photoshop
|
||||||
|
</div>
|
||||||
|
<div class="col-span-6 md:col-span-2 text-right hidden md:block">
|
||||||
|
<span class="inline-block px-3 py-1 border border-brand-accent/50 text-brand-accent text-[10px] font-bold uppercase tracking-widest bg-brand-accent/5">Expert</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- AI/ML -->
|
<!-- Row 2: 3D Generalist -->
|
||||||
<div class="animate-on-scroll slide-up stagger-3">
|
<div class="skill-row group relative grid grid-cols-12 gap-4 py-10 border-b border-white/10 items-center transition-colors duration-300 hover:border-brand-accent/30" data-image="3d">
|
||||||
<h3 class="text-base font-bold text-white uppercase mb-6 flex items-center gap-3 tracking-wide">
|
<div class="col-span-2 md:col-span-1 text-brand-accent font-mono text-sm relative overflow-hidden">
|
||||||
<i data-lucide="cpu" class="w-4 h-4 text-brand-accent"></i>
|
<span class="block group-hover:-translate-y-full transition-transform duration-500">02</span>
|
||||||
AI/ML Integration
|
<span class="absolute top-0 left-0 translate-y-full group-hover:translate-y-0 transition-transform duration-500">02</span>
|
||||||
</h3>
|
</div>
|
||||||
<div class="flex flex-wrap gap-2">
|
<div class="col-span-10 md:col-span-4 relative overflow-hidden">
|
||||||
<span class="skill-tag bg-brand-accent/10 border-brand-accent/40 text-brand-accent hover:bg-brand-accent/20">Stable Diffusion</span>
|
<h3 class="text-3xl md:text-5xl font-bold text-white uppercase tracking-tighter group-hover:text-brand-accent transition-colors duration-300">3D Generalist</h3>
|
||||||
<span class="skill-tag">LoRA Training</span>
|
</div>
|
||||||
<span class="skill-tag">Dataset Prep</span>
|
<div class="col-span-12 md:col-span-5 text-slate-400 font-mono text-xs md:text-sm tracking-wide group-hover:text-white transition-colors duration-300">
|
||||||
<span class="skill-tag">Synthetic Data</span>
|
Houdini • Blender • Maya • USD • Solaris
|
||||||
<span class="skill-tag">Prompt Engineering</span>
|
</div>
|
||||||
|
<div class="col-span-6 md:col-span-2 text-right hidden md:block">
|
||||||
|
<span class="inline-block px-3 py-1 border border-white/20 text-slate-300 text-[10px] font-bold uppercase tracking-widest">Advanced</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Dev -->
|
<!-- Row 3: AI / ML -->
|
||||||
<div class="animate-on-scroll slide-up stagger-4">
|
<div class="skill-row group relative grid grid-cols-12 gap-4 py-10 border-b border-white/10 items-center transition-colors duration-300 hover:border-brand-accent/30" data-image="ai">
|
||||||
<h3 class="text-base font-bold text-white uppercase mb-6 flex items-center gap-3 tracking-wide">
|
<div class="col-span-2 md:col-span-1 text-brand-accent font-mono text-sm relative overflow-hidden">
|
||||||
<i data-lucide="code" class="w-4 h-4 text-brand-accent"></i>
|
<span class="block group-hover:-translate-y-full transition-transform duration-500">03</span>
|
||||||
Development
|
<span class="absolute top-0 left-0 translate-y-full group-hover:translate-y-0 transition-transform duration-500">03</span>
|
||||||
</h3>
|
</div>
|
||||||
<div class="flex flex-wrap gap-2">
|
<div class="col-span-10 md:col-span-4 relative overflow-hidden">
|
||||||
<span class="skill-tag">Python</span>
|
<h3 class="text-3xl md:text-5xl font-bold text-white uppercase tracking-tighter group-hover:text-brand-accent transition-colors duration-300">AI Integration</h3>
|
||||||
<span class="skill-tag">JavaScript</span>
|
</div>
|
||||||
<span class="skill-tag">React</span>
|
<div class="col-span-12 md:col-span-5 text-slate-400 font-mono text-xs md:text-sm tracking-wide group-hover:text-white transition-colors duration-300">
|
||||||
<span class="skill-tag">Docker</span>
|
Stable Diffusion • LoRA • Datasets • Python
|
||||||
<span class="skill-tag">Linux</span>
|
</div>
|
||||||
<span class="skill-tag">Pipeline Dev</span>
|
<div class="col-span-6 md:col-span-2 text-right hidden md:block">
|
||||||
|
<span class="inline-block px-3 py-1 border border-brand-accent/50 text-brand-accent text-[10px] font-bold uppercase tracking-widest bg-brand-accent/5">Specialist</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Row 4: Development -->
|
||||||
|
<div class="skill-row group relative grid grid-cols-12 gap-4 py-10 border-b border-white/10 items-center transition-colors duration-300 hover:border-brand-accent/30" data-image="dev">
|
||||||
|
<div class="col-span-2 md:col-span-1 text-brand-accent font-mono text-sm relative overflow-hidden">
|
||||||
|
<span class="block group-hover:-translate-y-full transition-transform duration-500">04</span>
|
||||||
|
<span class="absolute top-0 left-0 translate-y-full group-hover:translate-y-0 transition-transform duration-500">04</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col-span-10 md:col-span-4 relative overflow-hidden">
|
||||||
|
<h3 class="text-3xl md:text-5xl font-bold text-white uppercase tracking-tighter group-hover:text-brand-accent transition-colors duration-300">Development</h3>
|
||||||
|
</div>
|
||||||
|
<div class="col-span-12 md:col-span-5 text-slate-400 font-mono text-xs md:text-sm tracking-wide group-hover:text-white transition-colors duration-300">
|
||||||
|
Python • React • Docker • Linux • Pipeline
|
||||||
|
</div>
|
||||||
|
<div class="col-span-6 md:col-span-2 text-right hidden md:block">
|
||||||
|
<span class="inline-block px-3 py-1 border border-white/20 text-slate-300 text-[10px] font-bold uppercase tracking-widest">Full Stack</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@ -7,6 +7,14 @@ heroImage: '../../assets/blog-placeholder-1.jpg'
|
|||||||
|
|
||||||
In summer 2024, Biohazard VFX partnered with Stinkfilms and director Felix Brady to create a visually striking brand film for G-Star Raw's Olympics campaign. This project pushed our team of 60+ artists to deliver high-end CG environments while pioneering new AI/ML integration workflows.
|
In summer 2024, Biohazard VFX partnered with Stinkfilms and director Felix Brady to create a visually striking brand film for G-Star Raw's Olympics campaign. This project pushed our team of 60+ artists to deliver high-end CG environments while pioneering new AI/ML integration workflows.
|
||||||
|
|
||||||
|
<div class="video-container my-10">
|
||||||
|
<video controls class="w-full border border-white/10">
|
||||||
|
<source src="/media/FF_PUFF_GStar_DC_v08_4608x3164.mp4" type="video/mp4" />
|
||||||
|
Your browser does not support the video tag.
|
||||||
|
</video>
|
||||||
|
<p class="text-slate-500 text-sm mt-3 font-mono">/// FINAL FILM</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
## The Challenge
|
## The Challenge
|
||||||
|
|
||||||
The creative brief called for expansive cityscapes and environments that would feel both futuristic and grounded in reality. The timeline was aggressive, and the scope was ambitious—exactly the kind of project we thrive on.
|
The creative brief called for expansive cityscapes and environments that would feel both futuristic and grounded in reality. The timeline was aggressive, and the scope was ambitious—exactly the kind of project we thrive on.
|
||||||
@ -43,6 +51,37 @@ Managing 60+ artists across multiple time zones required robust communication an
|
|||||||
|
|
||||||
The final film delivered on time and exceeded client expectations. The combination of traditional VFX craft with cutting-edge AI tools allowed us to achieve a level of visual complexity that would have been prohibitively expensive using traditional methods alone.
|
The final film delivered on time and exceeded client expectations. The combination of traditional VFX craft with cutting-edge AI tools allowed us to achieve a level of visual complexity that would have been prohibitively expensive using traditional methods alone.
|
||||||
|
|
||||||
|
## Shot Breakdowns
|
||||||
|
|
||||||
|
A closer look at some of the key shots and the techniques used to bring them to life.
|
||||||
|
|
||||||
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 my-10">
|
||||||
|
<div class="video-container">
|
||||||
|
<video controls class="w-full border border-white/10">
|
||||||
|
<source src="/media/GSTR_01_260_breakdown.mp4" type="video/mp4" />
|
||||||
|
</video>
|
||||||
|
<p class="text-slate-500 text-sm mt-3 font-mono">/// SHOT BREAKDOWN 01</p>
|
||||||
|
</div>
|
||||||
|
<div class="video-container">
|
||||||
|
<video controls class="w-full border border-white/10">
|
||||||
|
<source src="/media/GSTR_03_070_v10_breakdown_v01.mp4" type="video/mp4" />
|
||||||
|
</video>
|
||||||
|
<p class="text-slate-500 text-sm mt-3 font-mono">/// SHOT BREAKDOWN 02</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
## Making Of
|
||||||
|
|
||||||
|
Go behind the scenes to see how the team brought this project together.
|
||||||
|
|
||||||
|
<div class="video-container my-10">
|
||||||
|
<video controls class="w-full border border-white/10">
|
||||||
|
<source src="/media/FF_PUFF_GStar_DC_Making-of_v06_H264.mp4" type="video/mp4" />
|
||||||
|
Your browser does not support the video tag.
|
||||||
|
</video>
|
||||||
|
<p class="text-slate-500 text-sm mt-3 font-mono">/// MAKING OF</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
*This project exemplifies the direction we're taking at Biohazard VFX: embracing new technology while never compromising on quality or artistic vision.*
|
*This project exemplifies the direction we're taking at Biohazard VFX: embracing new technology while never compromising on quality or artistic vision.*
|
||||||
|
|||||||
@ -9,9 +9,10 @@ import { SITE_TITLE, SITE_DESCRIPTION } from '../consts';
|
|||||||
interface Props {
|
interface Props {
|
||||||
title?: string;
|
title?: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
|
usePadding?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { title = SITE_TITLE, description = SITE_DESCRIPTION } = Astro.props;
|
const { title = SITE_TITLE, description = SITE_DESCRIPTION, usePadding = true } = Astro.props;
|
||||||
---
|
---
|
||||||
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
@ -24,7 +25,7 @@ const { title = SITE_TITLE, description = SITE_DESCRIPTION } = Astro.props;
|
|||||||
<GridOverlay />
|
<GridOverlay />
|
||||||
<Navigation />
|
<Navigation />
|
||||||
|
|
||||||
<main class="relative z-10 pt-32 lg:pt-48 pb-24 min-h-screen">
|
<main class:list={["relative z-10 min-h-screen pb-24", { "pt-32 lg:pt-48": usePadding }]}>
|
||||||
<slot />
|
<slot />
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
|
|||||||
@ -1,112 +1,287 @@
|
|||||||
---
|
---
|
||||||
import BaseLayout from '../layouts/BaseLayout.astro';
|
import BaseLayout from '../layouts/BaseLayout.astro';
|
||||||
import { SITE_TITLE, SITE_DESCRIPTION } from '../consts';
|
import { SITE_TITLE } from '../consts';
|
||||||
|
|
||||||
|
const pageTitle = `Contact | ${SITE_TITLE}`;
|
||||||
---
|
---
|
||||||
|
|
||||||
<BaseLayout title={`Contact | ${SITE_TITLE}`} description="Get in touch for collaboration or inquiries.">
|
<BaseLayout title={pageTitle} description="Get in touch for collaboration or inquiries." usePadding={false}>
|
||||||
<section class="container mx-auto px-6 lg:px-12">
|
|
||||||
<div class="mb-20 animate-on-scroll slide-up">
|
<!-- Background Grid (Optional, low opacity) -->
|
||||||
<h1 class="text-5xl md:text-7xl lg:text-8xl font-bold uppercase text-white mb-5 tracking-tighter">
|
<div class="fixed inset-0 z-0 pointer-events-none">
|
||||||
Let's <span class="text-transparent bg-clip-text bg-gradient-to-r from-brand-accent via-orange-400 to-white">Talk</span>
|
<div class="w-full h-full grid grid-cols-12 gap-4 opacity-[0.03]">
|
||||||
</h1>
|
{Array.from({ length: 12 }).map((_) => (
|
||||||
<p class="text-slate-500 font-mono text-sm tracking-wide">/// GET IN TOUCH</p>
|
<div class="h-full border-r border-white"></div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="grid grid-cols-1 lg:grid-cols-12 gap-12 lg:gap-20">
|
<section class="relative z-10 min-h-screen flex flex-col pt-32 lg:pt-48 pb-20 px-6 lg:px-12">
|
||||||
<!-- Contact Form -->
|
|
||||||
<div class="lg:col-span-7 animate-on-scroll slide-up stagger-1">
|
<!-- Page Header -->
|
||||||
<form class="space-y-8" action="#" method="POST">
|
<div class="grid grid-cols-1 lg:grid-cols-12 gap-12 mb-20 lg:mb-32 border-b border-white/10 pb-12">
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
<div class="lg:col-span-8">
|
||||||
<div class="space-y-3">
|
<h1 class="text-6xl md:text-8xl lg:text-9xl font-bold uppercase tracking-tighter leading-[0.85] text-white mb-8">
|
||||||
<label for="name" class="text-xs font-bold uppercase tracking-widest text-slate-500 block">Name</label>
|
<span class="block animate-on-scroll slide-up">Project</span>
|
||||||
|
<span class="block text-brand-accent animate-on-scroll slide-up stagger-1">Inquiry</span>
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<div class="lg:col-span-4 flex flex-col justify-end">
|
||||||
|
<p class="font-mono text-sm text-slate-400 leading-relaxed mb-8 border-l border-brand-accent pl-6 animate-on-scroll fade-in stagger-2">
|
||||||
|
Available for freelance commissions and studio collaborations.
|
||||||
|
Currently booking Q3 2026.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid grid-cols-1 lg:grid-cols-12 gap-12 lg:gap-24 flex-grow">
|
||||||
|
|
||||||
|
<!-- Left Column: Contact Form -->
|
||||||
|
<div class="lg:col-span-7 animate-on-scroll slide-up stagger-3">
|
||||||
|
<div class="mb-8 flex items-center gap-3">
|
||||||
|
<span class="w-2 h-2 bg-brand-accent rounded-full animate-pulse"></span>
|
||||||
|
<span class="font-mono text-xs text-brand-accent uppercase tracking-widest">Transmission Uplink</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form class="space-y-12" action="#" method="POST">
|
||||||
|
<div class="group relative">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
id="name"
|
id="name"
|
||||||
name="name"
|
name="name"
|
||||||
placeholder="Your Name"
|
class="block w-full bg-transparent border-b border-white/20 py-4 text-xl text-white focus:outline-none focus:border-brand-accent transition-colors duration-300 placeholder-transparent peer"
|
||||||
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"
|
placeholder="Name"
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
|
<label for="name" class="absolute left-0 top-4 text-slate-500 text-sm font-mono uppercase tracking-widest transition-all duration-300 peer-focus:-top-6 peer-focus:text-xs peer-focus:text-brand-accent peer-valid:-top-6 peer-valid:text-xs peer-valid:text-slate-400 pointer-events-none">
|
||||||
|
/// Identification Name
|
||||||
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="space-y-3">
|
|
||||||
<label for="email" class="text-xs font-bold uppercase tracking-widest text-slate-500 block">Email</label>
|
<div class="group relative">
|
||||||
<input
|
<input
|
||||||
type="email"
|
type="email"
|
||||||
id="email"
|
id="email"
|
||||||
name="email"
|
name="email"
|
||||||
placeholder="name@example.com"
|
class="block w-full bg-transparent border-b border-white/20 py-4 text-xl text-white focus:outline-none focus:border-brand-accent transition-colors duration-300 placeholder-transparent peer"
|
||||||
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"
|
placeholder="Email"
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
|
<label for="email" class="absolute left-0 top-4 text-slate-500 text-sm font-mono uppercase tracking-widest transition-all duration-300 peer-focus:-top-6 peer-focus:text-xs peer-focus:text-brand-accent peer-valid:-top-6 peer-valid:text-xs peer-valid:text-slate-400 pointer-events-none">
|
||||||
|
/// Return Address
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Custom Dropdown -->
|
||||||
|
<div class="group relative" id="custom-select">
|
||||||
|
<input type="hidden" name="subject" id="subject-input" required>
|
||||||
|
|
||||||
|
<button type="button" id="select-trigger" class="block w-full text-left bg-transparent border-b border-white/20 py-4 text-xl text-white focus:outline-none focus:border-brand-accent transition-colors duration-300 flex justify-between items-center group-hover:border-white/40">
|
||||||
|
<span id="select-value" class="text-transparent">Select</span> <!-- Hidden placeholder text to keep height -->
|
||||||
|
<div class="text-brand-accent transform transition-transform duration-300" id="select-arrow">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6"/></svg>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<label id="select-label" class="absolute left-0 top-4 text-slate-500 text-sm font-mono uppercase tracking-widest transition-all duration-300 pointer-events-none">
|
||||||
|
/// Subject Protocol
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<!-- Dropdown Menu -->
|
||||||
|
<div id="select-options" class="absolute left-0 top-full w-full bg-brand-dark border border-white/20 shadow-2xl z-50 hidden opacity-0 transform translate-y-2 transition-all duration-200 origin-top mt-2">
|
||||||
|
<div class="p-1">
|
||||||
|
<div class="option px-5 py-4 hover:bg-white/5 cursor-pointer text-white text-lg font-light transition-colors flex items-center gap-3 group/option" data-value="project">
|
||||||
|
<span class="w-1.5 h-1.5 rounded-full bg-brand-accent opacity-0 group-hover/option:opacity-100 transition-opacity"></span>
|
||||||
|
New Project Commission
|
||||||
|
</div>
|
||||||
|
<div class="option px-5 py-4 hover:bg-white/5 cursor-pointer text-white text-lg font-light transition-colors flex items-center gap-3 group/option" data-value="collab">
|
||||||
|
<span class="w-1.5 h-1.5 rounded-full bg-brand-accent opacity-0 group-hover/option:opacity-100 transition-opacity"></span>
|
||||||
|
Studio Collaboration
|
||||||
|
</div>
|
||||||
|
<div class="option px-5 py-4 hover:bg-white/5 cursor-pointer text-white text-lg font-light transition-colors flex items-center gap-3 group/option" data-value="press">
|
||||||
|
<span class="w-1.5 h-1.5 rounded-full bg-brand-accent opacity-0 group-hover/option:opacity-100 transition-opacity"></span>
|
||||||
|
Press / Media
|
||||||
|
</div>
|
||||||
|
<div class="option px-5 py-4 hover:bg-white/5 cursor-pointer text-white text-lg font-light transition-colors flex items-center gap-3 group/option" data-value="other">
|
||||||
|
<span class="w-1.5 h-1.5 rounded-full bg-brand-accent opacity-0 group-hover/option:opacity-100 transition-opacity"></span>
|
||||||
|
Other Inquiry
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="space-y-3">
|
<div class="group relative">
|
||||||
<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/[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>
|
|
||||||
<option value="freelance" class="bg-brand-dark">Freelance Availability</option>
|
|
||||||
<option value="other" class="bg-brand-dark">Other</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="space-y-3">
|
|
||||||
<label for="message" class="text-xs font-bold uppercase tracking-widest text-slate-500 block">Message</label>
|
|
||||||
<textarea
|
<textarea
|
||||||
id="message"
|
id="message"
|
||||||
name="message"
|
name="message"
|
||||||
rows="6"
|
rows="4"
|
||||||
placeholder="Tell me about your project..."
|
class="block w-full bg-transparent border-b border-white/20 py-4 text-xl text-white focus:outline-none focus:border-brand-accent transition-colors duration-300 placeholder-transparent peer 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"
|
placeholder="Message"
|
||||||
required
|
required
|
||||||
></textarea>
|
></textarea>
|
||||||
|
<label for="message" class="absolute left-0 top-4 text-slate-500 text-sm font-mono uppercase tracking-widest transition-all duration-300 peer-focus:-top-6 peer-focus:text-xs peer-focus:text-brand-accent peer-valid:-top-6 peer-valid:text-xs peer-valid:text-slate-400 pointer-events-none">
|
||||||
|
/// Message Data
|
||||||
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="pt-6">
|
<div class="pt-8">
|
||||||
<button type="submit" class="btn-primary group relative overflow-hidden">
|
<button type="submit" class="group relative inline-flex items-center justify-center gap-4 px-8 py-4 bg-transparent border border-white/20 hover:border-brand-accent hover:bg-brand-accent/5 transition-all duration-300">
|
||||||
<span class="relative z-10">Send Message</span>
|
<span class="font-mono text-xs font-bold uppercase tracking-widest text-white group-hover:text-brand-accent transition-colors">Transmit Message</span>
|
||||||
<div class="absolute inset-0 bg-white opacity-0 group-hover:opacity-20 transition-opacity duration-300"></div>
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="text-slate-500 group-hover:text-brand-accent group-hover:translate-x-1 transition-all"><line x1="22" y1="2" x2="11" y2="13"/><polygon points="22 2 15 22 11 13 2 9 22 2"/></svg>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Sidebar Info -->
|
<!-- Right Column: System Status / Info -->
|
||||||
<div class="lg:col-span-5 space-y-12 animate-on-scroll slide-left stagger-2">
|
<div class="lg:col-span-5 space-y-16 animate-on-scroll slide-left stagger-4">
|
||||||
<div>
|
|
||||||
<h3 class="text-xs font-bold uppercase tracking-widest text-slate-500 mb-6">Contact Info</h3>
|
<!-- Data Block 1 -->
|
||||||
<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">
|
<div class="relative pl-6 border-l border-white/10">
|
||||||
|
<h3 class="font-mono text-xs text-slate-500 uppercase tracking-widest mb-4">Direct Link</h3>
|
||||||
|
<a href="mailto:nicholai@nicholai.work" class="text-2xl md:text-3xl font-bold text-white hover:text-brand-accent transition-colors break-all">
|
||||||
nicholai@nicholai.work
|
nicholai@nicholai.work
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<!-- Data Block 2 -->
|
||||||
<h3 class="text-xs font-bold uppercase tracking-widest text-slate-500 mb-6">Location</h3>
|
<div class="relative pl-6 border-l border-white/10">
|
||||||
<p class="text-base lg:text-lg text-slate-300 leading-relaxed font-light">
|
<h3 class="font-mono text-xs text-slate-500 uppercase tracking-widest mb-4">Coordinates</h3>
|
||||||
Colorado Springs, CO<br/>
|
<p class="text-xl text-white font-light">
|
||||||
Mountain Standard Time (MST)
|
Colorado Springs, CO<br>
|
||||||
|
<span class="text-slate-500 text-base">United States</span>
|
||||||
</p>
|
</p>
|
||||||
|
<div class="mt-4 font-mono text-xs text-brand-accent">
|
||||||
|
38.8339° N, 104.8214° W
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="pt-10 border-t border-white/10">
|
<!-- Data Block 3 -->
|
||||||
<h3 class="text-xs font-bold uppercase tracking-widest text-slate-500 mb-6">Availability</h3>
|
<div class="relative pl-6 border-l border-white/10">
|
||||||
<div class="flex items-center gap-3 mb-4">
|
<h3 class="font-mono text-xs text-slate-500 uppercase tracking-widest mb-4">Social Feed</h3>
|
||||||
<span class="relative flex h-2.5 w-2.5">
|
<ul class="space-y-4">
|
||||||
<span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-brand-accent opacity-75"></span>
|
<li>
|
||||||
<span class="relative inline-flex rounded-full h-2.5 w-2.5 bg-brand-accent"></span>
|
<a href="#" class="flex items-center gap-4 group">
|
||||||
</span>
|
<span class="text-slate-400 group-hover:text-white transition-colors text-lg">Instagram</span>
|
||||||
<span class="text-sm font-bold text-brand-accent uppercase tracking-wide">Open to opportunities</span>
|
<svg class="w-4 h-4 text-slate-600 group-hover:text-brand-accent transition-colors transform group-hover:translate-x-1 group-hover:-translate-y-1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="7" y1="17" x2="17" y2="7"/><polyline points="7 7 17 7 17 17"/></svg>
|
||||||
</div>
|
</a>
|
||||||
<p class="text-slate-400 text-sm leading-relaxed font-light">
|
</li>
|
||||||
Currently accepting new projects for Q3 2026. Reach out to schedule a discovery call.
|
<li>
|
||||||
</p>
|
<a href="#" class="flex items-center gap-4 group">
|
||||||
|
<span class="text-slate-400 group-hover:text-white transition-colors text-lg">LinkedIn</span>
|
||||||
|
<svg class="w-4 h-4 text-slate-600 group-hover:text-brand-accent transition-colors transform group-hover:translate-x-1 group-hover:-translate-y-1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="7" y1="17" x2="17" y2="7"/><polyline points="7 7 17 7 17 17"/></svg>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#" class="flex items-center gap-4 group">
|
||||||
|
<span class="text-slate-400 group-hover:text-white transition-colors text-lg">Vimeo</span>
|
||||||
|
<svg class="w-4 h-4 text-slate-600 group-hover:text-brand-accent transition-colors transform group-hover:translate-x-1 group-hover:-translate-y-1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="7" y1="17" x2="17" y2="7"/><polyline points="7 7 17 7 17 17"/></svg>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
</BaseLayout>
|
</BaseLayout>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* Custom autofill styles to match dark theme */
|
||||||
|
input:-webkit-autofill,
|
||||||
|
input:-webkit-autofill:hover,
|
||||||
|
input:-webkit-autofill:focus,
|
||||||
|
textarea:-webkit-autofill,
|
||||||
|
textarea:-webkit-autofill:hover,
|
||||||
|
textarea:-webkit-autofill:focus {
|
||||||
|
-webkit-text-fill-color: white;
|
||||||
|
-webkit-box-shadow: 0 0 0px 1000px #0B0D11 inset;
|
||||||
|
transition: background-color 5000s ease-in-out 0s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Label active state */
|
||||||
|
.label-active {
|
||||||
|
top: -1.5rem !important;
|
||||||
|
font-size: 0.75rem !important;
|
||||||
|
color: #94A3B8 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dropdown open state */
|
||||||
|
.dropdown-open #select-arrow {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const selectContainer = document.getElementById('custom-select');
|
||||||
|
const selectTrigger = document.getElementById('select-trigger');
|
||||||
|
const selectOptions = document.getElementById('select-options');
|
||||||
|
const selectValue = document.getElementById('select-value');
|
||||||
|
const hiddenInput = document.getElementById('subject-input') as HTMLInputElement;
|
||||||
|
const selectLabel = document.getElementById('select-label');
|
||||||
|
const options = document.querySelectorAll('.option');
|
||||||
|
const arrow = document.getElementById('select-arrow');
|
||||||
|
|
||||||
|
if (selectTrigger && selectOptions && selectValue && hiddenInput && selectLabel) {
|
||||||
|
|
||||||
|
// Toggle Dropdown
|
||||||
|
selectTrigger.addEventListener('click', () => {
|
||||||
|
const isOpen = !selectOptions.classList.contains('hidden');
|
||||||
|
|
||||||
|
if (isOpen) {
|
||||||
|
closeDropdown();
|
||||||
|
} else {
|
||||||
|
openDropdown();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Option Selection
|
||||||
|
options.forEach(option => {
|
||||||
|
option.addEventListener('click', (e) => {
|
||||||
|
const target = e.currentTarget as HTMLElement;
|
||||||
|
const value = target.dataset.value || '';
|
||||||
|
const text = target.innerText;
|
||||||
|
|
||||||
|
// Update UI
|
||||||
|
selectValue.textContent = text;
|
||||||
|
selectValue.classList.remove('text-transparent');
|
||||||
|
selectValue.classList.add('text-white');
|
||||||
|
|
||||||
|
// Update Data
|
||||||
|
hiddenInput.value = value;
|
||||||
|
|
||||||
|
// Update Label Style
|
||||||
|
selectLabel.classList.add('label-active');
|
||||||
|
selectLabel.classList.add('text-brand-accent'); // Highlight when selected
|
||||||
|
|
||||||
|
closeDropdown();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Close clicking outside
|
||||||
|
document.addEventListener('click', (e) => {
|
||||||
|
if (selectContainer && !selectContainer.contains(e.target as Node)) {
|
||||||
|
closeDropdown();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function openDropdown() {
|
||||||
|
selectOptions?.classList.remove('hidden');
|
||||||
|
// Small delay for opacity transition
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
selectOptions?.classList.remove('opacity-0', 'translate-y-2');
|
||||||
|
});
|
||||||
|
selectContainer?.classList.add('dropdown-open');
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeDropdown() {
|
||||||
|
selectOptions?.classList.add('opacity-0', 'translate-y-2');
|
||||||
|
setTimeout(() => {
|
||||||
|
selectOptions?.classList.add('hidden');
|
||||||
|
}, 200);
|
||||||
|
selectContainer?.classList.remove('dropdown-open');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import FeaturedProject from '../components/sections/FeaturedProject.astro';
|
|||||||
import Skills from '../components/sections/Skills.astro';
|
import Skills from '../components/sections/Skills.astro';
|
||||||
---
|
---
|
||||||
|
|
||||||
<BaseLayout>
|
<BaseLayout usePadding={false}>
|
||||||
<Hero />
|
<Hero />
|
||||||
|
|
||||||
<!-- Gradient Divider -->
|
<!-- Gradient Divider -->
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user