style: switch Films rows to responsive grid matching Algos layout
ContentRow and Browse My List sections now use a responsive CSS grid instead of fixed-width cards in a horizontal scroll: - Mobile: 2 columns grid - md (768px): 3 columns - lg (1024px): 4 columns - xl (1280px): 5 columns - 2xl (1536px): 6 columns Cards fill the available width at every breakpoint, matching the Algos/Trending tab grid layout for visual consistency. Scroll nav buttons hidden on desktop (grid doesn't scroll). Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -5,27 +5,27 @@
|
||||
</h2>
|
||||
|
||||
<div class="relative group">
|
||||
<!-- Scroll Left Button -->
|
||||
<!-- Scroll Left Button (mobile only — desktop uses grid) -->
|
||||
<button
|
||||
v-if="canScrollLeft"
|
||||
@click="scrollLeft"
|
||||
class="scroll-nav-button hidden md:flex items-center justify-center absolute left-0 top-0 bottom-0 z-10 w-12 transition-all"
|
||||
class="scroll-nav-button md:hidden flex items-center justify-center absolute left-0 top-0 bottom-0 z-10 w-12 transition-all"
|
||||
>
|
||||
<svg class="w-8 h-8" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"/>
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<!-- Content Slider -->
|
||||
<!-- Content Slider (mobile: horizontal scroll, desktop: responsive grid) -->
|
||||
<div
|
||||
ref="sliderRef"
|
||||
class="flex gap-8 overflow-x-auto overflow-y-visible scrollbar-hide scroll-smooth px-4 pt-6 pb-8"
|
||||
class="content-slider px-4 pt-6 pb-8"
|
||||
@scroll="handleScroll"
|
||||
>
|
||||
<div
|
||||
v-for="content in contents"
|
||||
:key="content.id"
|
||||
class="content-card flex-shrink-0 w-[200px] card-desktop-6 group/card cursor-pointer"
|
||||
class="content-card group/card cursor-pointer"
|
||||
@click="$emit('content-click', content)"
|
||||
>
|
||||
<div class="glass-card rounded-lg p-1.5 transition-all duration-300 relative">
|
||||
@@ -54,11 +54,11 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Scroll Right Button -->
|
||||
<!-- Scroll Right Button (mobile only — desktop uses grid) -->
|
||||
<button
|
||||
v-if="canScrollRight"
|
||||
@click="scrollRight"
|
||||
class="scroll-nav-button hidden md:flex items-center justify-center absolute right-0 top-0 bottom-0 z-10 w-12 transition-all"
|
||||
class="scroll-nav-button md:hidden flex items-center justify-center absolute right-0 top-0 bottom-0 z-10 w-12 transition-all"
|
||||
>
|
||||
<svg class="w-8 h-8" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/>
|
||||
@@ -129,21 +129,68 @@ onUnmounted(() => {
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.scrollbar-hide {
|
||||
/* ── Content Slider ──
|
||||
Mobile: horizontal scroll (flex row)
|
||||
Desktop: responsive grid matching the Algos tab layout */
|
||||
.content-slider {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
overflow-x: auto;
|
||||
overflow-y: visible;
|
||||
scroll-behavior: smooth;
|
||||
-ms-overflow-style: none;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
|
||||
.scrollbar-hide::-webkit-scrollbar {
|
||||
.content-slider::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Mobile: fixed-width cards for horizontal scrolling */
|
||||
.content-slider > .content-card {
|
||||
flex-shrink: 0;
|
||||
width: 160px;
|
||||
}
|
||||
|
||||
/* Desktop: switch to responsive grid */
|
||||
@media (min-width: 768px) {
|
||||
.content-slider {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 1.5rem;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.content-slider > .content-card {
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.content-slider {
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1280px) {
|
||||
.content-slider {
|
||||
grid-template-columns: repeat(5, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1536px) {
|
||||
.content-slider {
|
||||
grid-template-columns: repeat(6, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
.content-row-title {
|
||||
background: linear-gradient(to right, #fafafa, #9ca3af);
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
letter-spacing: 0.05em; /* 5% character spacing */
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
|
||||
.scroll-nav-button {
|
||||
@@ -184,17 +231,6 @@ onUnmounted(() => {
|
||||
transform: translateY(-4px);
|
||||
}
|
||||
|
||||
/* Show exactly 6 cards on desktop.
|
||||
Total horizontal padding: section px-4 (32px) + slider px-4 (32px) = 64px.
|
||||
Gaps between 6 cards: 5 × 2rem (gap-8) = 160px.
|
||||
Card width = (viewport - 64px padding - 160px gaps) / 6 */
|
||||
@media (min-width: 768px) {
|
||||
.card-desktop-6 {
|
||||
width: calc((100vw - 14rem) / 6);
|
||||
max-width: 300px;
|
||||
}
|
||||
}
|
||||
|
||||
.social-badge {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
@@ -83,11 +83,11 @@
|
||||
<!-- Continue Watching -->
|
||||
<div v-if="continueWatching.length > 0" class="content-row">
|
||||
<h2 class="content-row-title text-xl md:text-2xl font-bold text-white mb-4 px-4 uppercase">Continue Watching</h2>
|
||||
<div class="flex gap-8 overflow-x-auto overflow-y-visible scrollbar-hide scroll-smooth px-4 pt-6 pb-8">
|
||||
<div class="browse-grid px-4 pt-6 pb-8">
|
||||
<div
|
||||
v-for="item in continueWatching"
|
||||
:key="item.content.id"
|
||||
class="content-card flex-shrink-0 w-[200px] card-desktop-6 group/card cursor-pointer"
|
||||
class="content-card group/card cursor-pointer"
|
||||
@click="handleContentClick(item.content)"
|
||||
>
|
||||
<div class="glass-card rounded-lg p-1.5 transition-all duration-300 relative">
|
||||
@@ -112,11 +112,11 @@
|
||||
<!-- Saved Films -->
|
||||
<div v-if="myListContent.length > 0" class="content-row">
|
||||
<h2 class="content-row-title text-xl md:text-2xl font-bold text-white mb-4 px-4 uppercase">Saved Films</h2>
|
||||
<div class="flex gap-8 overflow-x-auto overflow-y-visible scrollbar-hide scroll-smooth px-4 pt-6 pb-8">
|
||||
<div class="browse-grid px-4 pt-6 pb-8">
|
||||
<div
|
||||
v-for="content in myListContent"
|
||||
:key="content.id"
|
||||
class="content-card flex-shrink-0 w-[200px] card-desktop-6 group/card cursor-pointer"
|
||||
class="content-card group/card cursor-pointer"
|
||||
@click="handleContentClick(content)"
|
||||
>
|
||||
<div class="glass-card rounded-lg p-1.5 transition-all duration-300">
|
||||
@@ -138,11 +138,11 @@
|
||||
<!-- Rentals -->
|
||||
<div v-if="rentedContent.length > 0" class="content-row">
|
||||
<h2 class="content-row-title text-xl md:text-2xl font-bold text-white mb-4 px-4 uppercase">My Rentals</h2>
|
||||
<div class="flex gap-8 overflow-x-auto overflow-y-visible scrollbar-hide scroll-smooth px-4 pt-6 pb-8">
|
||||
<div class="browse-grid px-4 pt-6 pb-8">
|
||||
<div
|
||||
v-for="content in rentedContent"
|
||||
:key="content.id"
|
||||
class="content-card flex-shrink-0 w-[200px] card-desktop-6 group/card cursor-pointer"
|
||||
class="content-card group/card cursor-pointer"
|
||||
@click="handleContentClick(content)"
|
||||
>
|
||||
<div class="glass-card rounded-lg p-1.5 transition-all duration-300 relative">
|
||||
@@ -177,7 +177,7 @@
|
||||
<h2 class="content-row-title text-xl md:text-2xl font-bold text-white mb-4 px-4 uppercase">
|
||||
{{ activeAlgorithmLabel }}
|
||||
</h2>
|
||||
<div class="grid grid-cols-2 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6 gap-4 md:gap-6 lg:gap-8 px-4 pt-6 pb-8">
|
||||
<div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-4 md:gap-6 lg:gap-8 px-4 pt-6 pb-8">
|
||||
<div
|
||||
v-for="content in filteredContent"
|
||||
:key="content.id"
|
||||
@@ -585,11 +585,36 @@ watch(() => searchSelection.pendingContent, (content) => {
|
||||
transform: translateY(-4px);
|
||||
}
|
||||
|
||||
/* Show exactly 6 cards on desktop (matches ContentRow) */
|
||||
/* Browse grid — matches ContentRow responsive grid */
|
||||
.browse-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.card-desktop-6 {
|
||||
width: calc((100vw - 14rem) / 6);
|
||||
max-width: 300px;
|
||||
.browse-grid {
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 1.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.browse-grid {
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1280px) {
|
||||
.browse-grid {
|
||||
grid-template-columns: repeat(5, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1536px) {
|
||||
.browse-grid {
|
||||
grid-template-columns: repeat(6, 1fr);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user