312 lines
11 KiB
HTML
312 lines
11 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en" data-current="home">
|
||
<head>
|
||
<meta charset="UTF-8" />
|
||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||
<title>Biohazard VFX | VFX Studio & Post-Production</title>
|
||
|
||
<!-- Favicons -->
|
||
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32.png" />
|
||
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16.png" />
|
||
|
||
<!-- SEO Meta -->
|
||
<meta name="description" content="Biohazard VFX is a global visual-effects studio delivering world-class VFX supervision, 3D animation, and end-to-end post-production." />
|
||
<!-- canonical -->
|
||
<link rel="canonical" href="https://biohazardvfx.com/" />
|
||
|
||
<!-- Preload critical fonts -->
|
||
<link rel="preload" href="fonts/BebasNeue-Regular.woff2" as="font" type="font/woff2" crossorigin />
|
||
<link rel="preload" href="fonts/Space_Mono/SpaceMono-Regular.ttf" as="font" type="font/ttf" crossorigin />
|
||
<meta name="robots" content="index, follow" />
|
||
|
||
<!-- Open Graph / Facebook -->
|
||
<meta property="og:type" content="website" />
|
||
<meta property="og:title" content="Biohazard VFX — Visual Effects Studio" />
|
||
<meta property="og:description" content="Global visual-effects & post-production studio delivering world-class VFX supervision, 3D animation, and finishing." />
|
||
<meta property="og:image" content="/images/Splash.jpg" />
|
||
<meta property="og:url" content="https://biohazardvfx.com/" />
|
||
|
||
<!-- Twitter -->
|
||
<meta name="twitter:card" content="summary_large_image" />
|
||
<meta name="twitter:title" content="Biohazard VFX — Visual Effects Studio" />
|
||
<meta name="twitter:description" content="Global visual-effects & post-production studio delivering world-class VFX supervision, 3D animation, and finishing." />
|
||
<meta name="twitter:image" content="/images/Splash.jpg" />
|
||
|
||
<!-- Structured Data -->
|
||
<script type="application/ld+json">
|
||
{
|
||
"@context": "https://schema.org",
|
||
"@type": "Organization",
|
||
"name": "Biohazard VFX",
|
||
"url": "https://biohazardvfx.com/",
|
||
"logo": "https://biohazardvfx.com/images/favicon-32x32.png",
|
||
"contactPoint": [{
|
||
"@type": "ContactPoint",
|
||
"email": "contact@biohazardvfx.com",
|
||
"contactType": "customer service"
|
||
}],
|
||
"sameAs": [
|
||
"https://www.instagram.com/nicholai.exe/",
|
||
"https://www.instagram.com/davaneh/",
|
||
"https://www.instagram.com/nuke_fx/"
|
||
]
|
||
}
|
||
</script>
|
||
|
||
<!-- Main stylesheet -->
|
||
<link rel="stylesheet" href="css/styles.css" />
|
||
<link rel="stylesheet" href="css/home.css" />
|
||
<!-- GLOBAL FONT-SIZE CONTROLS ---------------------->
|
||
<style id="global-font-scale">
|
||
/*
|
||
Adjust --font-scale below to make type bigger or smaller everywhere.
|
||
1 = 100% (default). 1.1 = +10%. 0.9 = −10%, etc.
|
||
*/
|
||
:root {
|
||
--font-scale: 1.0;
|
||
}
|
||
html { font-size: calc(16px * var(--font-scale)); }
|
||
</style>
|
||
<!-- END FONT-SIZE CONTROLS -->
|
||
<style>
|
||
.content-block, .section {
|
||
max-width: 1100px;
|
||
margin: 0 auto 4.5rem auto;
|
||
padding: 8vh var(--gutter-x) 6vh;
|
||
background: none;
|
||
border-radius: 0.7em;
|
||
box-sizing: border-box;
|
||
}
|
||
main.grid {
|
||
max-width: 2000px;
|
||
margin-left: auto;
|
||
margin-right: auto;
|
||
gap: 22px;
|
||
}
|
||
@media (max-width: 900px) {
|
||
.content-block, .section {
|
||
padding: 5vh 16px 3vh;
|
||
max-width: 98vw;
|
||
}
|
||
main.grid {
|
||
max-width: 98vw;
|
||
gap: 14px;
|
||
}
|
||
}
|
||
@media (max-width: 600px) {
|
||
.content-block, .section {
|
||
padding: 3vh 6px 2vh;
|
||
max-width: 100vw;
|
||
}
|
||
main.grid {
|
||
max-width: 100vw;
|
||
gap: 8px;
|
||
}
|
||
}
|
||
#projects.grid {
|
||
margin-bottom: 4.5rem;
|
||
}
|
||
#about.content-block {
|
||
margin-top: 4.5rem;
|
||
max-width: 2000px;
|
||
margin-left: auto;
|
||
margin-right: auto;
|
||
}
|
||
#team.content-block {
|
||
margin-top: 4.5rem;
|
||
max-width: 2000px;
|
||
margin-left: auto;
|
||
margin-right: auto;
|
||
}
|
||
#crew.content-block {
|
||
margin-top: 4.5rem;
|
||
max-width: 2000px;
|
||
margin-left: auto;
|
||
margin-right: auto;
|
||
}
|
||
#pipeline.section {
|
||
margin-bottom: 4.5rem;
|
||
max-width: 2000px;
|
||
margin-left: auto;
|
||
margin-right: auto;
|
||
}
|
||
footer {
|
||
margin-top: 2.5rem;
|
||
padding-bottom: 1.5rem;
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
|
||
|
||
<!-- =======================================================
|
||
NAV
|
||
======================================================= -->
|
||
<div id="nav-placeholder"></div>
|
||
|
||
<!-- HERO SECTION -->
|
||
<section id="hero" class="hero">
|
||
<video src="videos/reel.mp4" autoplay muted loop playsinline preload="metadata"></video>
|
||
</section>
|
||
|
||
<!-- =======================================================
|
||
ABOUT
|
||
======================================================= -->
|
||
|
||
<section id="about" class="content-block" data-speed="0.15">
|
||
<div class="about-content">
|
||
<!-- Content dynamically injected -->
|
||
</div>
|
||
</section>
|
||
|
||
<!-- =======================================================
|
||
PROJECT GRID (populated dynamically from /projects)
|
||
======================================================= -->
|
||
<main id="projects" class="grid" data-speed="0.1"></main>
|
||
|
||
<!-- =======================================================
|
||
TEAM SECTION (portraits)
|
||
======================================================= -->
|
||
<section id="team" class="content-block" data-speed="0.12">
|
||
<h2>Meet The Founders</h2>
|
||
<div class="team-container">
|
||
<a class="portrait" href="https://www.instagram.com/nicholai.exe/" target="_blank" aria-label="Nicholai Vogel Instagram">
|
||
<img src="images/nicholai.jpg" alt="Nicholai Vogel">
|
||
<h3>Nicholai Vogel</h3>
|
||
<p>Founder & CEO<br>VFX & CG Supervisor<br><span style="opacity:.7;font-size:.95em">"I just work here."</span></p>
|
||
</a>
|
||
<a class="portrait" href="https://www.instagram.com/davaneh/" target="_blank" aria-label="Davane Instagram">
|
||
<img src="images/davane.jpg" alt="Davane">
|
||
<h3>DAVANÉ</h3>
|
||
<p>Co-Founder & Executive Producer<br>VFX Supervisor<br><span style="opacity:.7;font-size:.95em">"The Executive"</span></p>
|
||
</a>
|
||
<a class="portrait" href="https://www.instagram.com/nuke_fx/" target="_blank" aria-label="Parth Gupta Instagram">
|
||
<img src="images/parth.jpg" alt="Parth Gupta">
|
||
<h3>Parth Gupta</h3>
|
||
<p>Co-Founder & Executive Producer<br>Comp Lead<br><span style="opacity:.7;font-size:.95em">"Hates Matchmove"</span></p>
|
||
</a>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- =======================================================
|
||
CREW COPY SECTION (text injected from written/crew.txt)
|
||
======================================================= -->
|
||
<section id="crew" class="content-block" data-speed="0.14">
|
||
<div class="crew-content"><!-- Content dynamically injected --></div>
|
||
</section>
|
||
|
||
<!-- =======================================================
|
||
Pipeline Section
|
||
=======================================================
|
||
<section id="pipeline" class="section">
|
||
<h2>PIPELINE</h2>
|
||
<div class="pipeline-content" id="pipeline-content">
|
||
</div>
|
||
</section> -->
|
||
|
||
|
||
<div class="contact-info" style="margin-top:2em;text-align:center;font-size:1em;opacity:.7;">
|
||
<p>We usually reply within 24 hours.<br>Email: <a href="mailto:contact@biohazardvfx.com">contact@biohazardvfx.com</a></p>
|
||
</div>
|
||
|
||
|
||
<!-- Main JS bundle (handles lazy-loading + data fetch) -->
|
||
<script src="js/main.js" defer></script>
|
||
<script src="js/common.js" defer></script>
|
||
<script src="js/ui.js" defer></script>
|
||
<script src="js/home.js" defer></script>
|
||
|
||
<!-- =======================================================
|
||
Social Links
|
||
======================================================= -->
|
||
<div id="socials-placeholder"></div>
|
||
|
||
<!-- =======================================================
|
||
COPYRIGHT
|
||
(static content, copyright notice)
|
||
======================================================= -->
|
||
|
||
<footer>
|
||
<p>© 2025 Biohazard VFX. All Rights Reserved.</p>
|
||
</footer>
|
||
|
||
<script>
|
||
// Inject nav fragment
|
||
fetch('fragments/nav.html')
|
||
.then(r => r.text())
|
||
.then(html => {
|
||
document.getElementById('nav-placeholder').outerHTML = html;
|
||
});
|
||
// Inject socials fragment
|
||
fetch('fragments/socials.html')
|
||
.then(r => r.text())
|
||
.then(html => {
|
||
document.getElementById('socials-placeholder').outerHTML = html;
|
||
});
|
||
// Inject pipeline blurb
|
||
fetch('written/pipeline.txt')
|
||
.then(r => r.text())
|
||
.then(txt => {
|
||
document.getElementById('pipeline-content').innerHTML = `<p>${txt}</p>`;
|
||
});
|
||
// 2. Smooth scroll navigation for anchor links
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
|
||
anchor.addEventListener('click', function(e) {
|
||
const targetId = this.getAttribute('href').slice(1);
|
||
const target = document.getElementById(targetId);
|
||
if(target) {
|
||
e.preventDefault();
|
||
target.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||
}
|
||
});
|
||
});
|
||
});
|
||
// 10. Lazy loading for all images and iframes
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
document.querySelectorAll('img, iframe').forEach(el => {
|
||
if(!el.hasAttribute('loading')) el.setAttribute('loading', 'lazy');
|
||
});
|
||
});
|
||
// 9. Accessibility: Add ARIA labels to nav links
|
||
document.querySelectorAll('header.nav nav a').forEach(link => {
|
||
if(!link.hasAttribute('aria-label')) {
|
||
link.setAttribute('aria-label', link.textContent.trim());
|
||
}
|
||
});
|
||
|
||
// 11. Parallax video effect
|
||
document.addEventListener('DOMContentLoaded',()=>{
|
||
const hero=document.getElementById('hero');
|
||
const about=document.getElementById('about');
|
||
const video=hero?.querySelector('video');
|
||
if(!hero||!about||!video) return;
|
||
|
||
const update=()=>{
|
||
const scrollY=window.scrollY;
|
||
const viewportHeight=window.innerHeight;
|
||
const aboutRect=about.getBoundingClientRect();
|
||
const aboutTop=aboutRect.top;
|
||
|
||
// Gradually fade IN gradient as we scroll: 0 when at top, 1 once About approaches hero top
|
||
const gradientOpacity = Math.max(0, Math.min(1, (viewportHeight - aboutTop) / (viewportHeight * .0125)));
|
||
hero.style.setProperty('--gradient-opacity', gradientOpacity);
|
||
|
||
// Allow the About block to slide upward and sit over the video. We let the margin become
|
||
// slightly negative for an overlapping effect once the user scrolls further.
|
||
const aboutPadding=15-(scrollY*0.03); // rem units – can go negative for overlap
|
||
about.style.marginTop=aboutPadding+'rem';
|
||
|
||
// Move video box smoothly - no position switching
|
||
const videoOffset=Math.max(0,scrollY-viewportHeight/2);
|
||
video.style.transform=`translateY(${videoOffset}px)`;
|
||
};
|
||
|
||
update();
|
||
window.addEventListener('scroll',update,{passive:true});
|
||
window.addEventListener('resize',update,{passive:true});
|
||
});
|
||
</script>
|
||
|
||
</body>
|
||
</html> |