diff --git a/src/scripts/anime/player.js b/src/scripts/anime/player.js index 8220721..bbeeb81 100644 --- a/src/scripts/anime/player.js +++ b/src/scripts/anime/player.js @@ -30,10 +30,10 @@ async function loadMetadata() { if (!data.error) { const romajiTitle = data.title.romaji || data.title.english || 'Anime Title'; - document.getElementById('anime-title').innerText = romajiTitle; - document.title = `Watching ${romajiTitle} - Ep ${currentEpisode}`; + document.getElementById('anime-title-details').innerText = romajiTitle; + document.getElementById('anime-title-details2').innerText = romajiTitle; - document.getElementById('detail-anime-title').innerText = romajiTitle; + document.title = `Watching ${romajiTitle} - Ep ${currentEpisode}`; const tempDiv = document.createElement('div'); tempDiv.innerHTML = data.description || 'No description available.'; @@ -53,23 +53,43 @@ async function loadMetadata() { document.getElementById('detail-cover-image').src = data.coverImage.large || data.coverImage.medium || ''; + if (data.characters && data.characters.edges && data.characters.edges.length > 0) { + populateCharacters(data.characters.edges); + } + if (!extName) { - totalEpisodes = data.episodes || 0; - } else { + if (totalEpisodes > 0) { + const simpleEpisodes = []; + for (let i = 1; i <= totalEpisodes; i++) { + simpleEpisodes.push({ + number: i, + title: null, + + thumbnail: null, + isDub: false + }); + } + populateEpisodeCarousel(simpleEpisodes); + } + + } else { try { const res2 = await fetch(`/api/anime/${animeId}/episodes${extQuery}`); const data2 = await res2.json(); totalEpisodes = Array.isArray(data2) ? data2.length : 0; + + if (Array.isArray(data2) && data2.length > 0) { + populateEpisodeCarousel(data2); + } + } catch (e) { console.error("Error cargando episodios por extensión:", e); totalEpisodes = 0; } } - populateEpisodeSelectors(totalEpisodes); - if (currentEpisode >= totalEpisodes && totalEpisodes > 0) { document.getElementById('next-btn').disabled = true; } @@ -79,42 +99,103 @@ async function loadMetadata() { } } -function populateEpisodeSelectors(count) { - const list = document.getElementById('episode-list'); +function populateCharacters(characterEdges) { + const list = document.getElementById('characters-list'); + list.classList.remove('characters-list'); + list.classList.add('characters-carousel'); list.innerHTML = ''; - for (let i = 1; i <= count; i++) { + characterEdges.forEach(edge => { + const character = edge.node; + const voiceActor = edge.voiceActors ? edge.voiceActors.find(va => va.language === 'Japanese' || va.language === 'English') : null; + + if (character) { + const card = document.createElement('div'); + card.classList.add('character-card'); + + const img = document.createElement('img'); + img.classList.add('character-card-img'); + img.src = character.image.large || character.image.medium || ''; + img.alt = character.name.full || 'Character'; + + const vaName = voiceActor ? (voiceActor.name.full || voiceActor.name.userPreferred) : null; + const characterName = character.name.full || character.name.userPreferred || '--'; + + const details = document.createElement('div'); + details.classList.add('character-details'); + + const name = document.createElement('p'); + name.classList.add('character-name'); + name.innerText = characterName; + + const actor = document.createElement('p'); + actor.classList.add('actor-name'); + if (vaName) { + actor.innerText = `${vaName} (${voiceActor.language})`; + } else { + actor.innerText = 'Voice Actor: N/A'; + } + + details.appendChild(name); + details.appendChild(actor); + card.appendChild(img); + card.appendChild(details); + list.appendChild(card); + } + }); +} +function populateEpisodeCarousel(episodesData) { + const carousel = document.getElementById('episode-carousel'); + carousel.innerHTML = ''; + + episodesData.forEach((ep, index) => { + const epNumber = ep.number || ep.episodeNumber || ep.id || (index + 1); + + if (!epNumber) return; + const extParam = extName ? `?${extName}` : ""; - const btn = document.createElement('a'); - btn.href = `/watch/${animeId}/${i}${extParam}`; - btn.classList.add('episode-btn'); - btn.dataset.episode = i; - btn.innerText = i; + const hasThumbnail = ep.thumbnail && ep.thumbnail.trim() !== ''; - if (i === currentEpisode) { - btn.classList.add('active-ep'); + const link = document.createElement('a'); + link.href = `/watch/${animeId}/${epNumber}${extParam}`; + link.classList.add('carousel-item'); + link.dataset.episode = epNumber; + + if (!hasThumbnail) { + link.classList.add('no-thumbnail'); } - list.appendChild(btn); - } -} - -function filterEpisodes() { - const searchInput = document.getElementById('episode-search'); - const filter = searchInput.value.toUpperCase().trim(); - const episodeList = document.getElementById('episode-list'); - const buttons = episodeList.getElementsByClassName('episode-btn'); - - for (let i = 0; i < buttons.length; i++) { - const episodeNumber = buttons[i].dataset.episode; - - if (episodeNumber.startsWith(filter) || filter === "") { - buttons[i].style.display = ""; - } else { - buttons[i].style.display = "none"; + if (parseInt(epNumber) === currentEpisode) { + link.classList.add('active-ep-carousel'); } - } + + const imgContainer = document.createElement('div'); + imgContainer.classList.add('carousel-item-img-container'); + + if (hasThumbnail) { + + const img = document.createElement('img'); + img.classList.add('carousel-item-img'); + img.src = ep.thumbnail; + img.alt = `Episode ${epNumber} Thumbnail`; + imgContainer.appendChild(img); + } + + link.appendChild(imgContainer); + + const info = document.createElement('div'); + info.classList.add('carousel-item-info'); + + const title = document.createElement('p'); + + title.innerText = `Ep ${epNumber}: ${ep.title || 'Untitled'}`; + + info.appendChild(title); + + link.appendChild(info); + carousel.appendChild(link); + }); } async function loadExtensions() { diff --git a/views/css/anime/watch.css b/views/css/anime/watch.css index 5539c27..3f2c583 100644 --- a/views/css/anime/watch.css +++ b/views/css/anime/watch.css @@ -1,5 +1,4 @@ :root { - --color-bg-base: #000000; --color-bg-elevated: #0a0a0b; --color-bg-card: #121214; @@ -38,16 +37,9 @@ --transition-smooth: 350ms cubic-bezier(0.4, 0, 0.2, 1); --plyr-color-main: var(--color-primary); - --plyr-video-control-color: var(--color-text-primary); - --plyr-video-control-background-hover: rgba(255, 255, 255, 0.12); - --plyr-menu-background: rgba(18, 18, 20, 0.95); - --plyr-menu-color: var(--color-text-primary); - --plyr-menu-border-color: var(--glass-border); } -*, -*::before, -*::after { +*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; @@ -55,18 +47,13 @@ body { margin: 0; + padding: 0; background-color: var(--color-bg-base); color: var(--color-text-primary); font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; line-height: 1.6; overflow-x: hidden; -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -.ui-scale { - transform: scale(0.90); - transform-origin: top center; } .top-bar { @@ -88,7 +75,6 @@ body { padding: 0.7rem 1.5rem; background: var(--glass-bg); backdrop-filter: blur(16px); - -webkit-backdrop-filter: blur(16px); border: 1px solid var(--glass-border); border-radius: var(--radius-full); color: var(--color-text-primary); @@ -107,20 +93,17 @@ body { } .watch-container { - max-width: 1800px; - margin: 0 auto; - padding: 1rem var(--spacing-xl) var(--spacing-xl); - display: grid; - grid-template-columns: 1fr 420px; + max-width: 1600px; + margin: var(--spacing-2xl) auto; + padding: 0 var(--spacing-xl); + display: flex; + flex-direction: column; gap: var(--spacing-xl); - align-items: start; -} - -.watch-container.sidebar-hidden { - grid-template-columns: 1fr; + align-items: center; } .player-section { + width: 100%; display: flex; flex-direction: column; gap: var(--spacing-lg); @@ -133,18 +116,13 @@ body { flex-wrap: wrap; background: var(--glass-bg); backdrop-filter: blur(16px); - -webkit-backdrop-filter: blur(16px); border: 1px solid var(--glass-border); border-radius: var(--radius-lg); padding: var(--spacing-md); box-shadow: var(--shadow-sm); } -.control-group { - display: flex; - align-items: center; - gap: var(--spacing-md); -} +.control-group { display: flex; align-items: center; gap: var(--spacing-md); } .sd-toggle { display: flex; @@ -165,18 +143,13 @@ body { transition: color var(--transition-base); text-transform: uppercase; letter-spacing: 0.05em; - position: relative; } -.sd-option.active { - color: var(--color-text-primary); -} +.sd-option.active { color: var(--color-text-primary); } .sd-bg { position: absolute; - top: 4px; - left: 4px; - bottom: 4px; + top: 4px; left: 4px; bottom: 4px; width: calc(50% - 4px); background: var(--color-primary); border-radius: var(--radius-full); @@ -185,9 +158,7 @@ body { z-index: 1; } -.sd-toggle[data-state="dub"] .sd-bg { - transform: translateX(100%); -} +.sd-toggle[data-state="dub"] .sd-bg { transform: translateX(100%); } .source-select { appearance: none; @@ -206,44 +177,12 @@ body { transition: all var(--transition-base); } -.source-select:hover { - border-color: var(--color-primary); - background-color: var(--color-bg-card); -} - -.source-select:focus { - outline: none; - border-color: var(--color-primary); - box-shadow: 0 0 0 3px var(--color-primary-glow); -} - -.toggle-episodes-btn { - display: flex; - align-items: center; - gap: var(--spacing-sm); - background: var(--color-bg-elevated); - border: var(--border-subtle); - color: var(--color-text-primary); - padding: 0.7rem 1.2rem; - border-radius: var(--radius-full); - font-weight: 600; - cursor: pointer; - transition: all var(--transition-base); - margin-left: auto; -} - -.toggle-episodes-btn:hover { - background: var(--color-primary); - border-color: var(--color-primary); -} - -.toggle-episodes-btn.active { - background: var(--color-primary); - border-color: var(--color-primary); -} +.source-select:hover { border-color: var(--color-primary); background-color: var(--color-bg-card); } +.source-select:focus { outline: none; border-color: var(--color-primary); box-shadow: 0 0 0 3px var(--color-primary-glow); } .video-container { aspect-ratio: 16/9; + width: 100%; background: var(--color-bg-base); border-radius: var(--radius-xl); overflow: hidden; @@ -252,15 +191,9 @@ body { transition: box-shadow var(--transition-smooth); } -.video-container:hover { - box-shadow: var(--shadow-lg), 0 0 0 1px var(--color-primary), var(--shadow-glow); -} +.video-container:hover { box-shadow: var(--shadow-lg), 0 0 0 1px var(--color-primary), var(--shadow-glow); } -#player { - width: 100%; - height: 100%; - object-fit: contain; -} +#player { width: 100%; height: 100%; object-fit: contain; } .loading-overlay { position: absolute; @@ -275,23 +208,16 @@ body { } .spinner { - width: 48px; - height: 48px; - border: 3px solid rgba(255, 255, 255, 0.1); + width: 48px; height: 48px; + border: 3px solid rgba(255,255,255,0.1); border-top-color: var(--color-primary); border-radius: 50%; animation: spin 0.8s linear infinite; } -@keyframes spin { - to { transform: rotate(360deg); } -} +@keyframes spin { to { transform: rotate(360deg); } } -.loading-overlay p { - color: var(--color-text-secondary); - font-size: 0.95rem; - font-weight: 500; -} +.loading-overlay p { color: var(--color-text-secondary); font-size: 0.95rem; font-weight: 500; } .episode-controls { display: flex; @@ -300,226 +226,240 @@ body { gap: var(--spacing-lg); background: var(--glass-bg); backdrop-filter: blur(16px); - -webkit-backdrop-filter: blur(16px); border: 1px solid var(--glass-border); border-radius: var(--radius-lg); padding: var(--spacing-lg); box-shadow: var(--shadow-sm); } -.episode-info h1 { - font-size: 1.75rem; - font-weight: 800; - line-height: 1.2; - margin: 0 0 var(--spacing-xs); - color: var(--color-text-primary); -} +.episode-info h1 { font-size: 1.75rem; font-weight: 800; margin: 0 0 var(--spacing-xs); } +.episode-info p { color: var(--color-primary); font-weight: 600; font-size: 1rem; text-transform: uppercase; letter-spacing: 0.05em; } -.episode-info p { - color: var(--color-primary); - font-weight: 600; - font-size: 1rem; - text-transform: uppercase; - letter-spacing: 0.05em; - margin: 0; -} - -.navigation-buttons { - display: flex; - gap: var(--spacing-md); -} +.navigation-buttons { display: flex; gap: var(--spacing-md); } .nav-btn { - display: flex; - align-items: center; - gap: var(--spacing-sm); - background: var(--color-bg-elevated); - border: var(--border-subtle); - color: var(--color-text-primary); - padding: 0.75rem 1.5rem; - border-radius: var(--radius-full); - font-weight: 600; - font-size: 0.9rem; - cursor: pointer; - transition: all var(--transition-base); - white-space: nowrap; + display: flex; align-items: center; gap: var(--spacing-sm); + background: var(--color-bg-elevated); border: var(--border-subtle); + color: var(--color-text-primary); padding: 0.75rem 1.5rem; + border-radius: var(--radius-full); font-weight: 600; font-size: 0.9rem; + cursor: pointer; transition: all var(--transition-base); } -.nav-btn:hover:not(:disabled) { - background: var(--color-primary); - border-color: var(--color-primary); - transform: translateY(-2px); - box-shadow: var(--shadow-glow); -} +.nav-btn:hover:not(:disabled) { background: var(--color-primary); border-color: var(--color-primary); transform: translateY(-2px); box-shadow: var(--shadow-glow); } +.nav-btn:disabled { opacity: 0.3; cursor: not-allowed; } -.nav-btn:disabled { - opacity: 0.3; - cursor: not-allowed; -} - -.episodes-sidebar { - position: sticky; - top: 6rem; - height: calc(100vh - 7rem); - background: var(--glass-bg); - backdrop-filter: blur(16px); - -webkit-backdrop-filter: blur(16px); - border: 1px solid var(--glass-border); +.episode-carousel-compact { + width: 100%; + max-width: 1600px; + margin-top: var(--spacing-lg); + padding: 0; + background: transparent; border-radius: var(--radius-lg); - padding: var(--spacing-lg); - box-shadow: var(--shadow-md); - display: flex; - flex-direction: column; + overflow: hidden; } -.watch-container.sidebar-hidden > .episodes-sidebar { - display: none; -} - -.sidebar-header { +.carousel-header { + margin-bottom: var(--spacing-lg); + padding: 0 var(--spacing-xl); display: flex; justify-content: space-between; align-items: center; - margin-bottom: var(--spacing-lg); - padding-bottom: var(--spacing-md); - border-bottom: 1px solid var(--glass-border); } -.sidebar-header h3 { - font-size: 1.5rem; - font-weight: 700; - color: var(--color-primary); - margin: 0; -} - -.close-sidebar-btn { - display: none; - background: transparent; - border: none; - color: var(--color-text-secondary); - width: 36px; - height: 36px; - border-radius: 50%; - cursor: pointer; - transition: all var(--transition-base); - padding: 0; - align-items: center; - justify-content: center; -} - -.close-sidebar-btn:hover { - background: rgba(255, 255, 255, 0.08); +.carousel-header h2 { + font-size: 1.6rem; + font-weight: 900; color: var(--color-text-primary); + letter-spacing: -0.04em; + border-left: 4px solid var(--color-primary); + padding-left: var(--spacing-md); } -.sidebar-search { - margin-bottom: var(--spacing-md); +.carousel-nav { + display: flex; + gap: var(--spacing-xs); } -.episode-search-input { - width: 100%; - appearance: none; - background-color: var(--color-bg-elevated); - border: var(--border-subtle); - color: var(--color-text-primary); - padding: 0.75rem 1.2rem; - border-radius: var(--radius-full); - font-size: 0.9rem; - font-weight: 500; - transition: all var(--transition-base); -} - -.episode-search-input:focus { - outline: none; - border-color: var(--color-primary); - box-shadow: 0 0 0 3px var(--color-primary-glow); -} - -.episode-search-input::placeholder { - color: var(--color-text-muted); -} - -.episode-list { - flex: 1; - overflow-y: auto; - display: grid; - grid-template-columns: repeat(auto-fill, minmax(70px, 1fr)); - gap: var(--spacing-sm); - padding: var(--spacing-xs); - align-content: start; -} - -.episode-list::-webkit-scrollbar { - width: 6px; -} - -.episode-list::-webkit-scrollbar-track { - background: transparent; -} - -.episode-list::-webkit-scrollbar-thumb { - background: rgba(255, 255, 255, 0.1); - border-radius: var(--radius-full); -} - -.episode-list::-webkit-scrollbar-thumb:hover { - background: rgba(255, 255, 255, 0.2); -} - -.episode-btn { +.carousel-arrow-mini { display: flex; align-items: center; justify-content: center; + width: 36px; + height: 36px; background: var(--color-bg-elevated); border: var(--border-subtle); - border-radius: var(--radius-md); - padding: 0.85rem; - color: var(--color-text-primary); - font-weight: 700; - font-size: 1rem; - text-decoration: none; - transition: all var(--transition-base); - box-shadow: var(--shadow-sm); - aspect-ratio: 1; - min-height: 52px; + border-radius: var(--radius-full); + color: var(--color-text-secondary); + cursor: pointer; + transition: all var(--transition-fast); } -.episode-btn:hover { - background: rgba(255, 255, 255, 0.1); +.carousel-arrow-mini:hover { + background: var(--color-primary); border-color: var(--color-primary); - transform: scale(1.05); + color: var(--color-text-primary); + box-shadow: var(--shadow-sm); } -.episode-btn.active-ep { +.carousel-arrow-mini[style*="opacity: 0.3"] { + background: var(--color-bg-elevated); + color: var(--color-text-muted); + border-color: var(--border-subtle); + box-shadow: none; +} + +.episode-carousel-compact-list { + display: flex; + gap: var(--spacing-md); + padding: var(--spacing-sm) var(--spacing-xl); + overflow-x: auto; + scroll-snap-type: x mandatory; + -webkit-overflow-scrolling: touch; + scrollbar-width: none; + mask-image: linear-gradient(to right, transparent, black var(--spacing-md), black calc(100% - var(--spacing-md)), transparent); +} + +.episode-carousel-compact-list::-webkit-scrollbar { display: none; } + +.carousel-item { + flex: 0 0 200px; + height: 112px; + + background: var(--color-bg-card); + border: 2px solid var(--border-subtle); + border-radius: var(--radius-md); + overflow: hidden; + position: relative; + transition: all var(--transition-base); + text-decoration: none; + display: flex; + flex-direction: column; + + scroll-snap-align: start; + box-shadow: var(--shadow-sm); +} + +.carousel-item:hover { + border-color: var(--color-primary); + transform: scale(1.02); + box-shadow: var(--shadow-md), var(--shadow-glow); +} + +.carousel-item.active-ep-carousel { + border-color: var(--color-primary); + background: rgba(139, 92, 246, 0.15); + box-shadow: 0 0 0 2px var(--color-primary), var(--shadow-md); + transform: scale(1.02); +} + +.carousel-item.active-ep-carousel::after { + content: 'WATCHING'; + position: absolute; + top: 0; + right: 0; background: var(--color-primary); color: var(--color-text-primary); - border-color: var(--color-primary); - box-shadow: var(--shadow-glow); + padding: 2px 8px; + font-size: 0.7rem; font-weight: 800; + border-bottom-left-radius: var(--radius-sm); + letter-spacing: 0.05em; + z-index: 10; +} + +.carousel-item-img-container { + height: 70px; + background: var(--color-bg-elevated); + overflow: hidden; position: relative; } -.episode-btn.active-ep::after { - content: ''; - position: absolute; - inset: -2px; - border: 2px solid var(--color-primary); - border-radius: var(--radius-md); - opacity: 0.5; +.carousel-item-img { + width: 100%; + height: 100%; + object-fit: cover; + transition: transform var(--transition-smooth); + opacity: 0.8; } -.anime-details { - max-width: 1800px; +.carousel-item:hover .carousel-item-img { + transform: scale(1.1); + opacity: 1; +} + +.carousel-item-info { + flex: 1; + padding: var(--spacing-xs) var(--spacing-sm); + display: flex; + align-items: center; + justify-content: flex-start; + background: var(--color-bg-elevated); +} + +.carousel-item-info p { + font-size: 1rem; + font-weight: 600; + color: var(--color-text-primary); + margin: 0; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + letter-spacing: 0; + line-height: 1.2; +} + +.carousel-item-info p::before { + content: attr(data-episode-number); + color: var(--color-primary); + font-weight: 800; + margin-right: var(--spacing-xs); + opacity: 0.7; +} + +.carousel-item.no-thumbnail { + flex: 0 0 160px; + height: 90px; + background: var(--color-bg-elevated); + border: 2px solid var(--border-subtle); + display: flex; + align-items: center; + justify-content: center; + flex-direction: row; +} + +.carousel-item.no-thumbnail .carousel-item-info { + padding: var(--spacing-sm); + background: transparent; + justify-content: center; +} + +.carousel-item.no-thumbnail .carousel-item-info p { + color: var(--color-text-secondary); + font-size: 1.05rem; + font-weight: 700; + text-align: center; +} + +.carousel-item.no-thumbnail:hover { + background: rgba(139, 92, 246, 0.12); + border-color: var(--color-primary); +} + +.carousel-item.no-thumbnail.active-ep-carousel .carousel-item-info p { + color: var(--color-primary); +} + +.anime-details, .anime-extra-content { + max-width: 1600px; margin: var(--spacing-2xl) auto; - padding: 0 var(--spacing-xl) 1rem; } .details-container { display: flex; + flex-direction: row; gap: var(--spacing-xl); background: var(--glass-bg); backdrop-filter: blur(16px); - -webkit-backdrop-filter: blur(16px); border: 1px solid var(--glass-border); border-radius: var(--radius-lg); padding: var(--spacing-xl); @@ -527,29 +467,25 @@ body { } .details-cover { + display: flex; + flex-direction: column; + align-items: flex-start; + gap: var(--spacing-md); flex-shrink: 0; } -.cover-image { - width: 220px; - height: auto; - border-radius: var(--radius-md); - box-shadow: var(--shadow-lg); -} - -.details-content h2 { - font-size: 2rem; - font-weight: 800; - margin: 0 0 var(--spacing-md); +.details-cover h1 { + font-size: 2.5rem; + font-weight: 900; color: var(--color-text-primary); + line-height: 1.2; + margin: 0 0 var(--spacing-md) 0; + text-align: left; } -.details-meta { - display: flex; - gap: var(--spacing-md); - flex-wrap: wrap; - margin-bottom: var(--spacing-lg); -} +.cover-image { width: 220px; border-radius: var(--radius-md); box-shadow: var(--shadow-lg); } + +.details-content h1 { font-size: 1.5rem; font-weight: 800; margin-bottom: var(--spacing-md); } .meta-badge { background: rgba(139, 92, 246, 0.12); @@ -561,131 +497,228 @@ body { border: 1px solid rgba(139, 92, 246, 0.2); } -.meta-badge.meta-score { - background: var(--color-primary); +.meta-badge.meta-score { background: var(--color-primary); color: white; } +.details-description { font-size: 1rem; line-height: 1.7; color: var(--color-text-secondary); } + +.characters-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: var(--spacing-xl); +} + +.characters-header h2 { + font-size: 1.75rem; + font-weight: 800; color: var(--color-text-primary); - border-color: var(--color-primary); + border-left: 5px solid var(--color-primary); + padding-left: var(--spacing-md); } -.details-description { - font-size: 1rem; - line-height: 1.7; - color: var(--color-text-secondary); - margin: 0; -} - -.plyr--video { - border-radius: var(--radius-xl); -} - -.plyr__controls { - background: linear-gradient(to top, rgba(0, 0, 0, 0.9) 0%, rgba(0, 0, 0, 0.5) 50%, transparent 100%) !important; - padding: 1rem 1.5rem 1.5rem !important; - border-radius: 0 0 var(--radius-xl) var(--radius-xl) !important; -} - -.plyr--full-ui input[type=range] { +.expand-btn { + display: flex; + align-items: center; + gap: var(--spacing-xs); + background: transparent; + border: none; color: var(--color-primary); + font-weight: 600; + cursor: pointer; + font-size: 1rem; + padding: var(--spacing-xs); + border-radius: var(--radius-sm); } -.plyr__control:hover { - background: rgba(255, 255, 255, 0.12) !important; +.expand-btn:hover { background: rgba(139, 92, 246, 0.1); } +.expand-btn svg { transition: transform var(--transition-smooth); } +.expand-btn[data-expanded="true"] svg { transform: rotate(180deg); } + +.characters-carousel { + display: flex; + flex-wrap: wrap; + gap: var(--spacing-lg); + align-content: flex-start; + overflow: hidden; + + height: 208px; + transition: height 0.55s cubic-bezier(0.4, 0, 0.2, 1); + padding: 0 var(--spacing-sm); + + -ms-overflow-style: none; + scrollbar-width: none; } -.plyr__menu__container { - background: var(--glass-bg) !important; - backdrop-filter: blur(16px); - border: 1px solid var(--glass-border); - border-radius: var(--radius-md) !important; - box-shadow: var(--shadow-lg) !important; +.characters-carousel::-webkit-scrollbar { + display: none; } -@media (max-width: 1100px) { - .watch-container { - grid-template-columns: 1fr; - padding-top: 5rem; +.characters-carousel.expanded { + + height: auto; + max-height: 3200px; + overflow-y: auto; + overflow-x: hidden; + padding: 0; + + -ms-overflow-style: auto; + scrollbar-width: thin; +} + +.characters-carousel.expanded::-webkit-scrollbar { + width: 6px; +} + +.characters-carousel.expanded::-webkit-scrollbar-thumb { + background: rgba(139, 92, 246, 0.4); + border-radius: 3px; +} + +.characters-carousel.expanded::-webkit-scrollbar-track { + background: transparent; +} + +.character-card { + + --card-min-width: 280px; + flex: 1 1 var(--card-min-width); + max-width: calc((100% - var(--spacing-lg) * 3) / 4); + min-width: var(--card-min-width); + + height: 92px; + display: flex; + align-items: center; + background: var(--color-bg-card); + border: var(--border-subtle); + border-radius: var(--radius-md); + padding: var(--spacing-md); + gap: var(--spacing-md); + transition: all var(--transition-fast); +} + +.character-card:hover { + border-color: var(--color-primary); + box-shadow: 0 8px 25px rgba(139, 92, 246, 0.15); + transform: translateY(-2px); +} + +.character-card-img { width: 60px; height: 60px; object-fit: cover; border-radius: var(--radius-sm); flex-shrink: 0; } +.character-details { overflow: hidden; flex: 1; } +.character-name { font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } +.actor-name { font-size: 0.875rem; color: var(--color-text-secondary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } + +.plyr--video { border-radius: var(--radius-xl); } +.plyr__controls { background: linear-gradient(to top, rgba(0,0,0,0.9) 0%, rgba(0,0,0,0.5) 50%, transparent 100%) !important; padding: 1rem 1.5rem 1.5rem !important; } +.plyr--full-ui input[type=range] { color: var(--color-primary); } +.plyr__control:hover { background: rgba(255,255,255,0.12) !important; } +.plyr__menu__container { background: var(--glass-bg) !important; backdrop-filter: blur(16px); border: 1px solid var(--glass-border); box-shadow: var(--shadow-lg) !important; } + +@media (min-width: 1024px) { + .carousel-nav { display: flex; } + .watch-container { padding-top: 5rem; } + + .details-cover { + align-items: center; + text-align: center; + } + .details-cover h1 { + text-align: center; + margin-bottom: var(--spacing-lg); } - .episodes-sidebar { - position: fixed; - top: 5rem; - right: 0; - left: 0; - width: auto; - height: auto; - max-height: 80vh; - margin: 0 1rem; - z-index: 999; - display: none; + .character-card { + max-width: calc((100% - var(--spacing-lg) * 2) / 3); } - .episodes-sidebar.sidebar-open { - display: flex; - } - - .close-sidebar-btn { - display: flex; - } - - .episode-list { - grid-template-columns: repeat(auto-fill, minmax(60px, 1fr)); + @media (min-width: 1400px) { + .character-card { + max-width: calc((100% - var(--spacing-lg) * 3) / 4); + } } } @media (max-width: 768px) { - .watch-container { - padding: 4.5rem 1rem 1rem; + .watch-container { padding: 4.5rem 1rem; } + + .episode-carousel-compact-list { + padding: var(--spacing-sm) var(--spacing-md); + } + .carousel-header { + padding: 0 var(--spacing-md); + } + .carousel-item { + flex: 0 0 180px; + height: 100px; + } + .carousel-item-img-container { height: 60px; } + .carousel-item-info p { font-size: 0.95rem; } + .carousel-item.no-thumbnail { + flex: 0 0 140px; + height: 80px; } - .anime-details { - padding: 0 1rem var(--spacing-xl); - } + .details-container { flex-direction: column; text-align: center; } - .details-container { - flex-direction: column; + .details-cover { + align-items: center; + width: 100%; + } + .details-cover h1 { + font-size: 2rem; text-align: center; } + .cover-image { width: 180px; margin: 0 auto; } - .cover-image { - width: 180px; - margin: 0 auto; - } + .episode-controls { flex-direction: column; gap: var(--spacing-md); } + .navigation-buttons { width: 100%; justify-content: center; } + .nav-btn { flex: 1; justify-content: center; } - .player-toolbar { - justify-content: center; - } - - .episode-controls { - flex-direction: column; + .characters-carousel { + justify-content: flex-start; gap: var(--spacing-md); + max-height: 194px; + padding: 0; } + .character-card { - .navigation-buttons { - width: 100%; - justify-content: center; - } - - .nav-btn { - flex: 1; - justify-content: center; - } - - .episodes-sidebar { - margin: 0 0.5rem; - padding: var(--spacing-md); + --card-min-width-sm: 45%; + flex: 1 1 var(--card-min-width-sm); + min-width: unset; + max-width: unset; + height: 85px; } } @media (max-width: 480px) { - .episode-info h1 { - font-size: 1.25rem; + .episode-info h1, .details-content h1 { font-size: 1.5rem; } + + .carousel-item { + flex: 0 0 150px; + height: 90px; + } + .carousel-item-img-container { height: 50px; } + .carousel-item-info p { font-size: 0.9rem; } + .carousel-item.no-thumbnail { + flex: 0 0 120px; + height: 70px; } - .details-content h2 { + .details-cover h1 { font-size: 1.5rem; } - .nav-btn span { - display: none; + .nav-btn span { display: none; } + + .character-card { + + flex: 1 1 100%; } +} + +.ui-scale-wrapper { + transform: scale(0.90); + transform-origin: top center; + width: 111.111%; + max-width: 1777px; + margin: 0 auto; + padding-top: 8vh; } \ No newline at end of file diff --git a/views/watch.html b/views/watch.html index 9ae823f..25d6481 100644 --- a/views/watch.html +++ b/views/watch.html @@ -25,30 +25,30 @@ -
- -
-
-
- Anime Cover -
-
-

-
- -- - -- - -- -
-

Loading description...

-
-
-
+
+
+
+
+ Anime Cover +
+
+

Loading...

+
+ -- + -- + -- +
+
+

Loading description...

+
+
+
+
-
@@ -56,7 +56,6 @@
Dub
-
- -
@@ -86,96 +76,113 @@
-

Loading...

+

Loading...

Episode --

+
+ +
- -
+
+
+
+
+

Cast & Characters

+ +
+ +
+
+
+ + \ No newline at end of file