dracin / static /css /app.css
adityaarta085's picture
Initial deploy to Hugging Face
a4ec82d
Raw
History Blame Contribute Delete
9.13 kB
/* ===== DramSi · Tailwind extension layer ===========================
Hanya hal yang tidak praktis di Tailwind atau perlu pseudo-element.
================================================================= */
* { -webkit-tap-highlight-color: transparent; }
html, body { overscroll-behavior-y: contain; }
::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-thumb { background: #1c1f37; border-radius: 999px; }
::-webkit-scrollbar-track { background: transparent; }
.no-scrollbar::-webkit-scrollbar { display: none; }
.no-scrollbar { -ms-overflow-style: none; scrollbar-width: none; }
/* Skeleton shimmer — Tailwind's bg-gradient + animate-shimmer */
.skeleton {
background: linear-gradient(90deg, #15172a 0%, #232744 50%, #15172a 100%);
background-size: 200% 100%;
animation: shimmer 1.4s infinite linear;
}
@keyframes shimmer {
0% { background-position: 200% 0; }
100% { background-position: -200% 0; }
}
/* Line clamp helpers (use Tailwind's line-clamp-* if @tailwindcss/line-clamp is enabled,
ini fallback yang sudah build-in di tailwind v3.3+) */
/* Vertical aspect for short drama */
.aspect-vertical {
aspect-ratio: 9 / 16;
}
/* Custom video styling */
video {
background: #000;
}
video::-webkit-media-controls-panel {
background-image: linear-gradient(transparent, rgba(0, 0, 0, .5));
}
/* Hero gradient overlay */
.hero-gradient {
background: linear-gradient(180deg, transparent 0%, rgba(5, 6, 13, 0.2) 45%, rgba(5, 6, 13, 0.95) 100%);
}
/* Bottom-sheet slide animation */
.sheet-translate {
transform: translateY(100%);
transition: transform 0.32s cubic-bezier(0.32, 0.72, 0.4, 1);
}
.sheet-translate.is-open { transform: translateY(0); }
/* Episode rank number stroke */
.rank-text {
font-family: 'Plus Jakarta Sans', sans-serif;
font-weight: 900;
font-size: 36px;
line-height: 1;
background: linear-gradient(180deg, #fff, #ff5da2);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
-webkit-text-stroke: 1.5px rgba(124, 92, 255, 0.55);
filter: drop-shadow(0 4px 8px rgba(0, 0, 0, 0.55));
}
/* Player overlay countdown ring */
.countdown-ring {
--p: 0;
background: conic-gradient(#7c5cff calc(var(--p) * 1%), rgba(255, 255, 255, 0.18) 0);
}
/* Active tab underline (used in platform-tabs) */
.tab-active::after {
content: '';
position: absolute;
left: 50%;
bottom: -2px;
transform: translateX(-50%);
width: 22px;
height: 3px;
border-radius: 2px;
background: linear-gradient(90deg, #7c5cff, #ff5da2);
}
/* Lucide icons default size */
[data-lucide] { width: 1em; height: 1em; }
/* =====================================================================
Subtitle styling (::cue)
Hanya properti berikut yang aman di ::cue: color, background,
font, opacity, outline, text-shadow, white-space.
Posisi cue di-handle browser (default: bottom-centered).
===================================================================== */
video::cue {
color: #fff;
background: transparent;
font-family: 'Inter', system-ui, sans-serif;
font-weight: 600;
font-size: 18px;
line-height: 1.35;
/* Double-stack shadow → terbaca jelas di background terang/gelap */
text-shadow:
0 0 4px rgba(0, 0, 0, 0.95),
0 1px 2px rgba(0, 0, 0, 0.95),
0 0 14px rgba(0, 0, 0, 0.55);
white-space: pre-line;
}
/* Kalau player vertical (drama pendek) ukurannya ngepas mobile */
.player video::cue { font-size: 16px; }
/* Layar besar */
@media (min-width: 1024px) {
video::cue { font-size: 20px; }
}
/* Hide aksen kotak background bawaan (Safari) */
video::-webkit-media-text-track-display {
background: transparent !important;
}
video::-webkit-media-text-track-container {
/* Geser sedikit ke atas dari edge bawah supaya gak kepotong control bar */
padding-bottom: 10px;
}
/* =====================================================================
Watch · immersive full-screen mobile experience (DramaBox-like)
- Pada layar < md, player mengambil seluruh viewport (fixed)
- Topbar & bottom nav disembunyikan, meta block disembunyikan
- Right rail floating: prev / episodes / next
===================================================================== */
@media (max-width: 767.98px) {
/* Sembunyikan chrome aplikasi saat berada di halaman /watch */
body.is-watch #topBar,
body.is-watch #bottomNav { display: none !important; }
/* Hilangkan padding bawah default body (yang biasanya untuk bottom nav) */
body.is-watch { padding-bottom: 0 !important; }
body.is-watch main {
padding: 0 !important;
max-width: none !important;
width: 100% !important;
}
body.is-watch .watch-root { margin: 0 !important; gap: 0 !important; }
/* Meta block (judul + tombol prev/next versi tile + sinopsis) tidak perlu di mobile */
body.is-watch .meta-block { display: none !important; }
/* Player wrap mengambil seluruh viewport */
body.is-watch .player-wrap {
position: fixed;
inset: 0;
width: 100vw;
height: 100vh;
height: 100dvh;
border: 0 !important;
border-radius: 0 !important;
z-index: 30;
}
/* Player inner: penuhi parent, abaikan aspect-ratio bawaan */
body.is-watch .player-inner {
aspect-ratio: auto !important;
width: 100% !important;
max-width: none !important;
height: 100%;
}
/* Object-fit kontrol: untuk drama vertikal "cover", untuk landscape "contain" */
body.is-watch.is-vertical #video { object-fit: cover; }
body.is-watch.is-horizontal #video { object-fit: contain; }
}
/* Swipe hint fade out helper */
#swipeHint { transition: opacity .4s ease; }
#swipeHint.hidden-fade { opacity: 0; pointer-events: none; }
/* Auto-hide mobile overlay state */
#mobileOverlay.is-hidden { opacity: 0; }
#mobileOverlay.is-hidden * { pointer-events: none !important; }
/* =====================================================================
Discover · TikTok-style vertical feed (mobile only)
- Setiap item mengambil seluruh viewport DI ATAS bottom nav
- scroll-snap-type: y mandatory → scroll satu drama per gesekan
- Hanya video yang sedang terlihat yang di-play
- Bottom nav TETAP terlihat agar user bisa navigasi ke halaman lain
===================================================================== */
/* Tinggi bottom nav (selaras dengan _bottom_nav.html: h-16 = 64px) */
:root { --bn-h: calc(64px + env(safe-area-inset-bottom)); }
@media (max-width: 767.98px) {
/* Hilangkan topbar di SEMUA halaman mobile — bottom nav cukup */
#topBar { display: none !important; }
/* Beri ruang status bar untuk konten utama */
body main { padding-top: calc(env(safe-area-inset-top) + 8px) !important; }
/* Saat di halaman watch (immersive), reset padding & sembunyikan juga bottom nav */
body.is-watch main { padding: 0 !important; }
body.is-watch #bottomNav { display: none !important; }
/* Saat di discover feed: TIDAK lagi sembunyikan bottom nav.
Cukup matikan padding-bottom global supaya feed bisa fullscreen-snap
di area sisa di atas nav. */
body.is-discover-feed { padding-bottom: 0 !important; }
body.is-discover-feed main {
padding: 0 !important;
max-width: none !important;
width: 100% !important;
}
}
.discover-feed {
position: fixed;
inset: 0;
/* Sisakan ruang untuk bottom nav (mobile saja) */
bottom: var(--bn-h);
width: 100vw;
background: #000;
z-index: 30;
overflow: hidden;
}
@media (min-width: 768px) {
/* Di desktop section ini gak dipakai, tapi reset jaga-jaga */
.discover-feed { display: none; }
}
.discover-feed-track {
position: absolute;
inset: 0;
overflow-y: auto;
scroll-snap-type: y mandatory;
scroll-behavior: smooth;
-webkit-overflow-scrolling: touch;
}
.discover-feed-track::-webkit-scrollbar { display: none; }
.feed-item {
position: relative;
/* Tinggi = viewport - bottom nav */
height: calc(100dvh - var(--bn-h));
width: 100%;
scroll-snap-align: start;
scroll-snap-stop: always;
background: #000;
overflow: hidden;
}
.feed-item .feed-media {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
background-position: center;
background-size: cover;
}
.feed-item .feed-video {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
}
.feed-item.is-vertical .feed-video { object-fit: cover; }
.feed-item.is-horizontal .feed-video { object-fit: contain; }
.feed-item .feed-bottom-grad {
position: absolute;
inset-inline: 0;
bottom: 0;
height: 55%;
background: linear-gradient(180deg, transparent, rgba(0,0,0,.5) 60%, rgba(0,0,0,.85));
pointer-events: none;
}
/* Loading state per item */
.feed-item .feed-spinner {
position: absolute;
inset: 0;
display: grid;
place-items: center;
pointer-events: none;
opacity: 0;
transition: opacity .25s ease;
}
.feed-item.is-loading .feed-spinner { opacity: 1; }
/* Mute pulse indicator */
.feed-item .feed-tap-indicator {
position: absolute;
inset: 0;
display: grid;
place-items: center;
opacity: 0;
pointer-events: none;
transition: opacity .35s ease;
}
.feed-item.is-paused .feed-tap-indicator { opacity: 1; }