feat: scroll to post bubble from recommended card + back-to-top button
Some checks failed
Deploy to Frontend Servers / deploy (push) Failing after 14s
Some checks failed
Deploy to Frontend Servers / deploy (push) Failing after 14s
Recommended cards already routed to /browse#post-<id>, but the stream had no logic to scroll to the target bubble — and the post might not be paged in yet. MessageStream now resolves the #post-<id> hash, auto-loads more pages until the bubble renders, scrolls to it, and gives it a brief gold highlight. Bubbles get scroll-mt so they clear the sticky header. Also adds a global floating back-to-top button (BackToTop) mounted in PublicLayout, shown after scrolling past 400px. Bundles related staging UI work already present in the working tree. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -20,9 +20,6 @@ body {
|
||||
/* Match theme: avoid default blue accent on controls */
|
||||
:root {
|
||||
accent-color: #eeb726;
|
||||
--animate-duration: 720ms;
|
||||
--animate-delay: 0s;
|
||||
--animate-repeat: 1;
|
||||
}
|
||||
|
||||
header a,
|
||||
@@ -49,26 +46,6 @@ header button {
|
||||
}
|
||||
}
|
||||
|
||||
.ark-page-fade-in {
|
||||
animation: ark-page-fade-in 240ms ease-out both;
|
||||
}
|
||||
|
||||
@keyframes ark-page-fade-in {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.ark-page-fade-in {
|
||||
animation: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Desktop header nav: thin scrollbar when links overflow (still 單列) */
|
||||
.header-nav-scroll {
|
||||
scrollbar-width: thin;
|
||||
@@ -89,6 +66,73 @@ header button {
|
||||
box-shadow: inset 0 -2px 0 #eeb726;
|
||||
}
|
||||
|
||||
/* Reusable skeleton placeholder with a soft shimmer sweep. */
|
||||
.ark-skeleton {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
background-color: #1d1e23;
|
||||
}
|
||||
.ark-skeleton::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
transform: translateX(-100%);
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
transparent,
|
||||
rgba(255, 255, 255, 0.05),
|
||||
transparent
|
||||
);
|
||||
animation: ark-shimmer 1.5s infinite;
|
||||
}
|
||||
|
||||
@keyframes ark-shimmer {
|
||||
100% {
|
||||
transform: translateX(100%);
|
||||
}
|
||||
}
|
||||
|
||||
/* Image fade-in: add .is-loaded on the img's onLoad handler. */
|
||||
.ark-img-fade {
|
||||
opacity: 0;
|
||||
transition: opacity 0.4s ease-out;
|
||||
}
|
||||
.ark-img-fade.is-loaded {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.ark-skeleton::after {
|
||||
animation: none;
|
||||
}
|
||||
.ark-img-fade {
|
||||
opacity: 1;
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Brief gold ring pulse when a bubble is targeted via a #post-<id> deep link. */
|
||||
.ark-bubble-highlight {
|
||||
border-radius: 1rem;
|
||||
animation: ark-bubble-highlight 2s ease-out both;
|
||||
}
|
||||
|
||||
@keyframes ark-bubble-highlight {
|
||||
0%,
|
||||
35% {
|
||||
box-shadow: 0 0 0 2px rgba(238, 183, 38, 0.9);
|
||||
}
|
||||
100% {
|
||||
box-shadow: 0 0 0 2px rgba(238, 183, 38, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.ark-bubble-highlight {
|
||||
animation: none;
|
||||
}
|
||||
}
|
||||
|
||||
.message-stream-copyable-text,
|
||||
.message-stream-copyable-text * {
|
||||
-webkit-user-select: text;
|
||||
|
||||
Reference in New Issue
Block a user