tweak(about): scroll-synced opacity fade for paw trail, more random layout

Opacity now animates via --paw-opacity in the same scroll-driven keyframe
as the scale/rotate transform, so each print actually fades in as it
scrolls into view instead of appearing at full (low) opacity immediately
and only growing in size. Positions reworked: irregular top gaps and
non-alternating side assignment instead of a near-uniform ladder, offsets
moved from hugging the viewport edge to flanking the centered text column,
and count bumped 13 -> 15 (+15%).
This commit is contained in:
admin committed 2026-08-14 20:08:02 +02:00
1 parent d2056b8a8b
commit f29f2d3a18
2 files changed
+33 -22

No files matched your search

+8 -3
View File
@@ -219,18 +219,22 @@
}
/* Über-uns paw print trail — scattered decorative icons behind the story
text (Gitea #23) that "stamp" into place as each one scrolls into view.
Base rule sets the resting rotation/scale so the fallback (no scroll-
timeline support) still looks intentional, not broken. */
text (Gitea #23) that fade + "stamp" into place as each one scrolls into
view, opacity and scale both driven by scroll position. Base rule sets
the resting opacity/rotation/scale so the fallback (no scroll-timeline
support) still looks intentional, not broken. */
.paw-trail-icon {
opacity: var(--paw-opacity, 0.15);
transform: scale(1) rotate(var(--paw-rot, 0deg));
}
@keyframes paw-trail-reveal {
from {
opacity: 0;
transform: scale(0.4) rotate(var(--paw-rot, 0deg));
}
to {
opacity: var(--paw-opacity, 0.15);
transform: scale(1) rotate(var(--paw-rot, 0deg));
}
}
@@ -255,6 +259,7 @@
}
.paw-trail-icon {
animation: none !important;
opacity: var(--paw-opacity, 0.15) !important;
transform: scale(1) rotate(var(--paw-rot, 0deg)) !important;
}
}
+25 -19
View File
@@ -12,30 +12,35 @@ type Print = {
static?: boolean;
};
// Scattered footprint positions down the "Über uns" page — deliberately
// irregular (varied rotation/offset/size) so it reads as a trail, not a grid.
// Scattered footprint positions down the "Über uns" page — irregular gaps
// and side assignment (no strict alternation) so it reads as a trail, not
// a grid. Offsets sit closer to the centered text column than the viewport
// edge, so the trail feels like it's flanking the story, not the screen.
const PRINTS: Print[] = [
{ top: "2%", side: "right", offset: "6%", size: "h-14 w-14 sm:h-20 sm:w-20", rotate: -18, opacity: 0.15, static: true },
{ top: "10%", side: "left", offset: "5%", size: "h-9 w-9 sm:h-12 sm:w-12", rotate: 10, opacity: 0.14 },
{ top: "18%", side: "right", offset: "12%", size: "h-10 w-10 sm:h-14 sm:w-14", rotate: -6, opacity: 0.15 },
{ top: "26%", side: "left", offset: "8%", size: "h-12 w-12 sm:h-16 sm:w-16", rotate: 14, opacity: 0.16 },
{ top: "34%", side: "right", offset: "6%", size: "h-16 w-16 sm:h-24 sm:w-24", rotate: 6, opacity: 0.14 },
{ top: "42%", side: "left", offset: "12%", size: "h-9 w-9 sm:h-12 sm:w-12", rotate: -12, opacity: 0.15 },
{ top: "50%", side: "right", offset: "9%", size: "h-12 w-12 sm:h-16 sm:w-16", rotate: 18, opacity: 0.16 },
{ top: "58%", side: "left", offset: "6%", size: "h-14 w-14 sm:h-20 sm:w-20", rotate: -8, opacity: 0.14 },
{ top: "66%", side: "right", offset: "14%", size: "h-10 w-10 sm:h-14 sm:w-14", rotate: 10, opacity: 0.15 },
{ top: "74%", side: "left", offset: "9%", size: "h-12 w-12 sm:h-16 sm:w-16", rotate: -16, opacity: 0.16 },
{ top: "82%", side: "right", offset: "7%", size: "h-14 w-14 sm:h-20 sm:w-20", rotate: 12, opacity: 0.14 },
{ top: "88%", side: "left", offset: "5%", size: "h-9 w-9 sm:h-12 sm:w-12", rotate: -10, opacity: 0.15 },
{ top: "94%", side: "right", offset: "10%", size: "h-12 w-12 sm:h-16 sm:w-16", rotate: 8, opacity: 0.14 },
{ top: "1%", side: "right", offset: "18%", size: "h-14 w-14 sm:h-20 sm:w-20", rotate: -16, opacity: 0.15, static: true },
{ top: "8%", side: "left", offset: "22%", size: "h-9 w-9 sm:h-12 sm:w-12", rotate: 9, opacity: 0.14 },
{ top: "13%", side: "left", offset: "16%", size: "h-11 w-11 sm:h-14 sm:w-14", rotate: -14, opacity: 0.16 },
{ top: "21%", side: "right", offset: "26%", size: "h-9 w-9 sm:h-12 sm:w-12", rotate: 18, opacity: 0.13 },
{ top: "25%", side: "right", offset: "15%", size: "h-16 w-16 sm:h-24 sm:w-24", rotate: 4, opacity: 0.15 },
{ top: "33%", side: "left", offset: "28%", size: "h-12 w-12 sm:h-16 sm:w-16", rotate: -8, opacity: 0.16 },
{ top: "38%", side: "right", offset: "19%", size: "h-9 w-9 sm:h-12 sm:w-12", rotate: 14, opacity: 0.14 },
{ top: "46%", side: "left", offset: "17%", size: "h-14 w-14 sm:h-20 sm:w-20", rotate: -20, opacity: 0.13 },
{ top: "49%", side: "right", offset: "24%", size: "h-12 w-12 sm:h-16 sm:w-16", rotate: 10, opacity: 0.16 },
{ top: "57%", side: "left", offset: "20%", size: "h-9 w-9 sm:h-12 sm:w-12", rotate: -6, opacity: 0.15 },
{ top: "64%", side: "right", offset: "16%", size: "h-12 w-12 sm:h-16 sm:w-16", rotate: 16, opacity: 0.14 },
{ top: "70%", side: "left", offset: "25%", size: "h-14 w-14 sm:h-20 sm:w-20", rotate: -12, opacity: 0.16 },
{ top: "78%", side: "right", offset: "21%", size: "h-9 w-9 sm:h-12 sm:w-12", rotate: 7, opacity: 0.13 },
{ top: "87%", side: "left", offset: "18%", size: "h-12 w-12 sm:h-16 sm:w-16", rotate: -18, opacity: 0.15 },
{ top: "95%", side: "right", offset: "23%", size: "h-9 w-9 sm:h-12 sm:w-12", rotate: 11, opacity: 0.14 },
];
/**
* Decorative paw print trail behind the "Über uns" story content (Gitea
* #23) — pure CSS scroll-driven animation (see .paw-trail-icon in
* globals.css), so this stays a Server Component. Each print (other than
* the first, always-visible one) "stamps" into place as it scrolls into
* view instead of just sitting static.
* the first, always-visible one) fades and scales into place as it scrolls
* into view, opacity set via --paw-opacity so the keyframe can animate
* toward it instead of the print appearing at full strength immediately.
*/
export function PawPrintTrail() {
return (
@@ -47,8 +52,9 @@ export function PawPrintTrail() {
style={{
top: print.top,
[print.side]: print.offset,
opacity: print.opacity,
...(print.static ? { transform: `rotate(${print.rotate}deg)` } : { "--paw-rot": `${print.rotate}deg` }),
...(print.static
? { opacity: print.opacity, transform: `rotate(${print.rotate}deg)` }
: { "--paw-opacity": print.opacity, "--paw-rot": `${print.rotate}deg` }),
} as React.CSSProperties}
fill="currentColor"
strokeWidth={0}