Files
Emil_Shanayev_Resume/components/hero.module.css
T
EmilandClaude Sonnet 5 b5ffc67a82
Deploy to GitHub Pages / build (push) Canceled after 0s
Deploy to GitHub Pages / deploy (push) Canceled after 0s
Redesign the resume site as a 3D-editor viewport
New design: studio backdrop with a perspective floor and X/Z axis lines, an
orientation gizmo that orbits on scroll, Bricolage Grotesque and Instrument
Sans (bundled, no build-time network). Projects are laid out as plates by a
row planner that keeps every row full for any count; a demo image from the
repo root is shown when present, otherwise a generated voxel sculpture.
Text and projects still come live from Gitea.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XtcZtnG4GQA1d6mW5PNrS9
2026-09-20 21:37:35 +03:00

192 lines
4.0 KiB
CSS

.hero {
--sway: 0deg;
position: relative;
isolation: isolate;
display: flex;
flex-direction: column;
min-height: min(100svh, 1000px);
overflow: clip;
background: linear-gradient(180deg, #f5f7fa 0%, #e6e9ee 100%);
}
/* The floor is a stage of its own below the text, so the grid never runs through the copy at any window height. */
.stage {
position: relative;
flex: 1;
min-height: 260px;
overflow: hidden;
background: linear-gradient(180deg, #d8dde4 0%, var(--studio-deep) 100%);
border-top: 1px solid rgba(21, 24, 29, 0.2);
}
.stage::after {
content: '';
position: absolute;
inset: auto 0 0 0;
height: 45%;
background: linear-gradient(180deg, transparent, var(--paper));
}
.floor {
position: absolute;
inset: 0;
perspective: 620px;
perspective-origin: 50% 0;
animation: open 1.7s cubic-bezier(0.2, 0.7, 0.2, 1) 0.1s both;
}
.plane {
position: absolute;
left: -70%;
right: -70%;
top: 0;
height: 300%;
transform-origin: 50% 0;
transform: rotateX(76deg) rotateZ(var(--sway));
background-image:
linear-gradient(to right, rgba(21, 24, 29, 0.2) 1px, transparent 1px),
linear-gradient(to bottom, rgba(21, 24, 29, 0.2) 1px, transparent 1px);
background-size: 80px 80px;
background-position: center top;
-webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 18%, #000 100%);
mask-image: linear-gradient(to bottom, transparent 0%, #000 18%, #000 100%);
}
/* The red X axis crosses the floor; the blue Z axis runs into the distance, like the axes of a 3D viewport. */
.plane::before,
.plane::after {
content: '';
position: absolute;
}
.plane::before {
left: 0;
right: 0;
top: 240px;
height: 3px;
background: var(--x);
}
.plane::after {
top: 0;
bottom: 0;
left: calc(50% - 1.5px);
width: 3px;
background: var(--z);
}
.content {
position: relative;
width: var(--shell);
margin: 0 auto;
padding: 136px 0 72px;
}
.status {
display: inline-flex;
align-items: center;
gap: 10px;
max-width: 100%;
padding: 8px 16px 8px 13px;
border-radius: 999px;
background: rgba(255, 255, 255, 0.72);
box-shadow: inset 0 0 0 1px var(--line);
font-size: 15px;
font-weight: 500;
line-height: 1.35;
}
.dot {
flex: none;
width: 9px;
height: 9px;
border-radius: 50%;
background: var(--y);
box-shadow: 0 0 0 4px rgba(90, 163, 0, 0.2);
}
.name {
margin: 30px 0 0 -0.045em;
font: 800 clamp(56px, 12.6vw, 204px) / 0.88 var(--font-head);
letter-spacing: -0.048em;
}
.role {
margin-top: 22px;
font: 500 clamp(22px, 2.7vw, 38px) / 1.15 var(--font-head);
letter-spacing: -0.022em;
}
.bio {
max-width: 58ch;
margin-top: 44px;
font-size: 19px;
line-height: 1.62;
color: rgba(21, 24, 29, 0.88);
}
.actions {
display: flex;
flex-wrap: wrap;
gap: 12px;
margin-top: 32px;
}
.button {
padding: 14px 24px;
border-radius: var(--radius-control);
font: 600 16px/1.2 var(--font-body);
text-decoration: none;
transition: background-color 0.2s, color 0.2s, box-shadow 0.2s;
}
.primary {
background: var(--ink);
color: var(--paper);
}
.primary:hover {
background: var(--z);
}
.secondary {
box-shadow: inset 0 0 0 1.5px var(--ink);
}
.secondary:hover {
background: var(--ink);
color: var(--paper);
}
/* One orchestrated moment on load: the floor opens out from the Z axis while the text settles in. */
.status,
.name,
.role,
.bio,
.actions {
animation: rise 0.9s cubic-bezier(0.2, 0.7, 0.2, 1) both;
}
.name { animation-delay: 0.06s; }
.role { animation-delay: 0.16s; }
.bio { animation-delay: 0.26s; }
.actions { animation-delay: 0.34s; }
@keyframes rise {
from { opacity: 0; transform: translateY(16px); }
to { opacity: 1; transform: none; }
}
@keyframes open {
from { clip-path: inset(0 50% 0 50%); }
to { clip-path: inset(0 0 0 0); }
}
@media (max-width: 760px) {
.content { padding: 112px 0 72px; }
.bio { margin-top: 32px; font-size: 18px; }
.stage { min-height: 200px; }
.plane::before { top: 170px; }
.plane { background-size: 56px 56px; }
}