homepage stuff and text animation fix

This commit is contained in:
elvira
2026-08-22 21:59:17 +03:00
parent 7677d10821
commit 45057f9083
6 changed files with 428 additions and 305 deletions
+43 -22
View File
@@ -36,6 +36,13 @@ @layer base {
color: #000;
-webkit-font-smoothing: antialiased;
}
/* Browsers don't give <button> a pointer cursor by default (unlike <a>),
and Tailwind's Preflight stopped forcing it a few versions back — so
every button sitewide needs it set explicitly, once, here. */
button:not(:disabled) {
cursor: pointer;
}
}
@keyframes back-to-top-spin {
@@ -47,15 +54,6 @@ @keyframes back-to-top-spin {
}
}
@keyframes text-flicker-in {
0%, 60% {
opacity: 0;
}
70%, 100% {
opacity: 1;
}
}
/* ═══════════════════════════════════════════════════════════════════
COMPONENTS
═══════════════════════════════════════════════════════════════════ */
@@ -302,25 +300,48 @@ @layer components {
transform: translate(0, 0);
}
/* ── Text flicker — word switches from regular to italic/bold once
its .is-visible ancestor appears; add data-text="<same word>" ── */
.text-flicker {
position: relative;
/* ── Text dance — the word itself toggles font-weight/font-style
(normal → bold+italic) three times, then stays bold+italic, once
its .is-visible ancestor appears (pair with the `appear` Stimulus
controller — data-controller="appear" data-appear-visible-class
="is-visible"); add data-text="<same word>" ── */
.text-dance {
display: inline-block;
font-weight: inherit;
font-style: normal;
}
.text-flicker::after {
/* Layout-shift guard: reserve the wider bold+italic width up front.
A zero-height, invisible line contributes its (wider)
shrink-to-fit width to the inline-block box, so the box never
has to grow once the animation starts — nothing around the word
moves. Trade-off: since the real word starts out narrower and
left-aligned, this leaves a small trailing gap after it until
the first bold+italic pulse fills the box. (A variable-font
weight axis would be a second way to smooth this out, but
Manrope ships here as separate static weight files, not a
variable font, so there's no axis to animate.) */
.text-dance::before {
content: attr(data-text);
position: absolute;
inset: 0;
font-weight: 700;
display: block;
height: 0;
overflow: hidden;
visibility: hidden;
font-weight: 800;
font-style: italic;
font-weight: extra-bold;
opacity: 0;
pointer-events: none;
}
.is-visible .text-flicker::after {
animation: text-flicker-in 0.7s ease 3 forwards;
.is-visible .text-dance {
animation: text-dance 0.8s ease 3 forwards;
animation-delay: var(--dance-delay, 0s);
}
}
/* Replayed 3 times via animation-iteration-count on .is-visible
.text-dance above — each iteration starts back at 0% (normal) and
snaps to 100% (bold+italic); forwards fill holds the final
iteration's 100% state after it ends, so the word settles there. */
@keyframes text-dance {
0%, 60% { font-weight: inherit; font-style: normal; }
70%, 100% { font-weight: 800; font-style: italic; }
}