fix: align homepage section titles and unify download button color
- Wrap the Categories and Popular sections in the same responsive max-width container (820/1080/1180) used by Official and Latest, so all four section titles line up vertically on desktop. - Official carousel arrows: hide the arrow at the edge already reached, and snap one card per click (reveal the next/previous card fully, keeping a small peek) instead of a fixed-pixel scroll. - Show the pagination dots on desktop too (was mobile-only). - RecommendedCard download button icon: text-ark-gold -> text-white to match the file bubble / popular / video download buttons. Desktop-scoped; mobile layout unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -172,8 +172,8 @@ export function RecommendedCard({
|
||||
type="button"
|
||||
className={
|
||||
useFigmaDesign
|
||||
? "relative z-20 flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-[#191921] text-ark-gold outline-none transition hover:bg-[#22232D] active:scale-95 focus-visible:ring-2 focus-visible:ring-ark-gold/80 disabled:cursor-wait"
|
||||
: "relative z-20 shrink-0 rounded-lg p-1 text-ark-gold outline-none transition hover:bg-ark-gold/10 active:scale-95 focus-visible:ring-2 focus-visible:ring-ark-gold/80 disabled:cursor-wait"
|
||||
? "relative z-20 flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-[#191921] text-white outline-none transition hover:bg-[#22232D] active:scale-95 focus-visible:ring-2 focus-visible:ring-ark-gold/80 disabled:cursor-wait"
|
||||
: "relative z-20 shrink-0 rounded-lg p-1 text-white outline-none transition hover:bg-ark-gold/10 active:scale-95 focus-visible:ring-2 focus-visible:ring-ark-gold/80 disabled:cursor-wait"
|
||||
}
|
||||
title={isDownloading ? t("downloading") : t("download")}
|
||||
aria-label={isDownloading ? t("downloading") : t("download")}
|
||||
|
||||
@@ -196,8 +196,39 @@ export function Home() {
|
||||
};
|
||||
}, [rec.length]);
|
||||
|
||||
// Reveal one more card per click, fully, inside the arrow "lanes" (the left
|
||||
// and right padding the arrows float in) so the edge card is never half-shown
|
||||
// or tucked under an arrow.
|
||||
// - Right arrow: bring the first card clipped on the right so its RIGHT edge
|
||||
// rests just left of the right arrow.
|
||||
// - Left arrow: bring the last card clipped on the left so its LEFT edge
|
||||
// rests just right of the left arrow.
|
||||
const scrollRec = (dir: 1 | -1) => {
|
||||
recRowRef.current?.scrollBy({ left: dir * 280, behavior: "smooth" });
|
||||
const row = recRowRef.current;
|
||||
if (!row) return;
|
||||
const children = Array.from(row.children) as HTMLElement[];
|
||||
if (children.length === 0) return;
|
||||
const rowLeft = row.getBoundingClientRect().left;
|
||||
const style = getComputedStyle(row);
|
||||
const padLeft = parseFloat(style.paddingLeft) || 0;
|
||||
const padRight = parseFloat(style.paddingRight) || 0;
|
||||
const epsilon = 2;
|
||||
let delta: number;
|
||||
if (dir === 1) {
|
||||
const laneRight = row.clientWidth - padRight;
|
||||
const next = children
|
||||
.map((c) => c.getBoundingClientRect().right - rowLeft)
|
||||
.find((right) => right > laneRight + epsilon);
|
||||
delta = next !== undefined ? next - laneRight : 0;
|
||||
} else {
|
||||
const lefts = children
|
||||
.map((c) => c.getBoundingClientRect().left - rowLeft)
|
||||
.filter((left) => left < padLeft - epsilon);
|
||||
delta = lefts.length ? lefts[lefts.length - 1] - padLeft : -row.scrollLeft;
|
||||
}
|
||||
const maxScroll = Math.max(0, row.scrollWidth - row.clientWidth);
|
||||
const target = Math.max(0, Math.min(maxScroll, row.scrollLeft + delta));
|
||||
row.scrollTo({ left: target, behavior: "smooth" });
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
@@ -241,6 +272,7 @@ export function Home() {
|
||||
|
||||
<Reveal delay={0}>
|
||||
<section id="categories" className="scroll-mt-16 md:scroll-mt-24">
|
||||
<div className="mx-auto max-w-full md:max-w-[820px] lg:max-w-[1080px] xl:max-w-[1180px]">
|
||||
<div className="px-4 md:px-0">
|
||||
<SectionHeader
|
||||
title={t("categorySection")}
|
||||
@@ -331,6 +363,7 @@ export function Home() {
|
||||
</Reveal>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</Reveal>
|
||||
|
||||
@@ -358,7 +391,7 @@ export function Home() {
|
||||
))}
|
||||
</div>
|
||||
<div
|
||||
className="flex h-[30px] items-center justify-center gap-1.5 md:hidden"
|
||||
className="flex h-[30px] items-center justify-center gap-1.5"
|
||||
aria-label="Recommended pagination"
|
||||
>
|
||||
{Array.from({ length: recommendedDotCount }).map((_, index) => (
|
||||
@@ -439,15 +472,17 @@ export function Home() {
|
||||
{hasPopular ? (
|
||||
<Reveal>
|
||||
<section id="popular" className="scroll-mt-16 md:scroll-mt-24">
|
||||
<div className="px-4 md:px-0">
|
||||
<SectionHeader
|
||||
title={t("popularSection")}
|
||||
viewAllTo="/browse?sort=popular"
|
||||
viewAllLabel={t("viewAll")}
|
||||
/>
|
||||
</div>
|
||||
<div className="mt-2.5 md:mt-7">
|
||||
<PopularRankList posts={popularPosts} categories={cats} />
|
||||
<div className="mx-auto max-w-full md:max-w-[820px] lg:max-w-[1080px] xl:max-w-[1180px]">
|
||||
<div className="px-4 md:px-0">
|
||||
<SectionHeader
|
||||
title={t("popularSection")}
|
||||
viewAllTo="/browse?sort=popular"
|
||||
viewAllLabel={t("viewAll")}
|
||||
/>
|
||||
</div>
|
||||
<div className="mt-2.5 md:mt-7">
|
||||
<PopularRankList posts={popularPosts} categories={cats} />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</Reveal>
|
||||
|
||||
Reference in New Issue
Block a user