Add logo loading screen gated on animation readiness
- Full-screen loader whose only content is the logo animating: the "B" draws in and fills, the base facets trace in, then a wave runs along them until the page is ready (pure CSS, plays before JS) - Loader gate holds the loader until GSAP + fonts and every 3D scene's first frame are ready, then waits 1s (min 1.4s total) before leaving; hard 8s limit, head-script fallback if JS never boots - Scroll reveals, SplitText and scene entry animations start only once the loader leaves, so above-the-fold entries play in view - Internal links fade the loader back in before navigating, so page changes are one seamless dark transition - No loader for no-JS or reduced-motion visitors Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
@@ -115,6 +115,137 @@ html.motion:not(.motion-fallback) [data-reveal-stagger] > * {
|
||||
margin-bottom: -0.08em;
|
||||
}
|
||||
|
||||
/* ---- Page loader (see src/components/loader) ---- */
|
||||
.page-loader {
|
||||
display: none;
|
||||
}
|
||||
|
||||
html.motion .page-loader {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
z-index: 9999;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: #0a0a0a;
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
transition:
|
||||
opacity 0.7s cubic-bezier(0.65, 0, 0.35, 1),
|
||||
visibility 0s linear 0s;
|
||||
}
|
||||
|
||||
html.motion.loader-done .page-loader {
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
pointer-events: none;
|
||||
transition:
|
||||
opacity 0.7s cubic-bezier(0.65, 0, 0.35, 1),
|
||||
visibility 0s linear 0.7s;
|
||||
}
|
||||
|
||||
html.loader-gone .page-loader * {
|
||||
animation-play-state: paused !important;
|
||||
}
|
||||
|
||||
html.motion.loader-leaving .page-loader {
|
||||
transition-duration: 0.32s, 0s;
|
||||
}
|
||||
|
||||
/* -- the logo -- */
|
||||
.page-loader-logo {
|
||||
--d0: 0.1s; /* start offset for the whole sequence */
|
||||
width: 56px;
|
||||
height: auto;
|
||||
overflow: visible;
|
||||
color: #fff;
|
||||
transition:
|
||||
opacity 0.45s ease,
|
||||
transform 0.7s cubic-bezier(0.65, 0, 0.35, 1);
|
||||
}
|
||||
|
||||
html.loader-done .page-loader-logo {
|
||||
opacity: 0;
|
||||
transform: scale(1.06);
|
||||
}
|
||||
|
||||
/* Page exits never show it. */
|
||||
html.loader-leaving .page-loader-logo {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.pl-shape {
|
||||
fill: currentColor;
|
||||
fill-opacity: 0;
|
||||
stroke: currentColor;
|
||||
stroke-width: 9;
|
||||
stroke-linejoin: round;
|
||||
stroke-dasharray: 1 1;
|
||||
stroke-dashoffset: 1;
|
||||
}
|
||||
|
||||
/* 1. the "B" draws itself in, then fills */
|
||||
.pl-letter {
|
||||
animation:
|
||||
pl-draw 1s cubic-bezier(0.65, 0, 0.35, 1) var(--d0) forwards,
|
||||
pl-fill 0.55s ease calc(var(--d0) + 0.65s) forwards;
|
||||
}
|
||||
|
||||
/* 2. the facets trace in and rise into place, left → right */
|
||||
.pl-facet .pl-shape {
|
||||
transform-box: fill-box;
|
||||
transform-origin: center;
|
||||
animation:
|
||||
pl-draw 0.6s ease-out calc(var(--d0) + 0.45s + var(--i) * 0.08s)
|
||||
forwards,
|
||||
pl-fill 0.45s ease calc(var(--d0) + 0.7s + var(--i) * 0.08s)
|
||||
forwards,
|
||||
pl-rise 0.7s cubic-bezier(0.22, 1, 0.36, 1)
|
||||
calc(var(--d0) + 0.45s + var(--i) * 0.08s) both;
|
||||
}
|
||||
|
||||
/* 3. while waiting: a signal runs along the facets */
|
||||
.pl-facet {
|
||||
transform-box: fill-box;
|
||||
transform-origin: center;
|
||||
animation: pl-wave 1.8s ease-in-out
|
||||
calc(var(--d0) + 1.35s + var(--i) * 0.11s) infinite;
|
||||
}
|
||||
|
||||
@keyframes pl-draw {
|
||||
to {
|
||||
stroke-dashoffset: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes pl-fill {
|
||||
to {
|
||||
fill-opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes pl-rise {
|
||||
from {
|
||||
transform: translateY(70px);
|
||||
}
|
||||
to {
|
||||
transform: none;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes pl-wave {
|
||||
0%,
|
||||
45%,
|
||||
100% {
|
||||
transform: none;
|
||||
color: #fff;
|
||||
}
|
||||
20% {
|
||||
transform: translateY(-46px);
|
||||
color: #34d399;
|
||||
}
|
||||
}
|
||||
|
||||
/* Hero graphics (<xl): stacked above the text; fades out downward into it */
|
||||
@media (max-width: 79.999rem) {
|
||||
.hero-graphic {
|
||||
|
||||
Reference in New Issue
Block a user