Files
ElegantFin/docs/index.html
2025-08-02 07:38:15 -07:00

1040 lines
36 KiB
HTML
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ElegantFin Theme for Jellyfin</title>
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
line-height: 1.6;
max-width: 1080px;
margin: 0 auto;
padding: 20px;
color: #333;
}
h1 {
color: #2c3e50;
border-bottom: 3px solid #3498db;
padding-bottom: 10px;
}
h2 {
color: #34495e;
border-bottom: 2px solid #ecf0f1;
padding-bottom: 5px;
}
h3 {
color: #2c3e50;
}
h4 {
color: #7f8c8d;
}
hr {
border: none;
height: 2px;
background: linear-gradient(to right, #3498db, #e74c3c);
margin: 30px 0;
}
code {
background-color: #f8f9fa;
padding: 2px 4px;
border-radius: 3px;
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
}
pre {
background-color: #f8f9fa;
padding: 15px;
border-radius: 5px;
overflow-x: auto;
border-left: 4px solid #3498db;
}
table {
width: 100%;
border-collapse: collapse;
margin: 20px 0;
}
th,
td {
padding: 12px;
text-align: center;
border: 1px solid #ddd;
}
th {
background-color: #f2f2f2;
font-weight: bold;
}
img {
max-width: 100%;
height: auto;
border-radius: 8px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
.banner img {
width: 100%;
margin-bottom: 20px;
}
details {
margin: 15px 0;
border: 1px solid #ddd;
border-radius: 5px;
padding: 10px;
}
summary {
cursor: pointer;
font-weight: bold;
padding: 10px;
background-color: #f8f9fa;
border-radius: 3px;
margin: -10px -10px 10px -10px;
}
summary:hover {
background-color: #e9ecef;
}
ul {
padding-left: 20px;
}
li {
margin: 5px 0;
}
a {
color: #3498db;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
.key-features {
background-color: #f8f9fa;
padding: 20px;
border-radius: 8px;
border-left: 4px solid #27ae60;
}
.installation-box {
background-color: #fff3cd;
border: 1px solid #ffeaa7;
border-radius: 5px;
padding: 15px;
margin: 15px 0;
}
.video-container {
text-align: center;
margin: 20px 0;
}
/* Carousel Styles */
.carousel-container {
position: relative;
max-width: 100%;
margin: 20px 0;
background: #f8f9fa;
border-radius: 12px;
overflow: hidden;
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
}
.carousel-tabs {
display: flex;
background: #fff;
border-bottom: 2px solid #e9ecef;
}
.carousel-tab {
flex: 1;
padding: 15px 20px;
background: #f8f9fa;
border: none;
cursor: pointer;
font-weight: 600;
color: #6c757d;
transition: all 0.3s ease;
font-size: 14px;
}
.carousel-tab.active {
background: #3498db;
color: white;
}
.carousel-tab:hover:not(.active) {
background: #e9ecef;
color: #495057;
}
.carousel-content {
position: relative;
min-height: 400px;
max-height: 80vh;
}
.carousel-section {
display: none;
padding: 20px;
}
.carousel-section.active {
display: block;
}
.carousel-wrapper {
position: relative;
overflow: hidden;
border-radius: 8px;
}
.carousel-track {
display: flex;
transition: transform 0.5s ease-in-out;
}
.carousel-slide {
min-width: 100%;
flex-shrink: 0;
text-align: center;
}
.carousel-slide img {
/* width: 30%; */
max-height: 55vh;
max-width: 800px;
/* height: fit-content; */
border-radius: 8px;
}
.slide-title {
margin-top: 15px;
font-weight: bold;
color: #2c3e50;
font-size: 18px;
}
.carousel-controls {
display: flex;
justify-content: center;
align-items: center;
gap: 20px;
margin-top: 20px;
padding: 0 20px;
}
.carousel-btn {
background: #3498db;
color: white;
border: none;
padding: 12px 16px;
border-radius: 50%;
cursor: pointer;
font-size: 16px;
transition: all 0.3s ease;
box-shadow: 0 2px 8px rgba(52, 152, 219, 0.3);
}
.carousel-btn:hover {
background: #2980b9;
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(52, 152, 219, 0.4);
}
.carousel-btn:disabled {
background: #bdc3c7;
cursor: not-allowed;
transform: none;
box-shadow: none;
}
.carousel-counter {
background: rgba(52, 152, 219, 0.1);
padding: 8px 16px;
border-radius: 20px;
color: #2c3e50;
font-weight: 600;
font-size: 14px;
}
.carousel-indicators {
display: flex;
justify-content: center;
gap: 8px;
margin-top: 15px;
padding: 0 20px 20px;
}
.carousel-dot {
width: 10px;
height: 10px;
border-radius: 50%;
background: #bdc3c7;
cursor: pointer;
transition: all 0.3s ease;
}
.carousel-dot.active {
background: #3498db;
transform: scale(1.2);
}
.carousel-dot:hover {
background: #7f8c8d;
}
/* Responsive adjustments */
@media (max-width: 768px) {
.carousel-tabs {
flex-direction: column;
}
.carousel-tab {
text-align: center;
}
.carousel-controls {
flex-wrap: wrap;
gap: 15px;
}
.carousel-btn {
padding: 10px 14px;
font-size: 14px;
}
}
</style>
</head>
<body>
<!-- Banner Image -->
<div class="banner">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Theme/assets/img/banner.png?raw=true"
alt="ElegantFin Theme for Jellyfin - Banner">
</div>
<!-- <h1>⭐ ElegantFin Theme</h1> -->
<p>ElegantFin is a Jellyfin theme inspired from Jellyseerr to improve the overall look and experience with various
fixes
to the UI/UX. It gives Jellyfin a fresh, modern look, and it aims to work on mobile, desktop, and TV, with just
one import.</p>
<h4><strong>Author:</strong> <a href="https://github.com/lscambo13">lscambo13</a></h4>
<hr>
<h3>✨ Key Features</h3>
<div class="key-features">
<ul>
<li>modern layouts and color tones</li>
<li>new and improved animations on most elements</li>
<li>rounded corners and even spacing everywhere</li>
<li>stylish borders, hover effects and shadows</li>
<li>neat layout that puts important stuff up front</li>
<li>reduced unnecessary clutter</li>
<li>various fixes to improve the user experience</li>
<li>same clean design across phone, desktop, and TV</li>
</ul>
</div>
<hr>
<h3>🖼️ Theme Showcase</h3>
<p>Captured on ElegantFin v25.08.02</p>
<div class="carousel-container">
<div class="carousel-tabs">
<button class="carousel-tab active" onclick="switchTab(0)">💻 Desktop</button>
<button class="carousel-tab" onclick="switchTab(1)">📱 Mobile</button>
<button class="carousel-tab" onclick="switchTab(2)">📺 TV View</button>
</div>
<div class="carousel-content">
<!-- Desktop Section -->
<div class="carousel-section active" id="section-0">
<div class="carousel-wrapper">
<div class="carousel-track" id="track-0">
<div class="carousel-slide">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Previews/previews-v25.08.02/raw/desktop/21.%20Login%20Page.png?raw=true"
alt="Login Page Desktop">
<div class="slide-title">Login Page</div>
</div>
<div class="carousel-slide">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Previews/previews-v25.08.02/raw/desktop/1.%20Homepage.png?raw=true"
alt="Homepage Desktop">
<div class="slide-title">Homepage</div>
</div>
<div class="carousel-slide">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Previews/previews-v25.08.02/raw/desktop/2.%20Movies%20Library.png?raw=true"
alt="Movies Library Desktop">
<div class="slide-title">Movies Library</div>
</div>
<div class="carousel-slide">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Previews/previews-v25.08.02/raw/desktop/4.%20Movie%20Page.png?raw=true"
alt="Movie Page Desktop">
<div class="slide-title">Movie Page</div>
</div>
<div class="carousel-slide">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Previews/previews-v25.08.02/raw/desktop/12.%20Movie%20Details.png?raw=true"
alt="Movie Details Desktop">
<div class="slide-title">Movie Details</div>
</div>
<div class="carousel-slide">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Previews/previews-v25.08.02/raw/desktop/11.%20TV%20Show%20Page.png?raw=true"
alt="TV Show Page Desktop">
<div class="slide-title">TV Show Page</div>
</div>
<div class="carousel-slide">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Previews/previews-v25.08.02/raw/desktop/18.%20TV%20Episode%20Page.png?raw=true"
alt="TV Episode Page Desktop">
<div class="slide-title">TV Episode Page</div>
</div>
<div class="carousel-slide">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Previews/previews-v25.08.02/raw/desktop/16.%20TV%20Show%20Seasons.png?raw=true"
alt="TV Show Seasons Desktop">
<div class="slide-title">TV Show Seasons</div>
</div>
<div class="carousel-slide">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Previews/previews-v25.08.02/raw/desktop/9.%20Web%20Player.png?raw=true"
alt="Web Player Desktop">
<div class="slide-title">Web Player</div>
</div>
<div class="carousel-slide">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Previews/previews-v25.08.02/raw/desktop/17.%20Cast%20Page.png?raw=true"
alt="Cast Page Desktop">
<div class="slide-title">Cast Page</div>
</div>
<div class="carousel-slide">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Previews/previews-v25.08.02/raw/desktop/14.%20Artist%20Page.png?raw=true"
alt="Artist Page Desktop">
<div class="slide-title">Artist Page</div>
</div>
<div class="carousel-slide">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Previews/previews-v25.08.02/raw/desktop/15.%20Music%20Player.png?raw=true"
alt="Music Player Desktop">
<div class="slide-title">Music Player</div>
</div>
<div class="carousel-slide">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Previews/previews-v25.08.02/raw/desktop/13.%20Book%20Page.png?raw=true"
alt="Book Page Desktop">
<div class="slide-title">Book Page</div>
</div>
<div class="carousel-slide">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Previews/previews-v25.08.02/raw/desktop/3.%20Sidebar.png?raw=true"
alt="Sidebar Desktop">
<div class="slide-title">Sidebar</div>
</div>
<div class="carousel-slide">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Previews/previews-v25.08.02/raw/desktop/5.%20Extra%20Dialog.png?raw=true"
alt="Extra Dialog Desktop">
<div class="slide-title">Extra Dialog</div>
</div>
<div class="carousel-slide">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Previews/previews-v25.08.02/raw/desktop/6.%20Settings%20Page.png?raw=true"
alt="Settings Page Desktop">
<div class="slide-title">Settings Page</div>
</div>
<div class="carousel-slide">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Previews/previews-v25.08.02/raw/desktop/19.%20Live%20TV%20Page.png?raw=true"
alt="Live TV Page Desktop">
<div class="slide-title">Live TV Page</div>
</div>
<div class="carousel-slide">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Previews/previews-v25.08.02/raw/desktop/20.%20Live%20TV%20Guide.png?raw=true"
alt="Live TV Guide Desktop">
<div class="slide-title">Live TV Guide</div>
</div>
</div>
</div>
<div class="carousel-controls">
<button class="carousel-btn" onclick="prevSlide(0)" id="prev-0"></button>
<div class="carousel-counter" id="counter-0">1 / 18</div>
<button class="carousel-btn" onclick="nextSlide(0)" id="next-0"></button>
</div>
<div class="carousel-indicators" id="indicators-0"></div>
</div>
<!-- Mobile Section -->
<div class="carousel-section" id="section-1">
<div class="carousel-wrapper">
<div class="carousel-track" id="track-1">
<div class="carousel-slide">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Previews/previews-v25.08.02/raw/mobile/21.%20Login%20Page.png?raw=true"
alt="Login Page Mobile">
<div class="slide-title">Login Page</div>
</div>
<div class="carousel-slide">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Previews/previews-v25.08.02/raw/mobile/1.%20Homepage.png?raw=true"
alt="Homepage Mobile">
<div class="slide-title">Homepage</div>
</div>
<div class="carousel-slide">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Previews/previews-v25.08.02/raw/mobile/2.%20Movies%20Library.png?raw=true"
alt="Movies Library Mobile">
<div class="slide-title">Movies Library</div>
</div>
<div class="carousel-slide">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Previews/previews-v25.08.02/raw/mobile/4.%20Movie%20Page.png?raw=true"
alt="Movie Page Mobile">
<div class="slide-title">Movie Page</div>
</div>
<div class="carousel-slide">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Previews/previews-v25.08.02/raw/mobile/12.%20Movie%20Details.png?raw=true"
alt="Movie Details Mobile">
<div class="slide-title">Movie Details</div>
</div>
<div class="carousel-slide">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Previews/previews-v25.08.02/raw/mobile/11.%20TV%20Show%20Page.png?raw=true"
alt="TV Show Page Mobile">
<div class="slide-title">TV Show Page</div>
</div>
<div class="carousel-slide">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Previews/previews-v25.08.02/raw/mobile/18.%20TV%20Episode%20Page.png?raw=true"
alt="TV Episode Page Mobile">
<div class="slide-title">TV Episode Page</div>
</div>
<div class="carousel-slide">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Previews/previews-v25.08.02/raw/mobile/16.%20TV%20Show%20Seasons.png?raw=true"
alt="TV Show Seasons Mobile">
<div class="slide-title">TV Show Seasons</div>
</div>
<div class="carousel-slide">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Previews/previews-v25.08.02/raw/mobile/9.%20Web%20Player.png?raw=true"
alt="Web Player Mobile">
<div class="slide-title">Web Player</div>
</div>
<div class="carousel-slide">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Previews/previews-v25.08.02/raw/mobile/17.%20Cast%20Page.png?raw=true"
alt="Cast Page Mobile">
<div class="slide-title">Cast Page</div>
</div>
<div class="carousel-slide">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Previews/previews-v25.08.02/raw/mobile/14.%20Artist%20Page.png?raw=true"
alt="Artist Page Mobile">
<div class="slide-title">Artist Page</div>
</div>
<div class="carousel-slide">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Previews/previews-v25.08.02/raw/mobile/15.%20Music%20Player.png?raw=true"
alt="Music Player Mobile">
<div class="slide-title">Music Player</div>
</div>
<div class="carousel-slide">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Previews/previews-v25.08.02/raw/mobile/13.%20Book%20Page.png?raw=true"
alt="Book Page Mobile">
<div class="slide-title">Book Page</div>
</div>
<div class="carousel-slide">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Previews/previews-v25.08.02/raw/mobile/3.%20Sidebar.png?raw=true"
alt="Sidebar Mobile">
<div class="slide-title">Sidebar</div>
</div>
<div class="carousel-slide">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Previews/previews-v25.08.02/raw/mobile/5.%20Extra%20Dialog.png?raw=true"
alt="Extra Dialog Mobile">
<div class="slide-title">Extra Dialog</div>
</div>
<div class="carousel-slide">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Previews/previews-v25.08.02/raw/mobile/6.%20Settings%20Page.png?raw=true"
alt="Settings Page Mobile">
<div class="slide-title">Settings Page</div>
</div>
<div class="carousel-slide">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Previews/previews-v25.08.02/raw/mobile/19.%20Live%20TV%20Page.png?raw=true"
alt="Live TV Page Mobile">
<div class="slide-title">Live TV Page</div>
</div>
<div class="carousel-slide">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Previews/previews-v25.08.02/raw/mobile/20.%20Live%20TV%20Guide.png?raw=true"
alt="Live TV Guide Mobile">
<div class="slide-title">Live TV Guide</div>
</div>
</div>
</div>
<div class="carousel-controls">
<button class="carousel-btn" onclick="prevSlide(1)" id="prev-1"></button>
<div class="carousel-counter" id="counter-1">1 / 18</div>
<button class="carousel-btn" onclick="nextSlide(1)" id="next-1"></button>
</div>
<div class="carousel-indicators" id="indicators-1"></div>
</div>
<!-- TV Section -->
<div class="carousel-section" id="section-2">
<div class="carousel-wrapper">
<div class="carousel-track" id="track-2">
<div class="carousel-slide">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Previews/previews-v25.08.02/raw/tv/21.%20Login%20Page.png?raw=true"
alt="Login Page TV">
<div class="slide-title">Login Page</div>
</div>
<div class="carousel-slide">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Previews/previews-v25.08.02/raw/tv/1.%20Homepage.png?raw=true"
alt="Homepage TV">
<div class="slide-title">Homepage</div>
</div>
<div class="carousel-slide">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Previews/previews-v25.08.02/raw/tv/2.%20Movies%20Library.png?raw=true"
alt="Movies Library TV">
<div class="slide-title">Movies Library</div>
</div>
<div class="carousel-slide">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Previews/previews-v25.08.02/raw/tv/4.%20Movie%20Page.png?raw=true"
alt="Movie Page TV">
<div class="slide-title">Movie Page</div>
</div>
<div class="carousel-slide">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Previews/previews-v25.08.02/raw/tv/5.%20Extra%20Dialog.png?raw=true"
alt="Extra Dialog TV">
<div class="slide-title">Extra Dialog</div>
</div>
<div class="carousel-slide">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Previews/previews-v25.08.02/raw/tv/6.%20Settings%20Page.png?raw=true"
alt="Settings Page TV">
<div class="slide-title">Settings Page</div>
</div>
<div class="carousel-slide">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Previews/previews-v25.08.02/raw/tv/9.%20Web%20Player.png?raw=true"
alt="Web Player TV">
<div class="slide-title">Web Player</div>
</div>
<div class="carousel-slide">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Previews/previews-v25.08.02/raw/tv/11.%20TV%20Show%20Page.png?raw=true"
alt="TV Show Page TV">
<div class="slide-title">TV Show Page</div>
</div>
<div class="carousel-slide">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Previews/previews-v25.08.02/raw/tv/12.%20Movie%20Details.png?raw=true"
alt="Movie Details TV">
<div class="slide-title">Movie Details</div>
</div>
<div class="carousel-slide">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Previews/previews-v25.08.02/raw/tv/13.%20Book%20Page.png?raw=true"
alt="Book Page TV">
<div class="slide-title">Book Page</div>
</div>
<div class="carousel-slide">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Previews/previews-v25.08.02/raw/tv/14.%20Artist%20Page.png?raw=true"
alt="Artist Page TV">
<div class="slide-title">Artist Page</div>
</div>
<div class="carousel-slide">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Previews/previews-v25.08.02/raw/tv/15.%20Music%20Player.png?raw=true"
alt="Music Player TV">
<div class="slide-title">Music Player</div>
</div>
<div class="carousel-slide">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Previews/previews-v25.08.02/raw/tv/16.%20TV%20Show%20Seasons.png?raw=true"
alt="TV Show Seasons TV">
<div class="slide-title">TV Show Seasons</div>
</div>
<div class="carousel-slide">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Previews/previews-v25.08.02/raw/tv/17.%20Cast%20Page.png?raw=true"
alt="Cast Page TV">
<div class="slide-title">Cast Page</div>
</div>
<div class="carousel-slide">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Previews/previews-v25.08.02/raw/tv/18.%20TV%20Episode%20Page.png?raw=true"
alt="TV Episode Page TV">
<div class="slide-title">TV Episode Page</div>
</div>
<div class="carousel-slide">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Previews/previews-v25.08.02/raw/tv/19.%20Live%20TV%20Page.png?raw=true"
alt="Live TV Page TV">
<div class="slide-title">Live TV Page</div>
</div>
<div class="carousel-slide">
<img src="https://github.com/lscambo13/ElegantFin/blob/main/Previews/previews-v25.08.02/raw/tv/20.%20Live%20TV%20Guide.png?raw=true"
alt="Live TV Guide TV">
<div class="slide-title">Live TV Guide</div>
</div>
</div>
</div>
<div class="carousel-controls">
<button class="carousel-btn" onclick="prevSlide(2)" id="prev-2"></button>
<div class="carousel-counter" id="counter-2">1 / 18</div>
<button class="carousel-btn" onclick="nextSlide(2)" id="next-2"></button>
</div>
<div class="carousel-indicators" id="indicators-2"></div>
</div>
</div>
</div>
<div class="video-container">
<video controls width="100%" style="max-width: 800px;">
<source
src="https://github.com/lscambo13/ElegantFin/raw/refs/heads/main/Previews/previews-v25.08.02/raw/mobile/ElegantFin%20Theme%20Video%20Demo.mp4?raw=true"
type="video/mp4">
Your browser does not support the video tag.
</video>
</div>
<hr>
<h3>👇 How to install/setup this theme?</h3>
<div class="installation-box">
<p><strong>Paste the following in Custom CSS code box:</strong></p>
<pre><code>@import url("https://cdn.jsdelivr.net/gh/lscambo13/ElegantFin@main/Theme/ElegantFin-jellyfin-theme-build-latest-minified.css");</code></pre>
</div>
<details>
<summary><i>Detailed steps for server-side implementation</i></summary>
<ol>
<li>Open Dashboard from Administration tab in Settings.</li>
<li>Select General tab from the side bar.</li>
<li>Scroll down to find Custom CSS code box under Branding section.</li>
<li>Paste the custom css in Custom CSS code box.</li>
<li>Click save</li>
</ol>
</details>
<details>
<summary><i>Detailed steps for client-side implementation</i></summary>
<ol>
<li>Open Display tab in Settings.</li>
<li>Scroll down to find Custom CSS code box.</li>
<li>Paste the custom css in Custom CSS code box.</li>
<li>Click save.</li>
</ol>
</details>
<hr>
<!--
<h3>🧩 How to customise this theme?</h3>
<details>
<summary><i>1. Custom media covers for user media libraries</i></summary>
<ul>
<li><a
href="https://github.com/lscambo13/ElegantFin/blob/main/custom-media-covers.md#%EF%B8%8F-presets-modify-these-styles-according-to-your-own-liking">Previews</a>
</li>
<li>Read more about this experimental add-on <a
href="https://github.com/lscambo13/ElegantFin/blob/main/custom-media-covers.md">here</a></li>
</ul>
</details>
<details>
<summary><i>2. Custom background image for the login page</i></summary>
<ul>
<li><a
href="https://user-images.githubusercontent.com/16425113/129554147-6ac7ba51-43e7-4c8e-ba77-e646a3ef6b12.jpg">Preview</a>
</li>
<li>To enable the background wallpaper on the login screen, first tick the 'Enable the splash screen' option
in your Jellyfin Dashboard below the Custom CSS Box.</li>
<li>Second, copy and paste the following code at the end in Custom CSS box but don't save yet.
<pre><code>:root{
--loginPageBgUrl: url("&lt;YOUR-JELLYFIN-SERVER-ADDRESS&gt;/Branding/Splashscreen?format=webp&foregroundLayer=1&quality=33&width=3840&height=2160&blur=2");
}</code></pre>
</li>
<li>Third, replace <code>&lt;YOUR-JELLYFIN-SERVER-ADDRESS&gt;</code> with your Jellyfin server address, for
example, <code>http://192.168.0.1:8097</code>.</li>
<li>Don't forget the correct http or https in your domain.</li>
<li>You can also modify the parameters, for example blur size or the resolution, according to your liking.
</li>
<li>Once done, save and refresh your apps and webpages.</li>
</ul>
</details>
<details>
<summary><i>3. Enable extra overlay buttons on cards on desktop</i></summary>
<ul>
<li>To enable 'Mark Played' and 'Add to Favorites' buttons that show up at the bottom right corner of cards
while hovering, copy and paste the following code at the end in Custom CSS box, click save and finally
refresh your app/webpage.
<pre><code>:root{
--extraCardButtonsVisibility: block;
}</code></pre>
</li>
<li>To hide them again, simply remove this code block or replace <code>block</code> with <code>none</code>.
</li>
</ul>
</details>
<details>
<summary><i>4. Place the overlay play button at the center of cards on desktop</i></summary>
<ul>
<li>To bring the mini play button to the center of cards, copy and paste the following code at the end in
Custom CSS box, click save and finally refresh your app/webpage.
<pre><code>:root{
--overlayPlayButtonPosition: 50%;
}</code></pre>
</li>
<li>To undo this change, simply remove this code block or replace <code>50%</code> with <code>2.8em</code>.
</li>
</ul>
</details>
<details>
<summary><i>5. Disable the card hover effect on desktop</i></summary>
<ul>
<li>To disable the reflection on cards that shows when hovering over them on desktop, copy and paste the
following code at the end in Custom CSS box, click save and finally refresh your app/webpage.
<pre><code>:root{
--cardHoverEffect: none;
}</code></pre>
</li>
<li>To undo this change, simply remove this code block or replace <code>none</code> with <code>""</code>.
</li>
</ul>
</details>
<details>
<summary><i>6. Enable labels below library cards</i></summary>
<ul>
<li>To enable text labels under the media library cards, copy and paste the following code at the end in
Custom CSS box, click save and finally refresh your app/webpage.
<pre><code>:root{
--libraryLabelVisibility: block;
}</code></pre>
</li>
<li>To undo this change, simply remove this code block or replace <code>block</code> with <code>none</code>.
</li>
</ul>
</details>
<details>
<summary><i>7. Enable support for the Media Bar plugin</i></summary>
<ul>
<li>ElegantFin does not support any plugins by default, so to to add external support for <a
href="https://github.com/IAmParadox27/jellyfin-plugin-media-bar/">this plugin</a>, copy and paste
the following code at the end in Custom CSS box, click save and finally refresh your app/webpage.
<pre><code>@import url("https://cdn.jsdelivr.net/gh/lscambo13/ElegantFin@main/Theme/assets/add-ons/media-bar-plugin-support-latest-min.css");</code></pre>
</li>
<li>To undo this change, simply remove this code block.</li>
</ul>
</details>
<hr> -->
<h3>🆗 Tested on</h3>
<ul>
<li>Jellyfin Server v10.10.6</li>
<li>Jellyfin Android App v2.6.2</li>
</ul>
<hr>
<!--
<h3>🛠️ Troubleshooting</h3>
<details>
<summary>1- <i>How do I check if I am using the latest version of ElegantFin?</i></summary>
<ul>
<li>To make sure that you are using the latest version of ElegantFin, check the version number at the bottom
in the Dashboard screen.</li>
<li>It should be something like ElegantFin v25.07.XX</li>
</ul>
</details>
<details>
<summary>2- <i>I see that a newer version is available, but I have not received it yet. Why?</i></summary>
<ul>
<li>If Dashboard footer shows an old version, it means that your app is still using an old cache.</li>
<li>Once that cache is updated, the new version will be loaded.</li>
<li>To get the latest version, you will need to clear cache. There are multiple ways to do it.</li>
<li>On web version, force a hard refresh of the page using CTRL + F5.</li>
<li>On apps, try signing out and back in again. OR in case of Jellyfin Media Player on windows, you might
need to delete the cache folder. That should definitely pull the latest version.</li>
</ul>
</details>
<details>
<summary>3- <i>Why do I notice visual bugs and inconsistencies on Jellyfin Media Player?</i></summary>
<ul>
<li>As of version 1.12.0, JMP is based on Qt 5.x which uses a very outdated web engine, so it does not
support many new CSS features. Once a new version based on Qt 6.x is released, most issues should
automatically be resolved. Until then, JMP is unsupported and I recommend using the web app instead.
</li>
</ul>
</details>
<details>
<summary>4- <i>Does it work on the AndroidTV version of the Jellyfin app?</i></summary>
<ul>
<li>As of version 0.18.11, the official Jellyfin app on the AndroidTVs does not support css themes, but the
Android mobile phone app supports them. The WebOS version of the app seems to be based on the mobile
phone version, so it supports the theme just fine.</li>
</ul>
</details>
<details>
<summary>5- <i>All the icons on my LG TV seem to be broken. How to fix them?</i></summary>
<ul>
<li>It seems that modern Material Icons which this theme uses are <a
href="https://github.com/lscambo13/ElegantFin/issues/39">not compatible on some WebOS TVs</a>. There
is a <a
href="https://www.reddit.com/r/youtubetv/comments/e27go3/chinese_symbols_instead_of_icons_on_lg_tv/">huge
similar thread</a> about this.</li>
<li>This bug can be fixed by using the older icons, so I have implemented the following workaround to bring
back older, supported icons.</li>
<li>Simply add the following code at the end in Custom CSS box and save, then refresh your apps and
webpages:
<pre><code>:root{
--iconPack: 'Material Icons';
}</code></pre>
</li>
</ul>
</details>
<details>
<summary>6- <i>How do I report bugs/issues?</i></summary>
<ul>
<li>First check <a href="https://github.com/lscambo13/ElegantFin/issues?q=">here</a> whether a similar issue
has been reported already. If it exists, upvote and comment there to let me know.</li>
<li>Alternatively, create a new issue <a
href="https://github.com/lscambo13/ElegantFin/issues/new/choose">here</a>.</li>
</ul>
</details>
<details>
<summary>7- <i>When can I expect another update?</i></summary>
<ul>
<li>🤷</li>
</ul>
</details>
<hr> -->
<h3>📌 Contributing</h3>
<p>Please read the <a href="./CONTRIBUTING.md">Contributor Guidelines</a> before opening pull requests.</p>
<h3>🙏 Feedback Appreciated</h3>
<p>Please use the right template when creating an <a
href="https://github.com/lscambo13/ElegantFin/issues/new/choose">issue</a> to <a
href="https://github.com/lscambo13/ElegantFin/issues/new?template=bug_report.md">report bugs</a> or <a
href="https://github.com/lscambo13/ElegantFin/issues/new?template=feature_request.md">provide
suggestions</a>.</p>
<script>
const carousels = [
{ currentSlide: 0, totalSlides: 16 },
{ currentSlide: 0, totalSlides: 8 }
];
function initializeCarousels() {
// Initialize indicators for both carousels
for (let carouselIndex = 0; carouselIndex < carousels.length; carouselIndex++) {
const indicatorsContainer = document.getElementById(`indicators-${carouselIndex}`);
indicatorsContainer.innerHTML = '';
for (let i = 0; i < carousels[carouselIndex].totalSlides; i++) {
const dot = document.createElement('div');
dot.className = `carousel-dot ${i === 0 ? 'active' : ''}`;
dot.onclick = () => goToSlide(carouselIndex, i);
indicatorsContainer.appendChild(dot);
}
}
updateCarousel(0);
updateCarousel(1);
}
function switchTab(tabIndex) {
// Update tab buttons
const tabs = document.querySelectorAll('.carousel-tab');
tabs.forEach((tab, index) => {
tab.classList.toggle('active', index === tabIndex);
});
// Update sections
const sections = document.querySelectorAll('.carousel-section');
sections.forEach((section, index) => {
section.classList.toggle('active', index === tabIndex);
});
}
function updateCarousel(carouselIndex) {
const track = document.getElementById(`track-${carouselIndex}`);
const counter = document.getElementById(`counter-${carouselIndex}`);
const prevBtn = document.getElementById(`prev-${carouselIndex}`);
const nextBtn = document.getElementById(`next-${carouselIndex}`);
const indicators = document.querySelectorAll(`#indicators-${carouselIndex} .carousel-dot`);
const currentSlide = carousels[carouselIndex].currentSlide;
const totalSlides = carousels[carouselIndex].totalSlides;
// Update track position
track.style.transform = `translateX(-${currentSlide * 100}%)`;
// Update counter
counter.textContent = `${currentSlide + 1} / ${totalSlides}`;
// Update button states
prevBtn.disabled = currentSlide === 0;
nextBtn.disabled = currentSlide === totalSlides - 1;
// Update indicators
indicators.forEach((dot, index) => {
dot.classList.toggle('active', index === currentSlide);
});
}
function nextSlide(carouselIndex) {
if (carousels[carouselIndex].currentSlide < carousels[carouselIndex].totalSlides - 1) {
carousels[carouselIndex].currentSlide++;
updateCarousel(carouselIndex);
}
}
function prevSlide(carouselIndex) {
if (carousels[carouselIndex].currentSlide > 0) {
carousels[carouselIndex].currentSlide--;
updateCarousel(carouselIndex);
}
}
function goToSlide(carouselIndex, slideIndex) {
carousels[carouselIndex].currentSlide = slideIndex;
updateCarousel(carouselIndex);
}
// Keyboard navigation
document.addEventListener('keydown', function (e) {
const activeSection = document.querySelector('.carousel-section.active');
const carouselIndex = activeSection ? parseInt(activeSection.id.split('-')[1]) : 0;
if (e.key === 'ArrowLeft') {
e.preventDefault();
prevSlide(carouselIndex);
} else if (e.key === 'ArrowRight') {
e.preventDefault();
nextSlide(carouselIndex);
}
});
// Auto-advance carousel (optional - uncomment to enable)
/*
setInterval(() => {
const activeSection = document.querySelector('.carousel-section.active');
const carouselIndex = activeSection ? parseInt(activeSection.id.split('-')[1]) : 0;
if (carousels[carouselIndex].currentSlide < carousels[carouselIndex].totalSlides - 1) {
nextSlide(carouselIndex);
} else {
carousels[carouselIndex].currentSlide = 0;
updateCarousel(carouselIndex);
}
}, 5000);
*/
// Initialize when page loads
document.addEventListener('DOMContentLoaded', initializeCarousels);
</script>
</body>
</html>