style(detail): redesign video detail page to cinema dark ultra-minimalist layout

This commit is contained in:
nianzhibai
2026-05-21 09:22:51 +08:00
parent 21768c9d0d
commit c862fc710b
4 changed files with 399 additions and 230 deletions
+29 -8
View File
@@ -13,12 +13,21 @@ export function VideoActions({ video, onHideVideo, hideSaving }: Props) {
const [likes, setLikes] = useState(video.likes ?? 0);
const [dislikes, setDislikes] = useState(video.dislikes ?? 0);
const [bursting, setBursting] = useState(false);
const [liked, setLiked] = useState(false);
const [disliked, setDisliked] = useState(false);
async function handleLike() {
if (liked) return;
setLiked(true);
setLikes((n) => n + 1);
setBursting(true);
window.setTimeout(() => setBursting(false), 240);
if (disliked) {
setDisliked(false);
setDislikes((n) => Math.max(0, n - 1));
}
try {
const res = await fetch(
`/api/video/${encodeURIComponent(video.id)}/like`,
@@ -31,26 +40,38 @@ export function VideoActions({ video, onHideVideo, hideSaving }: Props) {
}
} catch {
setLikes((n) => Math.max(0, n - 1));
setLiked(false);
}
}
function handleDislike() {
if (disliked) return;
setDisliked(true);
setDislikes((n) => n + 1);
if (liked) {
setLiked(false);
setLikes((n) => Math.max(0, n - 1));
}
}
return (
<div className="video-actions">
<button
className={`video-actions__btn video-actions__like ${bursting ? "is-bursting" : ""}`}
className={`video-actions__btn video-actions__like ${liked ? "is-active" : ""} ${bursting ? "is-bursting" : ""}`}
onClick={handleLike}
aria-label="点赞"
>
<ThumbsUp size={14} />
· {formatCount(likes)}
<ThumbsUp size={14} fill={liked ? "currentColor" : "none"} />
{liked ? "已赞" : "点赞"} · {formatCount(likes)}
</button>
<button
className="video-actions__btn is-danger"
onClick={() => setDislikes((n) => n + 1)}
className={`video-actions__btn is-danger ${disliked ? "is-active" : ""}`}
onClick={handleDislike}
aria-label="点踩"
>
<ThumbsDown size={14} />
· {formatCount(dislikes)}
<ThumbsDown size={14} fill={disliked ? "currentColor" : "none"} />
{disliked ? "已踩" : "点踩"} · {formatCount(dislikes)}
</button>
<button
className="video-actions__btn is-danger"
@@ -58,7 +79,7 @@ export function VideoActions({ video, onHideVideo, hideSaving }: Props) {
disabled={hideSaving}
>
<EyeOff size={14} />
{hideSaving ? "隐藏中" : "不再示"}
{hideSaving ? "隐藏中" : "不再示"}
</button>
</div>
);
+54 -10
View File
@@ -1,5 +1,6 @@
import { useState } from "react";
import type { TagItem, VideoDetail } from "@/types";
import { formatCount } from "@/lib/format";
type Props = {
video: VideoDetail;
@@ -17,6 +18,7 @@ export function VideoInfoPanel({
const [editingTags, setEditingTags] = useState(false);
const [draftTags, setDraftTags] = useState<string[]>(video.tags ?? []);
const [tagError, setTagError] = useState("");
const [descCollapsed, setDescCollapsed] = useState(true);
function openTagEditor() {
setDraftTags(video.tags ?? []);
@@ -37,13 +39,28 @@ export function VideoInfoPanel({
return (
<section className="info-panel" aria-label="视频信息">
<header className="info-panel__header"></header>
<header className="info-panel__header"></header>
<div className="info-panel__body">
<div className="info-row">
<span className="info-row__label"></span>
<span className="info-row__value">{video.publishedAt}</span>
</div>
<div className="info-row">
<span className="info-row__label"></span>
<span className="info-row__value">{video.author || video.category || "影视合集"}</span>
</div>
<div className="info-row">
<span className="info-row__label"></span>
<span className="info-row__value">{formatCount(video.views)} </span>
</div>
<div className="info-row">
<span className="info-row__label"></span>
<span className="info-row__value">{video.quality || "HD 1080P"}</span>
</div>
{video.sourceLabel && (
<div className="info-row">
<span className="info-row__label"></span>
@@ -52,14 +69,13 @@ export function VideoInfoPanel({
)}
<div className="info-row">
<span className="info-row__label">/</span>
<div className="info-row__value">
{video.category || video.author || "未设置"}
</div>
<span className="info-row__label"></span>
<span className="info-row__value">{video.duration || "未知"}</span>
</div>
<div className="info-row">
<span className="info-row__label"></span>
{/* 标签行 - 满宽 */}
<div className="info-row is-tags-row">
<span className="info-row__label"></span>
<div className="info-row__value">
<div className="detail-tags">
{(video.tags ?? []).map((t) => (
@@ -69,7 +85,7 @@ export function VideoInfoPanel({
))}
{onTagsChange && (
<button className="detail-tags__edit" onClick={openTagEditor}>
</button>
)}
</div>
@@ -84,7 +100,7 @@ export function VideoInfoPanel({
onChange={() => setDraftTags(toggleTag(draftTags, tag.label))}
/>
<span>{tag.label}</span>
{typeof tag.count === "number" && <em>{tag.count}</em>}
{typeof tag.count === "number" && <em>({tag.count})</em>}
</label>
))}
</div>
@@ -92,13 +108,41 @@ export function VideoInfoPanel({
<div className="detail-tag-editor__actions">
<button onClick={() => setEditingTags(false)}></button>
<button onClick={saveTags} disabled={tagSaving}>
{tagSaving ? "保存中..." : "保存"}
{tagSaving ? "保存中..." : "保存修改"}
</button>
</div>
</div>
)}
</div>
</div>
{/* 描述行 - Collapsible */}
{video.description && (
<div
className="info-row"
style={{
gridColumn: "1 / -1",
borderTop: "1px dashed rgba(255, 255, 255, 0.06)",
paddingTop: "var(--space-4)"
}}
>
<span className="info-row__label"></span>
<div className="info-row__value" style={{ position: "relative" }}>
<p className={`description ${descCollapsed ? "is-collapsed" : ""}`} style={{ margin: 0 }}>
{video.description}
</p>
{video.description.length > 120 && (
<button
className="description-toggle"
onClick={() => setDescCollapsed(!descCollapsed)}
style={{ border: 0, padding: 0, marginTop: "6px" }}
>
{descCollapsed ? "展开全部介绍 ↓" : "收起介绍 ↑"}
</button>
)}
</div>
</div>
)}
</div>
</section>
);
+7 -1
View File
@@ -112,20 +112,26 @@ export default function VideoDetailPage() {
<div className="container page-section">
<div className="detail-layout">
<div className="detail-main" ref={detailTopRef}>
{/* 顶置影院式悬浮播放器 */}
<div className="detail-player-card">
<div className="detail-title-bar">{detail.title}</div>
<VideoPlayer
src={detail.videoSrc}
poster={detail.poster}
title={detail.title}
onFirstPlay={handleFirstPlay}
/>
</div>
{/* 动作区 */}
<div className="detail-actions-row">
<VideoActions
video={detail}
onHideVideo={handleHideVideo}
hideSaving={hideSaving}
/>
</div>
{/* 磨砂元数据展板 */}
<VideoInfoPanel
video={detail}
availableTags={tags}
+309 -211
View File
@@ -1,49 +1,53 @@
/* =========================================================
* Video detail page
* Premium Video Detail Page Styles
* Cinema dark-slate concept with borderless player floating,
* below-player bold headers, glass uploader profiles, and
* high-density horizontal recommendation items.
* ========================================================= */
.detail-layout {
display: grid;
grid-template-columns: minmax(0, 1fr) 340px;
grid-template-columns: minmax(0, 1fr) 360px;
gap: var(--space-6);
margin-top: var(--space-4);
margin-top: var(--space-5);
align-items: start;
}
.detail-main {
min-width: 0;
display: flex;
flex-direction: column;
gap: var(--space-4);
gap: var(--space-5);
}
/* =========================================================
* Player card(标题 + 视频 + 操作 一体卡片)
* Movie-Theater Floating Player Container
* ========================================================= */
.detail-player-card {
display: flex;
flex-direction: column;
background: var(--bg-surface);
border: 1px solid var(--border-subtle);
background: #000;
border: 1px solid rgba(255, 255, 255, 0.04);
border-radius: var(--radius-lg);
overflow: hidden;
box-shadow: var(--shadow-md);
box-shadow: var(--shadow-xl);
transition: box-shadow var(--transition-normal), border-color var(--transition-normal);
}
.detail-title-bar {
padding: var(--space-4) var(--space-5);
font-size: var(--font-xl);
font-weight: var(--weight-bold);
letter-spacing: -0.005em;
color: var(--text-strong);
background: var(--bg-elevated);
border-bottom: 1px solid var(--border-subtle);
.detail-player-card:hover {
border-color: rgba(255, 255, 255, 0.08);
box-shadow:
0 12px 30px rgba(0, 0, 0, 0.4),
0 30px 80px rgba(0, 0, 0, 0.6);
}
/* ----- Player ----- */
/* Video Player controls custom style */
.video-player {
position: relative;
aspect-ratio: 16 / 9;
background: #000;
overflow: hidden;
width: 100%;
}
.video-player video {
@@ -59,96 +63,91 @@
display: grid;
place-items: center;
padding: var(--space-4);
background: rgba(0, 0, 0, 0.7);
color: #fff;
font-size: var(--font-md);
text-align: center;
backdrop-filter: blur(6px);
}
/* ----- Stats ----- */
.video-stats {
display: flex;
flex-wrap: wrap;
gap: var(--space-5);
padding: var(--space-3) var(--space-5);
background: var(--bg-surface);
color: var(--text-default);
border-bottom: 1px solid var(--border-subtle);
font-size: var(--font-sm);
}
.video-stats__item {
display: inline-flex;
align-items: center;
gap: 6px;
}
.video-stats__label {
color: var(--text-faint);
}
.video-stats__value {
background: rgba(8, 9, 13, 0.85);
color: var(--text-strong);
font-weight: var(--weight-semibold);
font-variant-numeric: tabular-nums;
font-size: var(--font-md);
font-weight: var(--weight-medium);
text-align: center;
backdrop-filter: blur(8px);
-webkit-backdrop-filter: blur(8px);
z-index: 2;
}
/* ----- Action bar ----- */
/* =========================================================
* Video Action Controls Row
* ========================================================= */
.detail-actions-row {
display: flex;
align-items: center;
gap: var(--space-4);
padding-bottom: var(--space-4);
border-bottom: 1px solid var(--border-subtle);
margin-bottom: var(--space-2);
}
/* =========================================================
* Translucent Action Buttons (Likes / Dislikes / Hide)
* ========================================================= */
.video-actions {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: var(--space-2);
padding: var(--space-4) var(--space-5);
background: var(--bg-surface);
}
.video-actions__btn {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 9px 16px;
height: 38px;
padding: 0 var(--space-4);
border-radius: var(--radius-pill);
background: var(--bg-elevated);
background: rgba(255, 255, 255, 0.04);
border: 1px solid rgba(255, 255, 255, 0.08);
color: var(--text-default);
font-size: var(--font-sm);
font-weight: var(--weight-medium);
border: 1px solid var(--border-subtle);
font-weight: var(--weight-semibold);
display: inline-flex;
align-items: center;
justify-content: center;
gap: 8px;
backdrop-filter: blur(8px);
-webkit-backdrop-filter: blur(8px);
transition: all var(--transition-fast);
}
.video-actions__btn:hover:not(:disabled) {
background: var(--bg-sunken);
border-color: var(--border-default);
background: rgba(255, 255, 255, 0.09);
border-color: rgba(255, 255, 255, 0.16);
color: var(--text-strong);
}
.video-actions__btn:disabled {
opacity: 0.5;
opacity: 0.4;
cursor: not-allowed;
}
.video-actions__btn.is-active {
background: var(--accent);
color: var(--text-on-accent);
border-color: var(--accent);
}
/* Point Actions Specific Hovers */
.video-actions__like:hover:not(:disabled) {
background: var(--accent-soft);
border-color: var(--border-accent);
color: var(--accent);
box-shadow: 0 4px 12px rgba(255, 138, 60, 0.12);
}
.video-actions__btn.is-danger {
color: var(--text-default);
.video-actions__btn.is-active {
background: var(--accent-gradient);
color: var(--text-on-accent);
border-color: var(--accent);
box-shadow: 0 4px 14px var(--accent-glow);
}
.video-actions__btn.is-danger:hover {
.video-actions__btn.is-danger:hover:not(:disabled) {
background: var(--danger-soft);
border-color: rgba(241, 85, 108, 0.4);
border-color: rgba(241, 85, 108, 0.3);
color: var(--danger);
box-shadow: 0 4px 12px rgba(241, 85, 108, 0.12);
}
/* like burst */
/* Burst dynamic animation for Point Up */
.video-actions__like.is-bursting {
animation: like-burst 280ms var(--ease-out);
}
@@ -156,70 +155,91 @@
@keyframes like-burst {
0% { transform: scale(1); }
35% {
transform: scale(1.1);
background: var(--accent);
transform: scale(1.12);
background: var(--accent-gradient);
color: var(--text-on-accent);
border-color: var(--accent);
box-shadow: 0 0 0 6px var(--accent-soft);
box-shadow: 0 0 0 8px var(--accent-soft);
}
100% { transform: scale(1); }
}
/* =========================================================
* Info panel
* Glassmorphic Info Panel Box
* ========================================================= */
.info-panel {
background: var(--bg-surface);
border: 1px solid var(--border-subtle);
background: var(--glass-card);
backdrop-filter: blur(16px);
-webkit-backdrop-filter: blur(16px);
border: 1px solid var(--border-default);
border-radius: var(--radius-lg);
overflow: hidden;
box-shadow: var(--shadow-md), var(--shadow-inset);
transition: border-color var(--transition-normal);
}
.info-panel:focus-within {
border-color: rgba(255, 255, 255, 0.14);
}
.info-panel__header {
padding: var(--space-3) var(--space-5);
font-size: var(--font-md);
font-weight: var(--weight-semibold);
font-weight: var(--weight-bold);
color: var(--text-strong);
background: var(--bg-elevated);
border-bottom: 1px solid var(--border-subtle);
background: rgba(255, 255, 255, 0.02);
border-bottom: 1px solid rgba(255, 255, 255, 0.05);
display: flex;
align-items: center;
gap: 8px;
gap: 10px;
}
.info-panel__header::before {
content: "";
width: 3px;
height: 14px;
border-radius: 2px;
background: var(--accent);
border-radius: var(--radius-xs);
background: var(--accent-gradient);
}
.info-panel__body {
padding: var(--space-5);
display: grid;
gap: var(--space-4);
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: var(--space-4) var(--space-5);
}
.info-row {
display: grid;
grid-template-columns: 96px minmax(0, 1fr);
gap: var(--space-3);
font-size: var(--font-sm);
align-items: start;
display: flex;
flex-direction: column;
gap: 6px;
min-width: 0;
}
/* Span Tags row full-width */
.info-row.is-tags-row {
grid-column: 1 / -1;
margin-top: 4px;
border-top: 1px dashed rgba(255, 255, 255, 0.06);
padding-top: var(--space-4);
}
.info-row__label {
color: var(--text-faint);
font-size: var(--font-xs);
font-weight: var(--weight-medium);
letter-spacing: 0.04em;
text-transform: uppercase;
}
.info-row__value {
color: var(--text-default);
font-size: var(--font-sm);
font-weight: var(--weight-medium);
min-width: 0;
}
/* ----- Detail tag chips ----- */
/* ----- Capsule Tag Chips ----- */
.detail-tags {
display: flex;
flex-wrap: wrap;
@@ -229,72 +249,95 @@
.detail-tags .tag-chip {
height: 26px;
padding: 0 12px;
padding: 0 11px;
font-size: var(--font-xs);
border-radius: var(--radius-pill);
background: rgba(255, 255, 255, 0.03);
border: 1px solid rgba(255, 255, 255, 0.07);
color: var(--text-muted);
cursor: default;
transition: all var(--transition-fast);
}
.detail-tags .tag-chip:hover {
background: var(--bg-surface);
color: var(--text-default);
border-color: var(--border-subtle);
background: var(--accent-soft);
color: var(--accent);
border-color: var(--border-accent);
}
.detail-tags__edit {
height: 26px;
padding: 0 12px;
border: 1px dashed var(--border-default);
border: 1px dashed rgba(255, 255, 255, 0.15);
border-radius: var(--radius-pill);
background: transparent;
color: var(--text-muted);
font-size: var(--font-xs);
font-weight: var(--weight-medium);
font-weight: var(--weight-semibold);
transition: all var(--transition-fast);
}
.detail-tags__edit:hover {
border-color: var(--border-accent);
color: var(--accent);
border-style: solid;
background: var(--accent-softer);
}
/* Elegant Tag Drawer */
.detail-tag-editor {
margin-top: var(--space-3);
padding: var(--space-3);
border: 1px solid var(--border-subtle);
border-radius: var(--radius-sm);
padding: var(--space-4);
border: 1px solid var(--border-default);
border-radius: var(--radius-md);
background: var(--bg-sunken);
box-shadow: var(--shadow-inset);
}
.detail-tag-editor__grid {
display: flex;
flex-wrap: wrap;
gap: 6px;
max-height: 200px;
overflow: auto;
max-height: 180px;
overflow-y: auto;
padding-right: var(--space-2);
}
.detail-tag-editor__grid::-webkit-scrollbar {
width: 6px;
}
.detail-tag-editor__grid::-webkit-scrollbar-thumb {
background: rgba(255, 255, 255, 0.06);
border-radius: 3px;
}
.detail-tag-editor__item {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 5px 10px;
border: 1px solid var(--border-subtle);
border-radius: var(--radius-sm);
padding: 6px 12px;
border: 1px solid rgba(255, 255, 255, 0.06);
border-radius: var(--radius-pill);
background: var(--bg-surface);
color: var(--text-default);
font-size: var(--font-xs);
font-weight: var(--weight-medium);
cursor: pointer;
transition: border-color var(--transition-fast);
transition: all var(--transition-fast);
user-select: none;
}
.detail-tag-editor__item:hover {
border-color: var(--border-default);
border-color: rgba(255, 255, 255, 0.15);
background: var(--bg-elevated);
}
.detail-tag-editor__item input {
width: 14px;
height: 14px;
width: 13px;
height: 13px;
margin: 0;
accent-color: var(--accent);
cursor: pointer;
}
.detail-tag-editor__item em {
@@ -307,36 +350,40 @@
display: flex;
justify-content: flex-end;
gap: var(--space-2);
margin-top: var(--space-3);
margin-top: var(--space-4);
border-top: 1px solid rgba(255, 255, 255, 0.05);
padding-top: var(--space-3);
}
.detail-tag-editor__actions button {
padding: 7px 14px;
border-radius: var(--radius-sm);
background: var(--bg-elevated);
height: 32px;
padding: 0 14px;
border-radius: 6px;
background: rgba(255, 255, 255, 0.04);
color: var(--text-default);
font-size: var(--font-sm);
font-weight: var(--weight-medium);
border: 1px solid var(--border-subtle);
font-size: var(--font-xs);
font-weight: var(--weight-semibold);
border: 1px solid rgba(255, 255, 255, 0.08);
}
.detail-tag-editor__actions button:hover {
background: var(--bg-sunken);
border-color: var(--border-default);
background: rgba(255, 255, 255, 0.08);
border-color: rgba(255, 255, 255, 0.15);
color: var(--text-strong);
}
.detail-tag-editor__actions button:last-child {
background: var(--accent);
background: var(--accent-gradient);
border-color: var(--accent);
color: var(--text-on-accent);
}
.detail-tag-editor__actions button:last-child:hover {
filter: brightness(1.05);
filter: brightness(1.06);
}
.detail-tag-editor__actions button:disabled {
opacity: 0.5;
opacity: 0.4;
cursor: not-allowed;
}
@@ -344,78 +391,49 @@
margin-top: var(--space-2);
color: var(--danger);
font-size: var(--font-xs);
}
/* ----- Description ----- */
.description {
font-size: var(--font-sm);
line-height: var(--line-relaxed);
color: var(--text-default);
white-space: pre-wrap;
margin: 0;
}
.description.is-collapsed {
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
}
.description-toggle {
display: inline-block;
margin-top: 6px;
color: var(--accent);
font-size: var(--font-xs);
font-weight: var(--weight-medium);
}
.description-toggle:hover {
text-decoration: underline;
font-weight: var(--weight-semibold);
}
/* =========================================================
* Comments
* Unified Comments Panel (Glass style)
* ========================================================= */
.comment-panel {
background: var(--bg-surface);
border: 1px solid var(--border-subtle);
background: var(--glass-card);
backdrop-filter: blur(16px);
-webkit-backdrop-filter: blur(16px);
border: 1px solid var(--border-default);
border-radius: var(--radius-lg);
overflow: hidden;
box-shadow: var(--shadow-md), var(--shadow-inset);
}
.comment-panel__header {
padding: var(--space-3) var(--space-5);
font-size: var(--font-md);
font-weight: var(--weight-semibold);
font-weight: var(--weight-bold);
color: var(--text-strong);
background: var(--bg-elevated);
border-bottom: 1px solid var(--border-subtle);
background: rgba(255, 255, 255, 0.02);
border-bottom: 1px solid rgba(255, 255, 255, 0.05);
display: flex;
align-items: center;
gap: 8px;
gap: 10px;
}
.comment-panel__header::before {
content: "";
width: 3px;
height: 14px;
border-radius: 2px;
background: var(--accent);
border-radius: var(--radius-xs);
background: var(--accent-gradient);
}
.comment-panel__body {
padding: var(--space-3) var(--space-5) var(--space-4);
}
.comment-list {
display: flex;
flex-direction: column;
}
.comment-item {
padding: var(--space-3) 0;
border-bottom: 1px solid var(--border-subtle);
border-bottom: 1px solid rgba(255, 255, 255, 0.05);
}
.comment-item:last-child {
@@ -428,38 +446,38 @@
gap: var(--space-2);
font-size: var(--font-xs);
color: var(--text-faint);
margin-bottom: 6px;
margin-bottom: 5px;
}
.comment-item__author {
color: var(--text-strong);
font-weight: var(--weight-semibold);
font-weight: var(--weight-bold);
}
.comment-empty {
padding: var(--space-7) 0;
padding: var(--space-6) 0;
text-align: center;
color: var(--text-muted);
font-size: var(--font-sm);
}
/* =========================================================
* Recommended sidebar
* Ultimate Compact Sidebar Recommendations Overrides
* ========================================================= */
.detail-side {
min-width: 0;
display: flex;
flex-direction: column;
gap: var(--space-3);
gap: var(--space-4);
}
.detail-side__header {
display: flex;
align-items: center;
gap: 8px;
padding: 0 var(--space-2);
gap: 10px;
padding: 0 var(--space-1);
font-size: var(--font-md);
font-weight: var(--weight-semibold);
font-weight: var(--weight-bold);
color: var(--text-strong);
}
@@ -467,35 +485,112 @@
content: "";
width: 3px;
height: 14px;
border-radius: 2px;
background: var(--accent);
border-radius: var(--radius-xs);
background: var(--accent-gradient);
}
/* Convert all standard VideoCards inside detail sidebar to elegant compact items */
.detail-side__list {
display: grid;
grid-template-columns: 1fr;
display: flex;
flex-direction: column;
gap: var(--space-3);
}
/* 推荐卡每张占独立一行,但不要无限拉宽:
* - 桌面侧栏 340px 时本身就在限内
* - 1024px 以下变单列布局后限制到 360px 居中,避免变成超大卡 */
.detail-side__list .video-card {
width: 100%;
max-width: 360px;
margin: 0 auto;
width: 100% !important;
max-width: none !important;
margin: 0 !important;
padding: 0 !important;
background: transparent !important;
border: none !important;
box-shadow: none !important;
border-radius: 0 !important;
transform: none !important;
}
/* Sidebar cards hover background overlay */
.detail-side__list .video-card:hover {
background: transparent !important;
}
.detail-side__list .video-card__link {
display: grid !important;
grid-template-columns: 140px minmax(0, 1fr) !important;
grid-template-rows: auto auto !important;
gap: 4px 12px !important;
align-items: start !important;
padding: 6px !important;
border-radius: var(--radius-md) !important;
background: transparent;
transition: background var(--transition-fast);
}
.detail-side__list .video-card__link:hover {
background: rgba(255, 255, 255, 0.03) !important;
color: inherit !important;
}
.detail-side__list .thumb-frame {
grid-column: 1 !important;
grid-row: 1 / span 2 !important;
width: 140px !important;
border-radius: var(--radius-sm) !important;
box-shadow: var(--shadow-sm);
aspect-ratio: 16 / 9 !important;
}
.detail-side__list .video-title {
grid-column: 2 !important;
grid-row: 1 !important;
font-size: 12px !important;
line-height: 1.35 !important;
font-weight: var(--weight-bold) !important;
color: var(--text-strong) !important;
margin: 0 !important;
display: -webkit-box !important;
-webkit-line-clamp: 2 !important;
-webkit-box-orient: vertical !important;
overflow: hidden !important;
white-space: normal !important;
}
.detail-side__list .video-card__link:hover .video-title {
color: var(--accent) !important;
}
.detail-side__list .video-meta {
grid-column: 2 !important;
grid-row: 2 !important;
font-size: 11px !important;
color: var(--text-muted) !important;
display: flex !important;
flex-wrap: wrap !important;
align-items: center !important;
gap: 2px 6px !important;
margin: 0 !important;
}
/* =========================================================
* Responsive
* Responsive Breakpoints
* ========================================================= */
@media (max-width: 1024px) {
.detail-layout {
grid-template-columns: minmax(0, 1fr);
gap: var(--space-5);
}
.detail-side {
margin-top: var(--space-3);
margin-top: var(--space-4);
border-top: 1px solid var(--border-subtle);
padding-top: var(--space-5);
}
.detail-side__list .video-card__link {
grid-template-columns: 160px minmax(0, 1fr) !important;
}
.detail-side__list .thumb-frame {
width: 160px !important;
}
}
@@ -505,60 +600,63 @@
gap: var(--space-4);
}
.detail-title-bar {
padding: var(--space-3) var(--space-4);
font-size: var(--font-md);
.detail-title {
font-size: var(--font-lg);
line-height: 1.35;
margin-bottom: var(--space-3);
}
.video-stats {
padding: var(--space-3) var(--space-4);
gap: var(--space-3);
}
.video-stats__item {
.detail-publisher-row {
flex-direction: column;
align-items: flex-start;
gap: 2px;
gap: var(--space-3);
padding-bottom: var(--space-3);
}
.video-actions {
padding: var(--space-3) var(--space-4);
width: 100%;
overflow-x: auto;
flex-wrap: nowrap;
scrollbar-width: none;
padding-bottom: 4px;
scrollbar-width: none; /* Firefox */
}
.video-actions::-webkit-scrollbar {
display: none; /* Chrome/Safari */
}
.video-actions::-webkit-scrollbar { display: none; }
.video-actions__btn {
flex-shrink: 0;
padding: 7px 12px;
height: 34px;
padding: 0 var(--space-3);
font-size: var(--font-xs);
}
.info-panel__header,
.comment-panel__header {
padding: 10px var(--space-4);
padding: 12px var(--space-4);
font-size: var(--font-sm);
}
.info-panel__body {
padding: var(--space-4);
grid-template-columns: 1fr;
gap: var(--space-3);
}
.info-row {
grid-template-columns: 1fr;
gap: 4px;
}
.info-row__label {
font-size: var(--font-xs);
text-transform: uppercase;
letter-spacing: 0.04em;
.info-row.is-tags-row {
padding-top: var(--space-3);
}
.comment-panel__body {
padding: 0 var(--space-4) var(--space-3);
}
.detail-side__list .video-card__link {
grid-template-columns: 120px minmax(0, 1fr) !important;
}
.detail-side__list .thumb-frame {
width: 120px !important;
}
}