feat: finish portfolio title, navigation, and destination effects

Add the approved name animation, rounded docking navigation, localized keyboard focus cue, unified builds card, and destination copy hierarchy.

Introduce lightweight one-shot meteors and a sun ring that repeats every three seconds at Contact. Open the email action in a separate browsing context. Preserve reduced-motion behavior and keep private handoff and visual-check artifacts out of version control.

Validation: 649 tests passed; all 20 failures in world-models and SceneCanvas reproduce on baseline 103427f. Typecheck, artifact verification, and transfer budgets passed. Client/SSR preview build passed before this commit. Existing baseline test failures remain unchanged.
This commit is contained in:
2026-09-05 22:16:42 +03:00
parent 103427f95b
commit f46131723b
31 changed files with 948 additions and 51 deletions

View File

@@ -119,7 +119,7 @@ body {
margin-block: clamp(140px, 23vh, 250px);
border-color: var(--line);
}
.portfolio-section > h2 {
:is(.portfolio-section, .project-stage__lead) > h2 {
font-size: clamp(42px, 4.7vw, 72px);
font-weight: 500;
letter-spacing: -0.055em;
@@ -498,7 +498,7 @@ body {
transform: translateY(-4px);
}
@supports (animation-timeline: view()) {
.portfolio-section > h2,
:is(.portfolio-section, .project-stage__lead) > h2,
.project-case-study__header {
animation: grand-tour-enter linear both;
animation-timeline: view();
@@ -627,7 +627,7 @@ body {
padding: 0;
background: transparent;
}
.portfolio-section > h2 {
:is(.portfolio-section, .project-stage__lead) > h2 {
font-size: 44px;
margin-block-end: 26px;
}
@@ -764,7 +764,7 @@ body {
}
@media print {
.hero-journey__content > *,
.portfolio-section > h2,
:is(.portfolio-section, .project-stage__lead) > h2,
.project-case-study__header {
animation: none !important;
}
@@ -922,7 +922,7 @@ html[data-expressway='live'] .portfolio-section[data-layout='project-stage'] {
.site-navigation a:hover {
background: rgb(158 220 226 / 8%);
}
.portfolio-section > h2 {
:is(.portfolio-section, .project-stage__lead) > h2 {
text-wrap: balance;
}
.project-case-study {
@@ -970,7 +970,7 @@ html[data-expressway='live'] .portfolio-section[data-layout='project-stage'] {
measure these headings. Reveal opacity alone, leaving their geometry stable. */
@media (prefers-reduced-motion: no-preference) {
@supports (animation-timeline: view()) {
.portfolio-section > h2 {
:is(.portfolio-section, .project-stage__lead) > h2 {
animation-name: expressway-heading;
}
}
@@ -1002,7 +1002,7 @@ html[data-expressway='live'] .portfolio-section[data-layout='project-stage'] {
}
@media (max-width: 360px) {
.portfolio-section > h2 {
:is(.portfolio-section, .project-stage__lead) > h2 {
font-size: 32px;
}
}
@@ -1024,7 +1024,7 @@ html[data-expressway='live'] .portfolio-section[data-layout='project-stage'] {
html[data-expressway='live'] .portfolio-section[data-layout='project-stage'] {
padding: 0;
}
.portfolio-section > h2 {
:is(.portfolio-section, .project-stage__lead) > h2 {
font-size: 38px;
}
.experience-record {