feat: update background color and enhance styling for main layout and sections

This commit is contained in:
ngthanhvu
2026-07-30 05:50:10 -04:00
parent 00036a7cc2
commit bba362f856
3 changed files with 151 additions and 86 deletions
+1 -1
View File
@@ -17,7 +17,7 @@ html {
body {
min-width: 320px;
background-color: #0f111a;
background-color: #0E111A;
color: #f8fbff;
}
+4 -2
View File
@@ -1,7 +1,7 @@
import {
faArrowLeft,
faArrowUp,
faArrowTurnDown,
faArrowTrendDown,
faArrowTrendUp,
faArrowsRotate,
faBackward,
@@ -92,8 +92,8 @@ import { library } from '@fortawesome/fontawesome-svg-core'
library.add(
faArrowLeft,
faArrowUp,
faArrowTurnDown,
faArrowTrendDown,
faArrowTrendUp,
faArrowsRotate,
faBackward,
@@ -249,6 +249,7 @@ export type IconName =
| 'toggle-left'
| 'toggle-right'
| 'trash'
| 'trending-down'
| 'trending-up'
| 'tv'
| 'type'
@@ -331,6 +332,7 @@ const iconMap: Record<IconName, [string, string]> = {
'toggle-left': ['fas', 'toggle-off'],
'toggle-right': ['fas', 'toggle-on'],
'trash': ['fas', 'trash-can'],
'trending-down': ['fas', 'arrow-trend-down'],
'trending-up': ['fas', 'arrow-trend-up'],
'tv': ['fas', 'tv'],
'type': ['fas', 'font'],
+146 -83
View File
@@ -349,7 +349,7 @@ useHead({
</script>
<template>
<main class="min-h-screen overflow-hidden bg-black">
<main class="min-h-screen overflow-hidden bg-[#0E111A]">
<AppHeader />
<div v-if="hero" class="relative bg-black mt-16 md:mt-0">
@@ -614,49 +614,57 @@ useHead({
</section>
<!-- Community sections -->
<section class="rounded-2xl border border-white/20 bg-black p-5">
<section class="relative overflow-visible rounded-2xl border border-white/15 bg-[#0E111A]">
<!-- Bình luận mới -->
<div v-if="recentComments.length" class="mb-8">
<div v-if="recentComments.length" class="relative border-b border-white/10 px-5 py-5 sm:px-8 sm:py-6 lg:px-12">
<div class="mb-5 flex items-center gap-3">
<AppIcon name="message-circle" class="size-6 text-yellow-400" />
<h2 class="text-2xl font-black uppercase text-white">Bình luận mới</h2>
</div>
<div class="relative">
<div ref="commentsCarouselRef"
class="no-scrollbar flex snap-x snap-mandatory gap-4 overflow-x-auto px-4 pb-5">
<div ref="commentsCarouselRef" class="no-scrollbar flex snap-x snap-mandatory gap-4 overflow-x-auto pb-2">
<NuxtLink v-for="comment in recentComments" :key="comment.id" :to="movieLinkFromSection(comment.movie)"
class="group relative h-50 snap-start overflow-hidden rounded-2xl bg-[#181a22]
transition-all sm:min-w-60 md:min-w-65 lg:min-w-67.5
xl:min-w-72.5 2xl:min-w-77.5">
transition-all duration-800 ease-in-out sm:min-w-60 md:min-w-65 lg:min-w-67.5
xl:min-w-72.5 2xl:min-w-77.5">
<!-- Blurred background -->
<div v-if="comment.movie?.poster" class="absolute inset-0" :style="{
backgroundImage: `url(${comment.movie.poster})`,
backgroundSize: 'cover',
backgroundPosition: 'center',
filter: 'blur(8px) saturate(1.2)',
transform: 'scale(1.2)'
}" />
<div v-if="comment.movie?.poster"
class="absolute inset-0 transition-all duration-700 ease-in-out group-hover:blur-sm group-hover:saturate-150"
:style="{
backgroundImage: `url(${comment.movie.poster})`,
backgroundSize: 'cover',
backgroundPosition: 'center',
filter: 'blur(8px) saturate(1.2)',
transform: 'scale(1.2)'
}" />
<!-- Dark gradient overlay -->
<div v-if="comment.movie?.poster" class="absolute inset-0 bg-linear-to-t
from-black via-black/80 to-black/40" />
<div v-if="comment.movie?.poster">
<div class="absolute inset-0 bg-linear-to-t from-[#0E111A] via-[#0E111A]/50 to-transparent" />
<div class="absolute inset-0 bg-linear-to-t from-[#0E111A]/30 via-[#0E111A]/10 to-transparent
transition-all duration-1200 ease-[cubic-bezier(0.65,0,0.35,1)]
group-hover:from-[#0E111A]/10 group-hover:via-[#0E111A]/5" />
</div>
<!-- Content -->
<div class="relative z-10 flex h-full flex-col p-4">
<div class="relative z-10 flex h-full flex-col p-4 transition-all duration-700 ease-in-out
group-hover:shadow-[inset_0_1px_20px_rgba(255,255,255,0.03)]">
<!-- Top: Avatar + Poster -->
<div class="flex items-end justify-between">
<!-- Avatar -->
<img v-if="comment.user?.avatar" :src="comment.user.avatar" :alt="comment.user?.name" class="size-12 shrink-0 rounded-full object-cover
ring-2 ring-white/20 shadow-md mt-auto">
<img v-if="comment.user?.avatar" :src="comment.user.avatar" :alt="comment.user?.name"
class="mt-auto size-12 shrink-0 rounded-full object-cover shadow-md ring-2 ring-white/20">
<!-- Fallback Avatar -->
<div v-else class="grid size-12 shrink-0 place-items-center rounded-full
bg-linear-to-br from-yellow-400 to-orange-500
text-lg font-black text-slate-950
ring-2 ring-white/20 shadow-md mt-auto">
<div v-else class="mt-auto grid size-12 shrink-0 place-items-center rounded-full
bg-linear-to-br from-yellow-400 to-orange-500 text-lg font-black text-slate-950
shadow-md ring-2 ring-white/20">
{{ (comment.user?.name || 'A').charAt(0).toUpperCase() }}
</div>
<!-- Movie Poster -->
<div class="h-19 w-13 shrink-0 overflow-hidden
rounded-lg shadow-md ring-1 ring-white/10">
<div class="h-19 w-13 shrink-0 overflow-hidden rounded-lg shadow-md ring-1 ring-white/10">
<img v-if="comment.movie?.poster" :src="comment.movie.poster" :alt="comment.movie?.name"
class="h-full w-full object-cover">
<img v-else-if="comment.movie?.thumb" :src="comment.movie.thumb" :alt="comment.movie?.name"
@@ -664,6 +672,7 @@ useHead({
<div v-else class="h-full w-full bg-slate-700" />
</div>
</div>
<!-- User Name + Gender -->
<div class="mt-2 flex min-w-0 items-center gap-1.5">
<span class="truncate text-sm font-bold text-white">
@@ -676,23 +685,24 @@ useHead({
<AppIcon v-if="comment.user?.gender === 'other'" name="minus"
class="size-3.5 shrink-0 text-purple-400" />
</div>
<!-- Comment -->
<p class="mt-1 line-clamp-2 text-[13px] leading-relaxed text-white/60">
{{ formatCommentContent(comment.content, 180) }}
</p>
<!-- Stats -->
<div class="mt-auto flex items-center gap-5 text-xs text-white/50">
<!-- Like -->
<span class="flex items-center gap-1">
<AppIcon name="thumbs-up" class="size-3.5" />
{{ comment.likeCount ?? 0 }}
</span>
<!-- Dislike -->
<span class="flex items-center gap-1">
<AppIcon name="thumbs-down" class="size-3.5" />
{{ comment.dislikeCount ?? 0 }}
</span>
<!-- Replies -->
<span class="flex items-center gap-1">
<AppIcon name="message-square" class="size-3.5" />
{{ comment.replyCount ?? 0 }}
@@ -702,92 +712,145 @@ useHead({
</NuxtLink>
</div>
<button type="button"
class="absolute -left-5 top-1/2 z-10 grid size-10 -translate-y-1/2 place-items-center rounded-full border border-white/20 bg-black text-white backdrop-blur-sm transition hover:bg-slate-900"
@click="scrollComments('left')">
<AppIcon name="chevron-left" class="size-5" />
<!-- Carousel navigation -->
<button type="button" class="absolute -left-[4.25rem] top-1/2 z-20 hidden size-14 -translate-y-1/2 place-items-center
rounded-full border border-white/15 bg-[#11141d] text-white shadow-lg
transition hover:bg-[#181c27] lg:grid" @click="scrollComments('left')">
<AppIcon name="chevron-left" class="size-6" />
</button>
<button type="button"
class="absolute -right-5 top-1/2 z-10 grid size-10 -translate-y-1/2 place-items-center rounded-full border border-white/20 bg-black text-white backdrop-blur-sm transition hover:bg-slate-900"
@click="scrollComments('right')">
<AppIcon name="chevron-right" class="size-5" />
<button type="button" class="absolute -right-[4.25rem] top-1/2 z-20 hidden size-14 -translate-y-1/2 place-items-center
rounded-full border border-white/15 bg-[#11141d] text-white shadow-lg
transition hover:bg-[#181c27] lg:grid" @click="scrollComments('right')">
<AppIcon name="chevron-right" class="size-6" />
</button>
</div>
</div>
<!-- Top sections -->
<div class="grid gap-4 lg:grid-cols-3">
<div class="grid items-stretch lg:grid-cols-3">
<!-- Sôi nổi nhất -->
<div class="rounded-xl border border-white/20 p-4">
<div class="mb-5 flex items-center gap-3">
<AppIcon name="zap" class="size-5 text-orange-500" />
<h2 class="text-lg font-black uppercase text-white">Sôi nổi nhất</h2>
<div class="flex h-full flex-col p-5 sm:p-6 lg:border-r lg:border-white/10">
<div class="mb-3 flex items-center gap-2">
<AppIcon name="zap" class="size-4 text-orange-500" />
<h2 class="text-sm font-black uppercase text-white">
Sôi nổi nhất
</h2>
</div>
<div class="space-y-4">
<NuxtLink v-for="(movie, index) in trendingMovies" :key="`${movie.source}-${movie.slug}-trending`"
:to="movieLinkFromSection(movie)" class="group flex items-center gap-3 transition hover:opacity-80">
<span class="w-6 text-center text-lg font-black text-white">{{ index + 1 }}.</span>
<AppIcon :name="index < 2 ? 'chevron-up' : index === 2 ? 'minus' : 'chevron-down'"
:class="index < 2 ? 'text-green-400' : index === 2 ? 'text-slate-400' : 'text-red-400'"
class="size-4 shrink-0" />
<div class="grid flex-1 grid-rows-5 gap-2.5">
<NuxtLink v-for="(movie, index) in trendingMovies.slice(0, 5)"
:key="`${movie.source}-${movie.slug}-trending`" :to="movieLinkFromSection(movie)"
class="group flex min-h-12 items-center gap-2 transition hover:opacity-80">
<span class="w-5 shrink-0 text-center text-sm font-black text-white/80">
{{ index + 1 }}.
</span>
<AppIcon :name="index < 2
? 'trending-up'
: index === 2
? 'minus'
: 'trending-down'" :class="index < 2
? 'text-green-400'
: index === 2
? 'text-slate-400'
: 'text-red-400'" class="size-3.5 shrink-0" />
<img :src="movie.thumb || movie.poster" :alt="movie.name"
class="h-16 w-11 shrink-0 rounded-md object-cover ring-1 ring-white/10">
<div class="min-w-0">
<p class="truncate text-sm font-bold text-white group-hover:text-yellow-300">{{ movie.name }}</p>
<p class="truncate text-xs text-slate-400">{{ movie.originName || movie.source }}</p>
class="h-12 w-8 shrink-0 rounded object-cover ring-1 ring-white/10">
<div class="min-w-0 flex-1">
<p class="truncate text-[13px] font-bold text-white group-hover:text-yellow-300">
{{ movie.name }}
</p>
</div>
</NuxtLink>
</div>
<NuxtLink to="/phim" class="mt-5 inline-block text-sm font-semibold text-slate-400 hover:text-white">
<NuxtLink to="/phim" class="mt-3 inline-block text-xs font-semibold text-slate-400 hover:text-white">
Xem thêm
</NuxtLink>
</div>
<!-- Yêu thích nhất -->
<div class="rounded-xl border border-white/20 p-4">
<div class="mb-5 flex items-center gap-3">
<AppIcon name="heart" class="size-5 text-pink-500" />
<h2 class="text-lg font-black uppercase text-white">Yêu thích nhất</h2>
<div class="flex h-full flex-col border-t border-white/10 p-5 sm:p-6
lg:border-t-0 lg:border-r lg:border-white/10">
<div class="mb-3 flex items-center gap-2">
<AppIcon name="heart" class="size-4 text-pink-500" />
<h2 class="text-sm font-black uppercase text-white">
Yêu thích nhất
</h2>
</div>
<div class="space-y-4">
<NuxtLink v-for="(movie, index) in mostRatedMovies" :key="`${movie.source}-${movie.slug}-rated`"
:to="movieLinkFromSection(movie)" class="group flex items-center gap-3 transition hover:opacity-80">
<span class="w-6 text-center text-lg font-black text-white">{{ index + 1 }}.</span>
<AppIcon :name="index < 2 ? 'chevron-up' : index === 2 ? 'minus' : 'chevron-down'"
:class="index < 2 ? 'text-green-400' : index === 2 ? 'text-slate-400' : 'text-red-400'"
class="size-4 shrink-0" />
<div class="grid flex-1 grid-rows-5 gap-2.5">
<NuxtLink v-for="(movie, index) in mostRatedMovies.slice(0, 5)"
:key="`${movie.source}-${movie.slug}-rated`" :to="movieLinkFromSection(movie)"
class="group flex min-h-12 items-center gap-2 transition hover:opacity-80">
<span class="w-5 shrink-0 text-center text-sm font-black text-white/80">
{{ index + 1 }}.
</span>
<AppIcon :name="index < 2
? 'trending-up'
: index === 2
? 'minus'
: 'trending-down'" :class="index < 2
? 'text-green-400'
: index === 2
? 'text-slate-400'
: 'text-red-400'" class="size-3.5 shrink-0" />
<img :src="movie.thumb || movie.poster" :alt="movie.name"
class="h-16 w-11 shrink-0 rounded-md object-cover ring-1 ring-white/10">
<div class="min-w-0">
<p class="truncate text-sm font-bold text-white group-hover:text-yellow-300">{{ movie.name }}</p>
<p class="truncate text-xs text-slate-400">{{ movie.originName || movie.source }}</p>
class="h-12 w-8 shrink-0 rounded object-cover ring-1 ring-white/10">
<div class="min-w-0 flex-1">
<p class="truncate text-[13px] font-bold text-white group-hover:text-yellow-300">
{{ movie.name }}
</p>
</div>
</NuxtLink>
</div>
<NuxtLink to="/phim" class="mt-5 inline-block text-sm font-semibold text-slate-400 hover:text-white">
<NuxtLink to="/phim" class="mt-3 inline-block text-xs font-semibold text-slate-400 hover:text-white">
Xem thêm
</NuxtLink>
</div>
<!-- Thể loại hot -->
<div class="rounded-xl border border-white/20 p-4">
<div class="mb-5 flex items-center gap-3">
<AppIcon name="layers" class="size-5 text-yellow-500" />
<h2 class="text-lg font-black uppercase text-white">Thể loại hot</h2>
<div class="flex h-full flex-col border-t border-white/10 p-5 sm:p-6 lg:border-t-0">
<div class="mb-3 flex items-center gap-2">
<AppIcon name="layers" class="size-4 text-yellow-500" />
<h2 class="text-sm font-black uppercase text-white">
Thể loại hot
</h2>
</div>
<div class="space-y-4">
<NuxtLink v-for="(genre, index) in hotGenres" :key="genre.name" to="/phim"
class="group flex items-center gap-3 transition hover:opacity-80">
<span class="w-6 text-center text-lg font-black text-white">{{ index + 1 }}.</span>
<AppIcon :name="index < 2 ? 'chevron-up' : index === 2 ? 'minus' : 'chevron-down'"
:class="index < 2 ? 'text-green-400' : index === 2 ? 'text-slate-400' : 'text-red-400'"
class="size-4 shrink-0" />
<span class="rounded-lg px-4 py-1.5 text-sm font-black text-slate-950" :class="genreTagColor(index)">
{{ genre.name }}
<div class="grid flex-1 grid-rows-5 gap-2.5">
<NuxtLink v-for="(genre, index) in hotGenres.slice(0, 5)" :key="genre.name" to="/phim"
class="group flex min-h-12 items-center gap-2 transition hover:opacity-80">
<span class="w-5 shrink-0 text-center text-sm font-black text-white/80">
{{ index + 1 }}.
</span>
<AppIcon :name="index < 2
? 'trending-up'
: index === 2
? 'minus'
: 'trending-down'" :class="index < 2
? 'text-green-400'
: index === 2
? 'text-slate-400'
: 'text-red-400'" class="size-3.5 shrink-0" />
<div class="flex h-12 items-center">
<span class="rounded-xl px-4 py-2 text-[10px] font-black text-white" :class="genreTagColor(index)">
{{ genre.name }}
</span>
</div>
</NuxtLink>
</div>
<NuxtLink to="/phim" class="mt-5 inline-block text-sm font-semibold text-slate-400 hover:text-white">
<NuxtLink to="/phim" class="mt-3 inline-block text-xs font-semibold text-slate-400 hover:text-white">
Xem thêm
</NuxtLink>
</div>