<section class="vb-build" aria-labelledby="vb-build-heading">
<!--
CONTENT
Team
Person
Photo
Role
Name
Heading
Title
Subtitle
-->
<div class="vb-build__sticky">
<div class="vb-build__world">
<div class="vb-build__tiles" aria-hidden="true"></div>
<div class="vb-build__people" aria-label="Team">
<div class="vb-build__person" aria-label="Team member">
<div class="vb-build__frame">
<img class="vb-build__photo" src="https://static.tildacdn.com/tild3637-6261-4063-a432-623130353930/Team_1.jpg" alt="Sarah Chen" draggable="false">
</div>
<div class="vb-build__pill">
<span class="vb-build__pill-role">Head of Design</span>
<span class="vb-build__pill-name">Sarah Chen</span>
</div>
</div>
<div class="vb-build__person" aria-label="Team member">
<div class="vb-build__frame">
<img class="vb-build__photo" src="https://static.tildacdn.com/tild3336-6264-4834-a664-303966363366/Team_4.jpg" alt="Marcus Webb" draggable="false">
</div>
<div class="vb-build__pill">
<span class="vb-build__pill-role">Creative Director</span>
<span class="vb-build__pill-name">Marcus Webb</span>
</div>
</div>
<div class="vb-build__person" aria-label="Team member">
<div class="vb-build__frame">
<img class="vb-build__photo" src="https://static.tildacdn.com/tild3536-3963-4863-b936-613834366161/Team_2.jpg" alt="Lena Park" draggable="false">
</div>
<div class="vb-build__pill">
<span class="vb-build__pill-role">Chief Executive Officer</span>
<span class="vb-build__pill-name">Lena Park</span>
</div>
</div>
<div class="vb-build__person" aria-label="Team member">
<div class="vb-build__frame">
<img class="vb-build__photo" src="https://static.tildacdn.com/tild6533-6364-4139-b539-626136666633/Team_28.jpg" alt="Daniel Torres" draggable="false">
</div>
<div class="vb-build__pill">
<span class="vb-build__pill-role">Lead Engineer</span>
<span class="vb-build__pill-name">Daniel Torres</span>
</div>
</div>
</div>
<div class="vb-build__heading-block" id="vb-build-heading" aria-label="Heading">
<h2 class="vb-build__headline">Our Team</h2>
<p class="vb-build__subtitle">The people who make it happen</p>
</div>
</div>
<div class="vb-build__scroll-hint" aria-hidden="true">↓</div>
</div>
<style>
.vb-build,
.vb-build * {
box-sizing: border-box;
}
.vb-build input,
.vb-build textarea,
.vb-build select {
font: inherit;
}
.vb-build {
position: relative;
height: 360vh;
margin: 0;
padding: 0;
font-family: Arial, Helvetica, sans-serif;
}
.vb-build__sticky {
position: sticky;
top: 0;
height: 100vh;
overflow: clip;
perspective: 1600px;
perspective-origin: 50% 44%;
background: #0f1013;
}
.vb-build__world {
position: absolute;
inset: 0;
transform-style: preserve-3d;
}
.vb-build.vb-build--preview {
height: auto !important;
min-height: 0;
}
.vb-build.vb-build--preview
.vb-build__sticky {
position: relative;
top: auto;
height: clamp(620px, 62vw, 820px);
min-height: 620px;
overflow: hidden;
}
.vb-build__tiles {
position: absolute;
inset: -30%;
background-image:
url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='156' height='156'%3E%3Crect x='7' y='7' width='142' height='142' rx='26' ry='26' fill='none' stroke='rgba(255%2C255%2C255%2C0.06)' stroke-width='1'/%3E%3C/svg%3E"),
radial-gradient(
ellipse 74% 64% at 50% 50%,
rgba(255,255,255,0) 32%,
rgba(15,16,19,0.54) 100%
);
background-size:
156px 156px,
100% 100%;
transform-origin: 50% 50%;
will-change:
transform,
opacity;
pointer-events: none;
}
.vb-build__people {
position: absolute;
top: 40%;
left: 50%;
width: 0;
height: 0;
transform-style: preserve-3d;
}
.vb-build__person {
position: absolute;
width: 0;
height: 0;
opacity: 0;
z-index: 2;
transform-style: preserve-3d;
will-change:
transform,
opacity;
}
.vb-build__frame {
position: absolute;
top: 0;
left: 0;
width: 172px;
padding: 9px;
border-radius: 24px;
background:
linear-gradient(
150deg,
rgba(255,255,255,0.98),
rgba(243,245,249,0.95) 45%,
rgba(224,228,236,0.92)
);
box-shadow:
inset 0 1px 0 rgba(255,255,255,0.92),
inset 0 -2px 6px rgba(25,28,36,0.10),
0 20px 44px rgba(0,0,0,0.22),
0 0 0 1px rgba(255,255,255,0.20);
transform:
translate(-50%,-50%);
}
.vb-build__photo {
display: block;
width: 154px;
height: 154px;
border-radius: 16px;
object-fit: cover;
object-position: 50% 30%;
}
.vb-build__pill {
position: absolute;
top: 0;
left: 0;
z-index: 10;
display: flex;
flex-direction: column;
align-items: center;
padding:
10px 18px;
border-radius:
999px;
background:
linear-gradient(
180deg,
rgba(255,255,255,0.96),
rgba(239,242,247,0.92)
);
-webkit-backdrop-filter:
blur(12px);
backdrop-filter:
blur(12px);
box-shadow:
inset 0 1px 0 rgba(255,255,255,0.94),
0 12px 28px rgba(0,0,0,0.18),
0 0 0 1px rgba(255,255,255,0.24);
white-space: nowrap;
opacity: 0;
transform:
translate(-50%,-50%)
scale(0.2);
transform-origin:
50% 50%;
will-change:
transform,
opacity;
}
.vb-build__pill-role {
font-size: 14px;
font-weight: 600;
line-height: 1.2;
color: #0e0e10;
}
.vb-build__pill-name {
margin-top: 2px;
font-size: 12px;
line-height: 1.2;
color: #6e6e76;
}
.vb-build__heading-block {
position: absolute;
left: 0;
bottom: 12%;
width: 100%;
text-align: center;
transform-style: preserve-3d;
will-change: transform;
pointer-events: auto;
}
.vb-build__headline {
margin: 0;
padding: 0;
font-size:
clamp(54px,11.5vw,168px);
font-weight: 400;
line-height: 0.92;
letter-spacing: -0.055em;
background:
linear-gradient(
180deg,
#ffffff 0%,
#d9ddea 55%,
#7e8598 100%
);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
text-wrap: balance;
}
.vb-build__subtitle {
margin:
16px 0 0;
font-size:
clamp(10px,1vw,13px);
letter-spacing: 0.32em;
text-transform: uppercase;
color: #9aa2b3;
}
.vb-build__scroll-hint {
position: absolute;
left: 50%;
bottom: 28px;
z-index: 100;
font-size: 20px;
color: #9aa2b3;
opacity: 1;
transform:
translateX(-50%);
transition:
opacity 0.4s;
animation:
vb-bounce
1.6s
ease-in-out
infinite;
pointer-events: none;
}
@keyframes vb-bounce {
0%,
100% {
transform:
translateX(-50%)
translateY(0);
}
50% {
transform:
translateX(-50%)
translateY(5px);
}
}
@media (max-width: 768px) {
.vb-build {
height: auto;
background: #0f1013;
}
.vb-build__sticky {
position: relative;
top: auto;
height: auto;
min-height: 0;
overflow: visible;
perspective: none;
padding:
80px 20px 60px;
}
.vb-build__topbar {
position: absolute;
top: 0;
padding:
16px 20px;
font-size: 13px;
}
.vb-build__world {
position: relative;
inset: auto;
display: flex;
flex-direction: column;
align-items: center;
gap: 0;
transform:
none !important;
transform-style:
flat;
}
.vb-build__tiles {
display: none;
}
.vb-build__heading-block {
position: relative;
left: auto;
bottom: auto;
order: -1;
width: 100%;
margin-bottom: 36px;
transform:
none !important;
pointer-events: auto;
}
.vb-build__headline {
font-size:
clamp(38px,10vw,64px);
-webkit-text-fill-color:
transparent;
}
.vb-build__subtitle {
margin-top: 10px;
font-size: 10px;
letter-spacing: 0.2em;
}
.vb-build__people {
position: relative;
top: auto;
left: auto;
display: flex;
flex-direction: column;
align-items: center;
gap: 20px;
width: 100%;
height: auto;
transform:
none !important;
}
.vb-build__person {
position: relative;
display: flex;
align-items: center;
gap: 16px;
width: 100%;
max-width: 360px;
height: auto;
padding: 16px;
border-radius: 20px;
background:
linear-gradient(
150deg,
#252830,
#1b1d23 45%,
#121318
);
box-shadow:
0 12px 28px rgba(0,0,0,0.24);
opacity:
1 !important;
transform:
none !important;
}
.vb-build__frame {
position: relative;
top: auto;
left: auto;
flex-shrink: 0;
width: 90px;
padding: 4px;
border-radius: 14px;
background:
linear-gradient(
150deg,
rgba(255,255,255,0.98),
rgba(243,245,249,0.95) 45%,
rgba(224,228,236,0.92)
);
box-shadow:
0 8px 18px rgba(0,0,0,0.16);
transform: none;
}
.vb-build__photo {
width: 82px;
height: 82px;
border-radius: 10px;
}
.vb-build__pill {
position: relative;
top: auto;
left: auto;
flex: 1;
align-items: flex-start;
padding: 0;
border-radius: 0;
background: none;
-webkit-backdrop-filter:
none;
backdrop-filter:
none;
box-shadow:
none;
white-space:
normal;
opacity:
1 !important;
transform:
none !important;
}
.vb-build__pill-role {
font-size: 18px;
font-weight: 700;
color: #f5f7fb;
}
.vb-build__pill-name {
margin-top: 3px;
font-size: 13px;
color: #b6bac4;
}
.vb-build__scroll-hint {
display: none;
}
}
@media (prefers-reduced-motion: reduce) {
.vb-build {
height: auto;
}
.vb-build__sticky {
position: relative;
height: 100vh;
min-height: 600px;
}
.vb-build__person {
opacity:
1 !important;
}
.vb-build__pill {
opacity:
1 !important;
}
.vb-build__scroll-hint {
display: none;
}
}
</style>
<script>
(function () {
'use strict';
var script =
document.currentScript;
var section =
script &&
script.closest
? script.closest('.vb-build')
: null;
if (!section) {
var sections =
document.querySelectorAll(
'.vb-build'
);
section =
sections.length
? sections[sections.length - 1]
: null;
}
if (
!section ||
section.classList.contains(
'vb-build-ready'
)
) {
return;
}
var sticky =
section.querySelector(
'.vb-build__sticky'
);
var world =
section.querySelector(
'.vb-build__world'
);
var tiles =
section.querySelector(
'.vb-build__tiles'
);
var peopleWrap =
section.querySelector(
'.vb-build__people'
);
var headingBlock =
section.querySelector(
'.vb-build__heading-block'
);
var scrollHint =
section.querySelector(
'.vb-build__scroll-hint'
);
if (
!sticky ||
!world ||
!tiles ||
!peopleWrap ||
!headingBlock
) {
return;
}
var persons = [];
var raw = 0;
var progress = 0;
var pointerX = 0;
var pointerY = 0;
var smoothPointerX = 0;
var smoothPointerY = 0;
var frame = null;
var running = false;
var headingNaturalY = null;
var mutationTimer = null;
var reducedMotion =
window.matchMedia(
'(prefers-reduced-motion: reduce)'
);
function clamp01(
value
) {
return value < 0
? 0
: value > 1
? 1
: value;
}
function lerp(
from,
to,
amount
) {
return from +
(
to -
from
) *
amount;
}
function segment(
value,
start,
end
) {
return clamp01(
(
value -
start
) /
(
end -
start
)
);
}
function easeInOut(
value
) {
return value < 0.5
? 2 * value * value
: -1 +
(
4 -
2 * value
) *
value;
}
function easeOut(
value
) {
var inverse =
1 -
value;
return 1 -
inverse *
inverse *
inverse;
}
function easeBack(
value
) {
var amount =
1.7;
var shifted =
value -
1;
return 1 +
(
amount +
1
) *
shifted *
shifted *
shifted +
amount *
shifted *
shifted;
}
function isMobile() {
return window.innerWidth <= 768;
}
function isPreview() {
try {
return window.self !== window.top;
}
catch (error) {
return true;
}
}
var previewMode =
isPreview();
if (
previewMode
) {
section.classList.add(
'vb-build--preview'
);
}
function getMainScale(
width,
count
) {
var viewportScale = 1;
if (width < 900) {
viewportScale = 0.82;
}
else if (width < 1100) {
viewportScale = 0.90;
}
var countScale = 1;
if (count === 5) {
countScale = 0.90;
}
else if (count === 6) {
countScale = 0.82;
}
else if (count === 7) {
countScale = 0.75;
}
else if (count >= 8) {
countScale = Math.max(
0.62,
0.75 -
(
count -
7
) *
0.045
);
}
return viewportScale *
countScale;
}
function getPillScale(
width,
count
) {
return getMainScale(
width,
count
);
}
function getExplodeScale(
width
) {
if (width < 900) {
return 0.62;
}
if (width < 1100) {
return 0.78;
}
return 1;
}
function getLanding(
index,
count,
width
) {
if (count <= 1) {
return {
x: 0,
y: -22,
angle: 0,
pillX: 0,
pillY: 112
};
}
var maxSpan =
Math.min(
width * 0.90,
980
);
var spacing =
Math.min(
250,
maxSpan /
(
count -
1
)
);
var centeredIndex =
index -
(
count -
1
) /
2;
var normalized =
centeredIndex /
Math.max(
1,
(
count -
1
) /
2
);
var x =
centeredIndex *
spacing;
var y =
34 -
(
76 *
(
1 -
Math.abs(
normalized
)
)
);
y +=
(
index % 2 === 0
? -4
: 4
);
var angle =
normalized *
5.5 +
(
index % 2 === 0
? -1.5
: 1.5
);
var pillY = 112;
return {
x: x,
y: y,
angle: angle,
pillX: 0,
pillY: pillY
};
}
function getEntrance(
index,
count,
width,
height
) {
var normalized =
count <= 1
? 0
: index /
(
count -
1
);
var side =
index % 2 === 0
? -1
: 1;
var verticalSide =
index % 4 < 2
? -1
: 1;
return {
x:
side *
(
width *
0.70 +
180
),
y:
verticalSide *
(
height *
0.54 +
120
) +
(
normalized -
0.5
) *
120,
rotateY:
side *
-72,
rotateZ:
side *
40
};
}
function getPersonState(
element,
index,
count,
width,
height
) {
return {
element: element,
pill:
element.querySelector(
'.vb-build__pill'
),
landing:
getLanding(
index,
count,
width
),
entrance:
getEntrance(
index,
count,
width,
height
)
};
}
function refreshPeople() {
var elements =
Array.prototype.slice.call(
peopleWrap.querySelectorAll(
'.vb-build__person'
)
);
var count =
elements.length;
var width =
sticky.offsetWidth ||
window.innerWidth;
var height =
sticky.offsetHeight ||
window.innerHeight;
persons =
elements.map(
function (
element,
index
) {
return getPersonState(
element,
index,
count,
width,
height
);
}
);
elements.forEach(
function (
element,
index
) {
var middle =
(
count -
1
) /
2;
element.style.zIndex =
String(
20 -
Math.round(
Math.abs(
index -
middle
)
)
);
}
);
if (
previewMode
) {
section.style.height =
'';
}
else if (
!isMobile()
) {
var sectionHeight =
Math.max(
250,
220 +
count *
12
);
section.style.height =
sectionHeight +
'vh';
}
else {
section.style.height =
'';
}
headingNaturalY = null;
if (
reducedMotion.matches ||
previewMode
) {
applyFinishedState();
}
}
function applyFinishedState() {
if (
isMobile()
) {
return;
}
var width =
sticky.offsetWidth ||
window.innerWidth;
var count =
persons.length;
var mainScale =
getMainScale(
width,
count
);
var pillScale =
getPillScale(
width,
count
);
persons.forEach(
function (person) {
var landing =
person.landing;
person.element.style.opacity =
'1';
person.element.style.transform =
'translate(' +
(
landing.x *
mainScale
).toFixed(2) +
'px,' +
(
landing.y *
mainScale
).toFixed(2) +
'px) scale(' +
mainScale.toFixed(4) +
') rotate(' +
landing.angle.toFixed(2) +
'deg)';
if (
person.pill
) {
person.pill.style.opacity =
'1';
person.pill.style.transform =
'translate(calc(-50% + ' +
(
landing.pillX *
pillScale
).toFixed(2) +
'px), calc(-50% + ' +
(
landing.pillY *
pillScale
).toFixed(2) +
'px)) scale(1)';
}
}
);
tiles.style.transform =
'scale(1)';
tiles.style.opacity =
'1';
headingBlock.style.transform =
'none';
}
function measureHeading() {
var previous =
headingBlock.style.transform;
headingBlock.style.transform =
'none';
var stickyRect =
sticky.getBoundingClientRect();
var headingRect =
headingBlock.getBoundingClientRect();
headingNaturalY =
(
headingRect.top +
headingRect.height /
2
) -
(
stickyRect.top +
stickyRect.height /
2
);
headingBlock.style.transform =
previous;
}
function onPointerMove(
event
) {
var rect =
sticky.getBoundingClientRect();
pointerX =
(
(
event.clientX -
rect.left
) /
rect.width -
0.5
) *
2;
pointerY =
(
(
event.clientY -
rect.top
) /
rect.height -
0.5
) *
2;
}
function render() {
var sectionRect =
section.getBoundingClientRect();
var viewportHeight =
window.innerHeight;
var denominator =
Math.max(
1,
section.offsetHeight -
viewportHeight
);
raw =
clamp01(
-sectionRect.top /
denominator
);
progress +=
(
raw -
progress
) *
0.09;
smoothPointerX +=
(
pointerX -
smoothPointerX
) *
0.08;
smoothPointerY +=
(
pointerY -
smoothPointerY
) *
0.08;
var p =
progress *
0.72;
var width =
sticky.offsetWidth;
var height =
sticky.offsetHeight;
var count =
persons.length;
var mainScale =
getMainScale(
width,
count
);
var pillScale =
getPillScale(
width,
count
);
var explodeScale =
getExplodeScale(
width
);
if (
headingNaturalY === null
) {
measureHeading();
}
var typeProgress =
easeInOut(
segment(
p,
0,
0.30
)
);
var headingScale =
lerp(
3.1,
1,
typeProgress
);
var headingY =
lerp(
-headingNaturalY,
0,
typeProgress
);
var tileScale =
lerp(
1.4,
1,
typeProgress
);
var tileOpacity =
lerp(
0.25,
1,
typeProgress
);
if (
scrollHint
) {
scrollHint.style.opacity =
p > 0.04
? '0'
: '1';
}
var explode = 0;
tiles.style.transform =
'scale(' +
tileScale.toFixed(4) +
') translateZ(' +
(
-320 *
explode
).toFixed(2) +
'px)';
tiles.style.opacity =
tileOpacity.toFixed(4);
var cardStart =
0.16;
var cardEnd =
0.50;
var cardSpan =
Math.max(
0.18,
Math.min(
0.26,
0.36 /
Math.max(
1,
count
) +
0.16
)
);
var cardUsable =
Math.max(
0,
(
cardEnd -
cardStart
) -
cardSpan
);
persons.forEach(
function (
person,
index
) {
var start =
cardStart +
(
count > 1
? index /
(
count -
1
) *
cardUsable
: 0
);
var cardProgress =
clamp01(
(
p -
start
) /
cardSpan
);
var cardBack =
easeBack(
cardProgress
);
var cardOut =
easeOut(
cardProgress
);
var landing =
getLanding(
index,
count,
width
);
var entrance =
getEntrance(
index,
count,
width,
height
);
person.landing =
landing;
person.entrance =
entrance;
var x =
lerp(
entrance.x,
landing.x,
cardBack
) *
mainScale;
var y =
lerp(
entrance.y,
landing.y,
cardBack
) *
mainScale;
var z =
lerp(
700,
0,
cardOut
) +
(
60 +
22 *
index
) *
explode;
var scale =
lerp(
2.4,
1,
cardOut
) *
mainScale;
var rotateY =
lerp(
entrance.rotateY,
0,
cardOut
);
var rotateZ =
lerp(
entrance.rotateZ,
landing.angle,
cardOut
);
person.element.style.opacity =
clamp01(
cardProgress *
5
).toFixed(4);
person.element.style.transform =
'translate(' +
x.toFixed(2) +
'px,' +
y.toFixed(2) +
'px) ' +
'translateZ(' +
z.toFixed(2) +
'px) ' +
'scale(' +
scale.toFixed(4) +
') ' +
'rotateY(' +
rotateY.toFixed(2) +
'deg) ' +
'rotate(' +
rotateZ.toFixed(2) +
'deg)';
}
);
var pillStart =
0.52;
var pillEnd =
0.72;
var pillSpan =
Math.max(
0.08,
Math.min(
0.12,
0.20 /
Math.max(
1,
count
) +
0.07
)
);
var pillUsable =
Math.max(
0,
(
pillEnd -
pillStart
) -
pillSpan
);
var pillZ =
190 *
explode;
persons.forEach(
function (
person,
index
) {
if (
!person.pill
) {
return;
}
var start =
pillStart +
(
count > 1
? index /
(
count -
1
) *
pillUsable
: 0
);
var pillProgress =
clamp01(
(
p -
start
) /
pillSpan
);
var pillBack =
easeBack(
pillProgress
);
var landing =
person.landing;
var pillX =
lerp(
0,
landing.pillX *
pillScale,
pillBack
);
var pillY =
lerp(
0,
landing.pillY *
pillScale,
pillBack
);
var pillScaleValue =
lerp(
0.2,
1,
pillBack
);
person.pill.style.opacity =
pillProgress > 0.01
? '1'
: '0';
person.pill.style.transform =
'translate(calc(-50% + ' +
pillX.toFixed(2) +
'px), calc(-50% + ' +
pillY.toFixed(2) +
'px)) ' +
'translateZ(' +
pillZ.toFixed(2) +
'px) ' +
'scale(' +
pillScaleValue.toFixed(4) +
')';
}
);
var headingZ =
120 *
explode;
headingBlock.style.transform =
'translateY(' +
(
headingY +
40 *
explode
).toFixed(2) +
'px) translateZ(' +
headingZ.toFixed(2) +
'px) scale(' +
headingScale.toFixed(4) +
')';
world.style.transform =
'none';
frame =
requestAnimationFrame(
render
);
}
function start() {
if (
running ||
isMobile() ||
reducedMotion.matches ||
previewMode
) {
return;
}
running = true;
frame =
requestAnimationFrame(
render
);
}
function stop() {
if (!running) {
return;
}
running = false;
if (frame) {
cancelAnimationFrame(
frame
);
frame = null;
}
}
var observer =
new IntersectionObserver(
function (entries) {
entries.forEach(
function (entry) {
if (
entry.isIntersecting
) {
start();
}
else {
stop();
}
}
);
},
{
threshold: 0
}
);
observer.observe(
section
);
document.addEventListener(
'visibilitychange',
function () {
if (
document.hidden
) {
stop();
}
else {
var rect =
section.getBoundingClientRect();
if (
rect.bottom > 0 &&
rect.top < window.innerHeight
) {
start();
}
}
}
);
var resizeObserver =
new ResizeObserver(
function () {
headingNaturalY = null;
refreshPeople();
}
);
resizeObserver.observe(
sticky
);
var peopleObserver =
new MutationObserver(
function () {
clearTimeout(
mutationTimer
);
mutationTimer =
setTimeout(
refreshPeople,
40
);
}
);
peopleObserver.observe(
peopleWrap,
{
childList: true
}
);
section.classList.add(
'vb-build-ready'
);
refreshPeople();
if (
reducedMotion.matches ||
previewMode
) {
applyFinishedState();
}
else {
start();
}
})();
</script>
</section>