Files
Emil_Shanayev_Resume/components/hero.module.css
T
EmilandClaude Sonnet 5 04c1cc5877
Deploy to GitHub Pages / build (push) Canceled after 0s
Deploy to GitHub Pages / deploy (push) Canceled after 0s
Make the resume bilingual and part of the shared site chrome
Adds a Russian version (data/resume.ru.json, default language) with an RU/EN
switch stored under the key shared with the front page and the portfolio.
The top bar becomes the site-wide one (brand, Resume, Portfolio, Gitea,
Contact, language, theme) with a second row of anchors for this page's
sections, and the fonts move to Unbounded and Onest so the three pages share
one type system. Portfolio links now point at /portfolio/.

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

221 lines
4.5 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, var(--hero-top) 0%, var(--hero-bottom) 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, var(--stage-top) 0%, var(--stage-bottom) 100%);
border-top: 1px solid var(--horizon);
}
.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, var(--grid) 1px, transparent 1px),
linear-gradient(to bottom, var(--grid) 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: var(--pill-bg);
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 var(--dot-glow);
}
.name {
margin: 30px 0 0 -0.045em;
font: 700 clamp(38px, 7.1vw, 118px) / 1 var(--font-head);
letter-spacing: -0.05em;
overflow-wrap: break-word;
}
.role {
margin-top: 22px;
font: 500 clamp(18px, 2.1vw, 30px) / 1.2 var(--font-head);
letter-spacing: -0.035em;
}
.bio {
max-width: 58ch;
margin-top: 44px;
font-size: 19px;
line-height: 1.62;
color: var(--ink-2);
}
.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: 1000px) {
.name {
font-size: clamp(44px, 12.5vw, 104px);
}
}
@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; }
}
.link {
margin-left: 10px;
padding: 14px 0;
font: 600 16px/1.2 var(--font-body);
text-decoration: underline;
text-decoration-thickness: 1.5px;
text-underline-offset: 5px;
text-decoration-color: var(--ink-line);
transition: text-decoration-color 0.2s, color 0.2s;
}
.link:hover {
color: var(--z-text);
text-decoration-color: currentColor;
}
@media (max-width: 620px) {
.link {
margin-left: 0;
}
}