├── .gitignore
├── assets
├── logo.png
├── banner.png
└── screenshots
│ ├── admin.jpg
│ ├── home.jpg
│ ├── details.jpg
│ └── library.jpg
├── theme
├── modules
│ ├── forgot-password.css
│ ├── central-libraries-small.css
│ ├── hide-my-media.css
│ ├── change-logo.css
│ ├── moving-cards.css
│ ├── count-indicators.css
│ ├── static-sidebar.css
│ ├── README.md
│ ├── floating-progress.css
│ └── smaller-cast.css
├── complete.css
└── base.css
├── package.json
├── .github
└── workflows
│ └── release.yml
├── LICENSE
├── release.purge.js
├── release.config.js
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | /node_modules
--------------------------------------------------------------------------------
/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JamsRepos/Jamfin/HEAD/assets/logo.png
--------------------------------------------------------------------------------
/assets/banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JamsRepos/Jamfin/HEAD/assets/banner.png
--------------------------------------------------------------------------------
/assets/screenshots/admin.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JamsRepos/Jamfin/HEAD/assets/screenshots/admin.jpg
--------------------------------------------------------------------------------
/assets/screenshots/home.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JamsRepos/Jamfin/HEAD/assets/screenshots/home.jpg
--------------------------------------------------------------------------------
/assets/screenshots/details.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JamsRepos/Jamfin/HEAD/assets/screenshots/details.jpg
--------------------------------------------------------------------------------
/assets/screenshots/library.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JamsRepos/Jamfin/HEAD/assets/screenshots/library.jpg
--------------------------------------------------------------------------------
/theme/modules/forgot-password.css:
--------------------------------------------------------------------------------
1 | /*
2 | This module will remove the "Forgot Password" button from the login page.
3 | This is useful if you have a third-party user management system.
4 | This can be used as a standalone module.
5 | */
6 |
7 | #btnResetPassword,
8 | .btnForgotPassword {
9 | display: none !important;
10 | }
11 |
12 | #loginPage {
13 | max-height: 450px;
14 | }
--------------------------------------------------------------------------------
/theme/modules/central-libraries-small.css:
--------------------------------------------------------------------------------
1 | /*
2 | This module will change "My Media (small)" to be centered on the homepage.
3 | This is useful to make the homepage look more balanced.
4 | This can be used as a standalone module.
5 | */
6 |
7 | #indexPage .section0 .itemsContainer.padded-left.padded-right {
8 | justify-content: center !important;
9 | padding-top: 15px !important;
10 | }
11 |
--------------------------------------------------------------------------------
/theme/modules/hide-my-media.css:
--------------------------------------------------------------------------------
1 | /*
2 | This module will hide the "My Media" section from the Jellyfin homepage.
3 | This is useful if you want an even more minimalistic homepage.
4 | This can be used as a standalone module.
5 | */
6 |
7 | #indexPage .section0 .sectionTitle {
8 | display: none;
9 | }
10 |
11 | #indexPage .section0 {
12 | padding-top: 1em;
13 | }
14 |
15 | #indexPage .verticalSection.section0 {
16 | padding-top: 3em;
17 | }
--------------------------------------------------------------------------------
/theme/modules/change-logo.css:
--------------------------------------------------------------------------------
1 | /*
2 | This module will change the Jellyfin logo to a custom one.
3 | This allows you to white-label your Jellyfin instance slightly.
4 | This can be used as a standalone module.
5 | */
6 |
7 | :root {
8 | --logo-url: url('https://cdn.jsdelivr.net/gh/JamsRepos/Jamfin@latest/assets/banner.png');
9 | }
10 |
11 | .pageTitleWithDefaultLogo,
12 | .spashLogo {
13 | background-image: var(--logo-url) !important;
14 | }
15 |
--------------------------------------------------------------------------------
/theme/modules/moving-cards.css:
--------------------------------------------------------------------------------
1 | /*
2 | This module will make your Jellyfin cards lift up slightly when hovered over.
3 | This is a simple and effective way to make your Jellyfin instance look more modern.
4 | This can be used as a standalone module.
5 | */
6 |
7 | .cardBox:hover {
8 | transform: translateY(-2.5px);
9 | -webkit-transform: translateY(-2.5px);
10 | -moz-transform: translateY(-2.5px);
11 | -ms-transform: translateY(-2.5px);
12 | -o-transform: translateY(-2.5px);
13 | }
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "jamfin",
3 | "version": "1.0.0",
4 | "license": "MIT",
5 | "scripts": {
6 | "semantic-release": "semantic-release"
7 | },
8 | "devDependencies": {
9 | "@semantic-release/changelog": "^6.0.3",
10 | "@semantic-release/exec": "^6.0.3",
11 | "@semantic-release/git": "^10.0.1",
12 | "@semantic-release/github": "^10.0.5",
13 | "axios": "^1.7.2",
14 | "conventional-changelog-conventionalcommits": "^8.0.0",
15 | "semantic-release": "^24.0.0"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: Create Release
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 |
8 | jobs:
9 | release:
10 | runs-on: ubuntu-latest
11 | steps:
12 | - name: Checkout code
13 | uses: actions/checkout@v3
14 |
15 | - name: Set up Node.js
16 | uses: actions/setup-node@v3
17 | with:
18 | node-version: 21
19 |
20 | - name: Install dependencies
21 | run: npm install
22 |
23 | - name: Run semantic-release
24 | id: release
25 | run: npm run semantic-release
26 | env:
27 | GH_TOKEN: ${{ secrets.GH_TOKEN }}
--------------------------------------------------------------------------------
/theme/modules/count-indicators.css:
--------------------------------------------------------------------------------
1 | /*
2 | This module change the color of the count indicators.
3 | This is a simple and effective way to make your Jellyfin instance look more modern.
4 | This can be used as a standalone module.
5 | */
6 |
7 | :root {
8 | --show-count-indicators: flex; /* none to hide */
9 | --count-indicator-colour: rgba(200, 200, 200, 0.75);
10 | --played-indicator-colour: rgba(32, 139, 36, 0.75);
11 | }
12 |
13 | .countIndicator {
14 | display: var(--show-count-indicators);
15 | }
16 |
17 | .countIndicator,
18 | .fullSyncIndicator,
19 | .mediaSourceIndicator,
20 | .playedIndicator {
21 | background: var(--count-indicator-colour);
22 | }
23 |
24 | .playedIndicator {
25 | background: var(--played-indicator-colour);
26 | }
--------------------------------------------------------------------------------
/theme/modules/static-sidebar.css:
--------------------------------------------------------------------------------
1 | /*
2 | This module will allow you to make the sidebar static, meaning it will not scroll with the rest of the page.
3 | This is a simple and effective way to make your Jellyfin instance look more modern.
4 | This can be used as a standalone module.
5 | */
6 |
7 | .layout-desktop .mainDrawer,
8 | .MuiDrawer-paperAnchorLeft {
9 | left: 0 !important;
10 | top: 0;
11 | width: 250px !important;
12 | background-color: var(--theme-sidebar-background-colour) !important;
13 | z-index: 100;
14 | }
15 |
16 | .layout-desktop .mainDrawerButton,
17 | .layout-desktop .headerHomeButton {
18 | display: none;
19 | }
20 |
21 | .layout-desktop .libraryPage:not(#editItemMetadataPage) {
22 | margin-left: 250px;
23 | width: calc(100% - 250px);
24 | }
25 |
26 | .layout-desktop #slides-container {
27 | margin-left: 320px;
28 | width: calc(100% - 385px);
29 | }
30 |
31 | .layout-desktop .hide-scroll .mainDrawer,
32 | .layout-desktop .hideMainDrawer .mainDrawer {
33 | display: none;
34 | }
35 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 Jam
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/theme/complete.css:
--------------------------------------------------------------------------------
1 | /*
2 | The complete pack of the Jamfin theme. This file includes all the modules and the main theme.
3 | If you wish to use only some of the modules, you can import them individually.
4 | You can grab the base theme by changing jamfin.css to base.css in the first line.
5 | */
6 |
7 | @import url("https://cdn.jsdelivr.net/gh/JamsRepos/Jamfin@latest/theme/base.css");
8 | @import url("https://cdn.jsdelivr.net/gh/JamsRepos/Jamfin@latest/theme/modules/static-sidebar.css");
9 | @import url("https://cdn.jsdelivr.net/gh/JamsRepos/Jamfin@latest/theme/modules/central-libraries-small.css");
10 | @import url("https://cdn.jsdelivr.net/gh/JamsRepos/Jamfin@latest/theme/modules/change-logo.css");
11 | @import url("https://cdn.jsdelivr.net/gh/JamsRepos/Jamfin@latest/theme/modules/count-indicators.css");
12 | @import url("https://cdn.jsdelivr.net/gh/JamsRepos/Jamfin@latest/theme/modules/forgot-password.css");
13 | @import url("https://cdn.jsdelivr.net/gh/JamsRepos/Jamfin@latest/theme/modules/hide-my-media.css");
14 | @import url("https://cdn.jsdelivr.net/gh/JamsRepos/Jamfin@latest/theme/modules/moving-cards.css");
15 | @import url("https://cdn.jsdelivr.net/gh/JamsRepos/Jamfin@latest/theme/modules/smaller-cast.css");
16 | @import url("https://cdn.jsdelivr.net/gh/JamsRepos/Jamfin@latest/theme/modules/floating-progress.css");
17 |
--------------------------------------------------------------------------------
/theme/modules/README.md:
--------------------------------------------------------------------------------
1 |
2 |

3 |
4 | ## 🧩 Modules
5 |
6 | Here you can find our assortment of modules. These are included within the complete pack of the theme however can be used in conjunction with the base theme or any other theme of your choosing.
7 |
8 | ## 🔌 Installation
9 |
10 | The general format to install a module is as followed, you will need to replace the `
` with the file name of the module you wish to install.
11 |
12 |
13 |
14 | ```css
15 | @import url("https://cdn.jsdelivr.net/gh/JamsRepos/Jamfin@latest/theme/modules/.css");
16 | ```
17 |
18 |
19 |
20 | #### ❓Where do I install it?
21 |
22 | Locate the `Custom CSS code` option under your General settings in the admin panel and simply paste one of the lines above within the box.
23 |
24 | If you wish to just install this for yourself only, you can do so by going to your users Display settings and copy the following settings.
25 |
26 | - [x] Disable server-provided custom CSS code
27 |
28 | Then enter the theme into the `Custom CSS code` option and save your settings.
29 |
30 | ## 🖌️ Customisation
31 |
32 | Each module has it's own individual customisation parameters. Please read the respective README by going into each modules folder.
33 |
34 |
--------------------------------------------------------------------------------
/theme/modules/floating-progress.css:
--------------------------------------------------------------------------------
1 | /*
2 | This module will make progress bars float from the bottom of the card.
3 | This is useful if you wish to make the progress bar more visible.
4 | This can be used as a standalone module.
5 | */
6 |
7 | :root {
8 | --floating-progress-roundness: .75rem;
9 | --floating-progress-height: 10px;
10 | }
11 |
12 | .sessionNowPlayingDetails {
13 | padding-bottom: 10px;
14 | }
15 |
16 | .fullInnerCardFooter,
17 | .activeSession .backgroundProgress,
18 | .activeSession .playbackProgress,
19 | .activeSession .transcodingProgress {
20 | width: 95%;
21 | bottom: 10px;
22 | margin: 0 auto;
23 | height: var(--floating-progress-height);
24 | border-radius: var(--floating-progress-roundness) !important;
25 | -webkit-border-radius: var(--floating-progress-roundness) !important;
26 | -moz-border-radius: var(--floating-progress-roundness) !important;
27 | }
28 |
29 | .itemProgressBar {
30 | height: var(--floating-progress-height);
31 | box-shadow: inset 0 1px var(--theme-menu-shadow-colour);
32 | -webkit-box-shadow: inset 0 1px var(--theme-menu-shadow-colour);
33 | -moz-box-shadow: inset 0 1px var(--theme-menu-shadow-colour);
34 | }
35 |
36 | .playbackProgress > div,
37 | .backgroundProgress > div,
38 | .transcodingProgress > div {
39 | box-shadow: inset 0 1px var(--theme-menu-shadow-colour);
40 | -webkit-box-shadow: inset 0 1px var(--theme-menu-shadow-colour);
41 | -moz-box-shadow: inset 0 1px var(--theme-menu-shadow-colour);
42 | border-radius: var(--floating-progress-roundness);
43 | -webkit-border-radius: var(--floating-progress-roundness);
44 | -moz-border-radius: var(--floating-progress-roundness);
45 | }
--------------------------------------------------------------------------------
/release.purge.js:
--------------------------------------------------------------------------------
1 | const axios = require('axios');
2 | const fs = require('fs');
3 | const path = require('path');
4 |
5 | function getCssFiles(dir, fileList = []) {
6 | const files = fs.readdirSync(dir);
7 | files.forEach((file) => {
8 | const filePath = path.join(dir, file);
9 | const stat = fs.statSync(filePath);
10 | if (stat.isDirectory()) {
11 | getCssFiles(filePath, fileList);
12 | } else if (file.endsWith('.css')) {
13 | const relativePath = path.relative(__dirname, filePath);
14 | fileList.push(`/gh/JamsRepos/Jamfin@latest/${relativePath}`);
15 | }
16 | });
17 | return fileList;
18 | }
19 |
20 | async function purgeCdnCache() {
21 | try {
22 | const cssDirectory = path.resolve(__dirname, './theme');
23 | const paths = getCssFiles(cssDirectory);
24 |
25 | const jsonPayload = {
26 | path: paths,
27 | };
28 |
29 | const response = await axios.post('https://purge.jsdelivr.net/', jsonPayload, {
30 | headers: {
31 | 'Content-Type': 'application/json',
32 | },
33 | });
34 |
35 | const id = response.data.id;
36 | let status = 'pending';
37 |
38 | while (status === 'pending') {
39 | await new Promise(resolve => setTimeout(resolve, 1000));
40 | const statusResponse = await axios.get(`https://purge.jsdelivr.net/status/${id}`);
41 | status = statusResponse.data.status;
42 | }
43 |
44 | if (status === 'finished') {
45 | console.log('CDN cache purge finished successfully.');
46 | } else {
47 | console.error('CDN cache purge failed.');
48 | process.exit(1);
49 | }
50 | } catch (error) {
51 | console.error('Error during CDN cache purge:', error);
52 | process.exit(1);
53 | }
54 | }
55 |
56 | purgeCdnCache();
57 |
--------------------------------------------------------------------------------
/release.config.js:
--------------------------------------------------------------------------------
1 | const branch = process.env.CURRENT_BRANCH || "main";
2 |
3 | if (!branch) {
4 | throw new Error("CURRENT_BRANCH not set");
5 | }
6 |
7 | /**
8 | * @type {import("semantic-release").GlobalConfig}
9 | */
10 | const config = {
11 | branches: ["main"],
12 | repositoryUrl: "https://github.com/JamsRepos/Jamfin.git",
13 | plugins: [
14 | [
15 | "@semantic-release/commit-analyzer",
16 | {
17 | releaseRules: [
18 | { scope: "no-release", release: false },
19 | { type: "build", release: "patch" },
20 | { type: "ci", release: "patch" },
21 | { type: "chore", release: "patch" },
22 | { type: "docs", release: false },
23 | { type: "refactor", release: "patch" },
24 | { type: "style", release: "patch" },
25 | { breaking: true, release: "major" },
26 | ],
27 | },
28 | ],
29 | [
30 | "@semantic-release/release-notes-generator",
31 | {
32 | preset: "conventionalcommits",
33 | presetConfig: {
34 | types: [
35 | { type: "feat", section: "New Features" },
36 | { type: "fix", section: "Bug Fixes" },
37 | { type: "perf", section: "Performance Improvements", hidden: false },
38 | { type: "revert", section: "Commit Reverts", hidden: false },
39 | { type: "build", section: "Build System", hidden: false },
40 | { type: "ci", section: "Continuous Integration", hidden: false },
41 | { type: "chore", section: "Chores", hidden: false },
42 | { type: "docs", section: "Documentation", hidden: false },
43 | { type: "style", section: "Style Changes", hidden: false },
44 | { type: "refactor", section: "Code Refactoring", hidden: false },
45 | { type: "test", section: "Test Cases", hidden: true },
46 | ],
47 | },
48 | },
49 | ],
50 | [
51 | "@semantic-release/exec",
52 | {
53 | successCmd: "node release.purge.js"
54 | }
55 | ]
56 | ],
57 | };
58 |
59 | if (branch === "main") {
60 | config.plugins.splice(-2, 0, "@semantic-release/github");
61 | }
62 |
63 | module.exports = config;
64 |
--------------------------------------------------------------------------------
/theme/modules/smaller-cast.css:
--------------------------------------------------------------------------------
1 | /*
2 | This module will make the cast cards smaller when viewing content details.
3 | This is useful if you want a more compact view of the cast.
4 | This can be used as a standalone module.
5 | Original Code: https://jellyfin.org/docs/general/clients/css-customization/#stylized-and-smaller-cast--crew-info
6 | */
7 |
8 | #castContent .card.overflowPortraitCard.personCard.card-hoverable.card-withuserdata {
9 | width: 4.2cm;
10 | font-size: 90%;
11 | }
12 |
13 | #castContent .card.overflowPortraitCard.personCard.card-withuserdata {
14 | width: 4.2cm;
15 | font-size: 90%;
16 | }
17 |
18 | #castContent .cardContent-button.cardImageContainer.coveredImage.cardContent.cardContent-shadow.itemAction.lazy {
19 | background-size: cover;
20 | -webkit-background-size: cover;
21 | -moz-background-size: cover;
22 | -o-background-size: cover;
23 | }
24 |
25 | #castContent .cardContent-button.cardImageContainer.coveredImage.defaultCardBackground.defaultCardBackground1.cardContent.cardContent-shadow.itemAction {
26 | background-size: cover;
27 | -webkit-background-size: cover;
28 | -moz-background-size: cover;
29 | -o-background-size: cover;
30 | }
31 |
32 | #castContent .cardContent-button.cardImageContainer.coveredImage.defaultCardBackground.defaultCardBackground2.cardContent.cardContent-shadow.itemAction {
33 | background-size: cover;
34 | -webkit-background-size: cover;
35 | -moz-background-size: cover;
36 | -o-background-size: cover;
37 | }
38 |
39 | #castContent .cardContent-button.cardImageContainer.coveredImage.defaultCardBackground.defaultCardBackground3.cardContent.cardContent-shadow.itemAction {
40 | background-size: cover;
41 | -webkit-background-size: cover;
42 | -moz-background-size: cover;
43 | -o-background-size: cover;
44 | }
45 |
46 | #castContent .cardContent-button.cardImageContainer.coveredImage.defaultCardBackground.defaultCardBackground4.cardContent.cardContent-shadow.itemAction {
47 | background-size: cover;
48 | -webkit-background-size: cover;
49 | -moz-background-size: cover;
50 | -o-background-size: cover;
51 | }
52 |
53 | #castContent .cardContent-button.cardImageContainer.coveredImage.defaultCardBackground.defaultCardBackground5.cardContent.cardContent-shadow.itemAction {
54 | background-size: cover;
55 | -webkit-background-size: cover;
56 | -moz-background-size: cover;
57 | -o-background-size: cover;
58 | }
59 |
60 | #castContent .cardScalable {
61 | width: 3.8cm;
62 | height: 3.8cm;
63 | }
64 |
65 | #castContent .cardOverlayButton-br {
66 | bottom: 4%;
67 | right: 15%;
68 | width: 70%;
69 | }
70 |
71 | #castContent .cardOverlayButton.cardOverlayButton-hover.itemAction.paper-icon-button-light {
72 | margin: auto;
73 | }
74 |
75 | #castContent .cardBox:not(.visualCardBox) .cardPadder {
76 | background-color: unset;
77 | }
78 |
79 | #castContent .cardBox:not(.visualCardBox) .cardPadder,
80 | #castContent .cardContent-shadow {
81 | box-shadow: unset;
82 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |

3 |
4 | [](https://www.jsdelivr.com/package/gh/JamsRepos/Jamfin)
5 |
6 | (
About -
Screenshots )
7 |
8 | ## ℹ️ Welcome
9 |
10 | This project brings a modern, sleek glassmorphism design to Jellyfin, enhancing your media server's aesthetics. The theme is designed to be modular and compact, allowing server owners to easily customize their Jellyfin experience.
11 |
12 | ## 🧩 Modules
13 |
14 | You can find our plug-and-play modules in the [modules folder](theme/modules/README.md). Each module's folder contains an explanation of its purpose and detailed instructions on how to use it.
15 |
16 | ## 🔌 Installation
17 |
18 | The following line includes the base theme as well as all our optional modules. This is what our screenshots are based off.
19 |
20 |
21 |
22 | ```css
23 | @import url("https://cdn.jsdelivr.net/gh/JamsRepos/Jamfin@latest/theme/complete.css");
24 | ```
25 |
26 |
27 |
28 | If you just want the theme without all our modules integrated, simply copy this line instead. Feel free to add the modules seperately.
29 |
30 |
31 |
32 | ```css
33 | @import url("https://cdn.jsdelivr.net/gh/JamsRepos/Jamfin@latest/theme/base.css");
34 | ```
35 |
36 |
37 |
38 | #### ❓Where do I install it?
39 |
40 | Locate the `Custom CSS code` option under your General settings in the admin panel and simply paste one of the lines above within the box.
41 |
42 | If you wish to just install this for yourself only, you can do so by going to your users Display settings and copy the following settings.
43 |
44 | - [x] Disable server-provided custom CSS code
45 |
46 | Then enter the theme into the `Custom CSS code` option and save your settings.
47 |
48 | ## 🖌️ Customisation
49 |
50 | Not sure if you like our colour scheme? No worries, we allow easy access to our themes colours. Paste these below your import and customise away!
51 |
52 |
53 | ```css
54 | :root {
55 | /* Colours */
56 | --theme-background-colour: #101010;
57 | --theme-sidebar-background-colour: #222222;
58 | --theme-menu-background-colour: #3a3a3a80;
59 | --theme-menu-shadow-colour: #fff3;
60 | --theme-base-colour: #696969;
61 | --theme--hover-colour: #dbdbdb;
62 | --theme-restart-colour: #da87287e;
63 | --theme-shutdown-colour: #c21c1c9d;
64 | --theme-progress-bar-colour: #cfcfcf;
65 | --theme-progress-bar-background-colour: #2c2c2c;
66 | --theme-progress-bar-transcoding-colour: #eb7e25;
67 |
68 | /* General Appearance */
69 | --theme-roundness: .75rem;
70 | --theme-blur: 16px;
71 | }
72 | ```
73 |
74 |
75 |
76 | #### ❓How do I customise the colours for the module too?
77 |
78 | You will find these within the respective modules folder, to cause less confusion they are excluded out of this example.
79 |
80 | ## 📷 Screenshots
81 |
82 |

83 |

84 |

85 |
86 | #### 🙏 Special Thanks
87 |
88 | Special thanks to [Scyfin](https://github.com/loof2736/scyfin) for design inspiration.
89 |
90 |
91 |
--------------------------------------------------------------------------------
/theme/base.css:
--------------------------------------------------------------------------------
1 | /*
2 | Jamfin - Another Jellyfin Theme aimed to please the masses.
3 | Please note that this theme is still in development and may not be fully functional.
4 | This theme is based on the Jellyfin default theme.
5 | This theme is licensed under the MIT License.
6 | */
7 |
8 | :root {
9 | /* Colours */
10 | --theme-background-colour: #101010;
11 | --theme-sidebar-background-colour: #222222;
12 | --theme-menu-background-colour: #3a3a3a80;
13 | --theme-menu-shadow-colour: #fff3;
14 | --theme-base-colour: #696969;
15 | --theme-text-colour: #dbdbdb;
16 | --theme-restart-colour: #da87287e;
17 | --theme-shutdown-colour: #c21c1c9d;
18 | --theme-progress-bar-colour: #cfcfcf;
19 | --theme-progress-bar-background-colour: #2c2c2c;
20 | --theme-progress-bar-transcoding-colour: #eb7e25;
21 | --theme-chapter-marker-colour: #dbdbdb;
22 | --theme-chapter-marker-watched-colour: #4a4a4a;
23 |
24 | /* General Appearance */
25 | --theme-roundness: .75rem;
26 | --theme-blur: 16px;
27 | }
28 |
29 | /* Remove the Default Focus Outline */
30 | *:focus-visible {
31 | outline: none;
32 | }
33 |
34 | /* Change Background Colours */
35 | .backgroundContainer,
36 | .mainDrawer,
37 | .drawer-open,
38 | .nowPlayingPlaylist,
39 | .nowPlayingContextMenu,
40 | html {
41 | background-color: var(--theme-background-colour);
42 | }
43 |
44 | /* Re-design the Header */
45 |
46 | .layout-desktop [dir="ltr"] .pageTitle {
47 | margin-left: 1.2em;
48 | }
49 |
50 | [dir="ltr"] .sidebarHeader {
51 | padding-left: 2em;
52 | font-weight: bold;
53 | }
54 |
55 | [dir="ltr"] .navMenuOption {
56 | padding: .9em 1.2em !important;
57 | }
58 |
59 | .pageTitleWithLogo {
60 | height: 50px;
61 | }
62 |
63 | .skinHeader {
64 | background-color: transparent;
65 | }
66 |
67 | .layout-desktop .headerLeft,
68 | .layout-desktop .headerRight {
69 | margin-top: 1rem;
70 | }
71 |
72 | .layout-mobile .headerRight {
73 | margin: 0 .29em;
74 | }
75 |
76 | .layout-mobile .libraryPage:not(.noSecondaryNavPage) {
77 | padding-top: 8.5em !important;
78 | }
79 |
80 | .paper-icon-button-light > div {
81 | width: 25px;
82 | height: 25px;
83 | transform: unset;
84 | }
85 |
86 | .skinHeader.semiTransparent {
87 | background-color: unset;
88 | }
89 |
90 | .headerTabs,
91 | .headerRight,
92 | .dialog,
93 | .raised,
94 | .fab,
95 | .paper-icon-button-light:not(
96 | .headerRight,
97 | .headerRight .paper-icon-button-light
98 | ),
99 | .osdHeader .headerLeft .paper-icon-button-light,
100 | .detailButton,
101 | .sliderBubble,
102 | .MuiDataGrid-root,
103 | .MuiMenu-list,
104 | .MuiButton-root,
105 | .toast.toastVisible,
106 | .guide-date-tab-button.emby-tab-button-active,
107 | .guide-date-tab-button:focus,
108 | .MuiTabs-centered .MuiTab-root,
109 | #skipIntro .emby-button,
110 | .chapterThumbContainer,
111 | .chapterThumbTextContainer {
112 | color: var(--theme-text-colour);
113 | border-radius: var(--theme-roundness);
114 | box-shadow: inset 0 1px var(--theme-menu-shadow-colour);
115 | background-color: var(--theme-menu-background-colour);
116 | backdrop-filter: blur(var(--theme-blur)) !important;
117 | -webkit-backdrop-filter: blur(var(--theme-blur)) !important;
118 | -moz-backdrop-filter: blur(var(--theme-blur)) !important;
119 | -o-backdrop-filter: blur(var(--theme-blur)) !important;
120 | -ms-backdrop-filter: blur(var(--theme-blur)) !important;
121 | }
122 |
123 | .dialogBackdrop {
124 | background-color: #111;
125 | }
126 |
127 | .headerTabs .emby-tabs-slider {
128 | display: flex;
129 | align-items: center;
130 | }
131 |
132 | .headerTabs .emby-tab-button,
133 | .headerRight .paper-icon-button-light,
134 | .detailButton,
135 | .sessionCardButton,
136 | .guideOptions,
137 | .MuiTabs-centered .MuiTab-root {
138 | padding: .556em !important;
139 | margin: 0 .29em !important;
140 | border-radius: var(--theme-roundness);
141 | }
142 |
143 | .layout-desktop .headerTabs,
144 | .layout-desktop .headerLeft,
145 | .layout-desktop .headerRight,
146 | .layout-desktop .emby-tabs-slider,
147 | .layout-desktop .raised {
148 | height: 50px;
149 | }
150 |
151 | .layout-mobile .headerTabs,
152 | .layout-mobile .headerRight,
153 | .layout-mobile .emby-tabs-slider,
154 | .layout-mobile .raised {
155 | height: 40px;
156 | }
157 |
158 | .layout-desktop .headerTabs {
159 | margin-left: 250px;
160 | }
161 |
162 | @media (max-width: 1599px) {
163 | .layout-desktop .sectionTabs {
164 | width: auto;
165 | align-self: center;
166 | margin-top: -58px;
167 | }
168 |
169 | .layout-desktop .headerRight {
170 | margin-right: .8em;
171 | }
172 |
173 | .layout-mobile .headerTabs {
174 | margin: 20px auto;
175 | width: auto;
176 | }
177 |
178 | .layout-mobile .pageTitleWithLogo {
179 | height: 40px;
180 | }
181 | }
182 |
183 | .layout-tv .sectionTabs {
184 | width: unset;
185 | }
186 |
187 | @media (min-width: 100em) {
188 | .layout-tv .headerTabs {
189 | margin-top: unset;
190 | }
191 |
192 | .layout-mobile .headerTabs {
193 | margin-top: -1.3em;
194 | }
195 | }
196 |
197 | @media (max-width: 100em) {
198 | .layout-tv .sectionTabs {
199 | width: fit-content;
200 | align-self: center;
201 | font-size: 125%;
202 | }
203 | }
204 |
205 | @media (max-width: 50em) {
206 | .homeLibraryButton {
207 | width: 100% !important;
208 | }
209 | }
210 |
211 | /* Main Drawer */
212 |
213 | .layout-desktop,
214 | .touch-menu-la.transition {
215 | transition: none;
216 | }
217 |
218 | .layout-mobile .mainDrawer {
219 | padding-top: 1.2em;
220 | }
221 |
222 | .layout-desktop .mainDrawer-scrollContainer {
223 | margin-top: 100px;
224 | }
225 |
226 | .navMenuOption,
227 | .navMenuOption-selected,
228 | .navMenuOption:hover,
229 | .MuiListItem-root,
230 | .MuiDrawer-paperAnchorLeft .MuiButtonBase-root {
231 | border-radius: var(--theme-roundness) !important;
232 | width: 80%;
233 | margin: auto !important;
234 | }
235 |
236 | .navMenuOption:hover,
237 | .listItem:hover,
238 | .MuiButton-root:hover {
239 | background-color: var(--theme-menu-shadow-colour);
240 | }
241 |
242 | .navMenuOption-selected,
243 | .Mui-selected {
244 | background: var(--theme-menu-shadow-colour) !important;
245 | }
246 |
247 | /* Main Cards */
248 |
249 | .section0 .sectionTitle {
250 | padding-top: 1em !important;
251 | }
252 |
253 | .layout-desktop .section0 .emby-scrollbuttons,
254 | .layout-desktop .section1 .emby-scrollbuttons {
255 | padding-top: unset;
256 | }
257 |
258 | .cardContent:not(.dashboardSection .cardContent),
259 | .cardPadder:not(.dashboardSection .cardPadder),
260 | .blurhash-canvas,
261 | .dialog,
262 | .itemSelectionPanel {
263 | border-radius: var(--theme-roundness) !important;
264 | box-shadow: inset 0 1px var(--theme-menu-shadow-colour) !important;
265 | transition: 0.2s;
266 | }
267 |
268 | .cardOverlayContainer {
269 | border-radius: var(--theme-roundness) !important;
270 | box-shadow: inset 0 2px var(--theme-menu-shadow-colour) !important;
271 | transition: unset;
272 | }
273 |
274 | .layout-mobile .cardOverlayButton {
275 | padding: unset;
276 | margin: 5px;
277 | }
278 |
279 | .layout-mobile .cardOverlayButtonIcon {
280 | background: unset !important;
281 | }
282 |
283 | .layout-desktop .cardOverlayContainer > .cardOverlayButton-br .cardOverlayButton {
284 | padding: unset;
285 | margin: 5px;
286 | }
287 |
288 | .defaultCardBackground1,
289 | .defaultCardBackground2,
290 | .defaultCardBackground3,
291 | .defaultCardBackground4,
292 | .defaultCardBackground5,
293 | .cardOverlayContainer > .cardOverlayFab-primary {
294 | background-color: var(--theme-menu-background-colour);
295 | font-size: 110%;
296 | }
297 |
298 | .button-submit:focus,
299 | .paper-icon-button-light:hover:not(:disabled, .btnDelete),
300 | .raised:hover,
301 | .emby-tab-button:hover,
302 | .detailButton:hover,
303 | .emby-tab-button.show-focus:focus,
304 | .paper-icon-button-light.show-focus:focus,
305 | .emby-button.show-focus:focus,
306 | .alphaPickerButton-tv:focus,
307 | #skipIntro .emby-button:hover,
308 | .multiSelectCheckboxOutline {
309 | border-radius: var(--theme-roundness) !important;
310 | transform: unset !important;
311 | -webkit-transform: unset !important;
312 | -moz-transform: unset !important;
313 | -o-transform: unset !important;
314 | -ms-transform: unset !important;
315 | color: var(--theme-text-colour);
316 | background-color: var(--theme-menu-shadow-colour) !important;
317 | }
318 |
319 | .layout-tv .itemDetailsGroup .emby-button.show-focus:focus {
320 | padding: 5px 10px;
321 | }
322 |
323 | /* User Settings */
324 |
325 | .readOnlyContent h2,
326 | .sectionTitle,
327 | .dashboardSection h3,
328 | .MuiListSubheader-root {
329 | font-weight: bold;
330 | }
331 |
332 | .listItem-border,
333 | .itemSelectionPanel {
334 | border: unset;
335 | }
336 |
337 | .listItem {
338 | padding-left: 1.2em !important;
339 | }
340 |
341 | .listItem:hover,
342 | .MuiButtonBase-root,
343 | .MuiButtonBase-root:hover,
344 | .emby-tab-button,
345 | progress {
346 | border-radius: var(--theme-roundness);
347 | }
348 |
349 | .collapseContent,
350 | .formDialogFooter:not(.formDialogFooter-clear),
351 | .formDialogHeader:not(.formDialogHeader-clear),
352 | .paperList,
353 | .visualCardBox,
354 | .emby-select-withcolor,
355 | .emby-input,
356 | .emby-textarea {
357 | background-color: var(--theme-menu-background-colour);
358 | border-radius: var(--theme-roundness);
359 | box-shadow: inset 0 1px var(--theme-menu-shadow-colour);
360 | border: unset;
361 | padding: 10px;
362 | }
363 |
364 | .emby-select[disabled] {
365 | box-shadow: unset;
366 | }
367 |
368 | .trackSelections .selectContainer .detailTrackSelect {
369 | padding: 0 10px;
370 | }
371 |
372 | /* Content Details */
373 |
374 | .layout-desktop .detailImageContainer .card {
375 | width: 250px;
376 | max-width: unset;
377 | top: 1.5em;
378 | left: 0;
379 | }
380 |
381 | /* Backwards Compatibility for versions before 10.11.0 */
382 | .layout-desktop .infoWrapper .detailImageContainer .card {
383 | padding-top: 8.5em;
384 | }
385 |
386 | .layout-desktop .detailPagePrimaryContent {
387 | padding-top: 135px;
388 | padding-left: 300px;
389 | min-height: 325px;
390 | }
391 |
392 | .layout-desktop .mainDetailButtons {
393 | margin-top: 350px;
394 | margin-left: 292px;
395 | position: absolute;
396 | }
397 |
398 | .layout-mobile .mainDetailButtons {
399 | display: flex;
400 | flex-flow: wrap;
401 | gap: 10px;
402 | }
403 |
404 | .mainDetailButtons .detailButton {
405 | display: inline-flex;
406 | align-items: center;
407 | padding-left: 50px;
408 | position: relative;
409 | }
410 |
411 | .btnPlay .detailButton-content:before {
412 | content: "Play";
413 | }
414 |
415 | .btnReplay .detailButton-content:before {
416 | content: "Replay";
417 | }
418 |
419 | .btnDownload .detailButton-content:before {
420 | content: "Download";
421 | }
422 |
423 | .btnPlayTrailer .detailButton-content:before {
424 | content: "Trailer";
425 | }
426 |
427 | .btnInstantMix .detailButton-content:before {
428 | content: "Instant Mix";
429 | }
430 |
431 | .btnShuffle .detailButton-content:before {
432 | content: "Shuffle";
433 | }
434 |
435 | .btnCancelSeriesTimer .detailButton-content:before {
436 | content: "Cancel Programme";
437 | }
438 |
439 | .btnCancelTimer .detailButton-content:before {
440 | content: "Stop Recording";
441 | }
442 |
443 | .btnPlaystate .detailButton-content:before {
444 | content: "Watched";
445 | }
446 |
447 | .btnUserRating .detailButton-content:before {
448 | content: "Favourite";
449 | }
450 |
451 | .btnSplitVersions .detailButton-content:before {
452 | content: "Split Versions";
453 | }
454 |
455 | .btnMoreCommands .detailButton-content:before {
456 | content: "Options";
457 | }
458 |
459 | .detailButton-content:before {
460 | position: relative;
461 | margin-left: 30px;
462 | }
463 |
464 | .detailButton-icon:before {
465 | position: absolute;
466 | top: 7px;
467 | left: 7px;
468 | }
469 |
470 | .mainDetailButtons .material-icons {
471 | height: unset;
472 | }
473 |
474 | .layout-desktop .detailPagePrimaryContainer,
475 | .layout-desktop .detailPageContent {
476 | padding-left: 3.3% !important;
477 | }
478 |
479 | .detailRibbon {
480 | background: unset;
481 | padding-left: 0 !important;
482 | }
483 |
484 | .layout-desktop .infoWrapper {
485 | padding-top: 226px;
486 | padding-left: 300px;
487 | }
488 |
489 | .itemBackdrop::before {
490 | content: '';
491 | position: absolute;
492 | top: 0; /* cover the full element */
493 | left: 0;
494 | right: 0;
495 | bottom: 0;
496 | background: linear-gradient(180deg, transparent 5%, var(--theme-background-colour));
497 | pointer-events: none; /* ensures it's non-interactive */
498 | z-index: 1; /* sits on top of the image */
499 | }
500 |
501 | .layout-mobile .itemBackdrop {
502 | margin-top: unset;
503 | -webkit-animation: backdrop-fadein .8s ease-in normal both;
504 | animation: backdrop-fadein .8s ease-in normal both;
505 | }
506 |
507 | .layout-mobile .detailImageContainer .card {
508 | filter: unset;
509 | -webkit-filter: unset;
510 | -moz-filter: unset;
511 | -o-filter: unset;
512 | -ms-filter: unset;
513 | padding-left: 2em;
514 | }
515 |
516 | .layout-desktop .detailLogo {
517 | left: 3%;
518 | right: unset;
519 | z-index: 1;
520 | }
521 |
522 | .layout-desktop .backgroundContainer.withBackdrop,
523 | .MuiPaper-root,
524 | .MuiTabs-indicator {
525 | background-color: unset;
526 | background-image: unset;
527 | box-shadow: unset;
528 | }
529 |
530 | .layout-desktop .backdropImage {
531 | filter: blur(5px);
532 | -webkit-filter: blur(5px);
533 | -moz-filter: blur(5px);
534 | -o-filter: blur(5px);
535 | -ms-filter: blur(5px);
536 | }
537 |
538 | .darkenContent {
539 | backdrop-filter: blur(5px) brightness(0.75);
540 | -webkit-backdrop-filter: blur(5px) brightness(0.75);
541 | -moz-backdrop-filter: blur(5px) brightness(0.75);
542 | -o-backdrop-filter: blur(5px) brightness(0.75);
543 | -ms-backdrop-filter: blur(5px) brightness(0.75);
544 | background: -webkit-linear-gradient(180deg, transparent, var(--theme-background-colour));
545 | background: -moz-linear-gradient(180deg, transparent, var(--theme-background-colour));
546 | background: -o-linear-gradient(180deg, transparent, var(--theme-background-colour));
547 | background: -ms-linear-gradient(180deg, transparent, var(--theme-background-colour));
548 | background: linear-gradient(180deg, transparent, var(--theme-background-colour));
549 | }
550 |
551 | .itemsContainer-tv {
552 | margin-left: 10px;
553 | }
554 |
555 | /* Admin Settings */
556 |
557 | #btnRestartServer {
558 | box-shadow: inset 0 1px var(--theme-restart-colour) !important;
559 | }
560 |
561 | #btnRestartServer:hover,
562 | .notifications,
563 | .MuiChip-filledInfo {
564 | color: var(--theme-text-colour) !important;
565 | background-color: var(--theme-restart-colour) !important;
566 | }
567 |
568 | #btnShutdown,
569 | .btnDelete {
570 | box-shadow: inset 0 1px var(--theme-shutdown-colour) !important;
571 | }
572 |
573 | #btnShutdown:hover,
574 | .btnDelete:hover,
575 | .notification_important,
576 | .MuiChip-filledError {
577 | color: var(--theme-text-colour) !important;
578 | background-color: var(--theme-shutdown-colour) !important;
579 | }
580 |
581 | .listItemIcon:not(.listItemIcon-transparent) {
582 | border-radius: var(--theme-roundness);
583 | }
584 |
585 | .sessionCardButtons {
586 | margin: .29em 0;
587 | }
588 |
589 | .dashboardSection .cardContent {
590 | border-top-left-radius: var(--theme-roundness);
591 | border-top-right-radius: var(--theme-roundness);
592 | }
593 |
594 | div[data-role="controlgroup"] a[data-role="button"]:first-child {
595 | border-bottom-left-radius: var(--theme-roundness);
596 | border-top-left-radius: var(--theme-roundness);
597 | }
598 |
599 | div[data-role="controlgroup"] a[data-role="button"]:last-child {
600 | border-bottom-right-radius: var(--theme-roundness);
601 | border-top-right-radius: var(--theme-roundness);
602 | }
603 |
604 | .dashboardColumn {
605 | flex-shrink: inherit;
606 | }
607 |
608 | /* Base Colours */
609 |
610 | .selectLabelFocused,
611 | .textareaLabelFocused,
612 | .inputLabelFocused,
613 | .mdl-slider,
614 | .metadataSidebarIcon,
615 | .button-link,
616 | .guide-date-tab-button.emby-tab-button-active,
617 | .guide-date-tab-button:focus,
618 | #divRunningTasks span,
619 | .MuiAlert-icon,
620 | .listItemBodyText span {
621 | color: var(--theme-text-colour) !important;
622 | }
623 |
624 | .emby-checkbox:checked + span + .checkboxOutline,
625 | .listItemIcon:not(
626 | .listItemIcon-transparent,
627 | .notification_important,
628 | .notifications
629 | ),
630 | .guide-channelHeaderCell:focus,
631 | .programCell:focus,
632 | .emby-button.show-focus:focus,
633 | ::selection,
634 | div[data-role="controlgroup"] a.ui-btn-active,
635 | .MuiAvatar-root,
636 | .selectionCommandsPanel {
637 | background-color: var(--theme-base-colour) !important;
638 | }
639 |
640 | .emby-checkbox + span + .checkboxOutline,
641 | .emby-checkbox:checked + span + .checkboxOutline,
642 | .emby-checkbox:focus:not(:checked) + span + .checkboxOutline,
643 | .mdl-spinner__layer-1,
644 | .mdl-spinner__layer-2,
645 | .mdl-spinner__layer-3,
646 | .mdl-spinner__layer-4 {
647 | border-color: var(--theme-base-colour) !important;
648 | }
649 |
650 | .mdl-slider {
651 | -webkit-appearance: none;
652 | appearance: none;
653 | width: 100%;
654 | background: transparent;
655 | }
656 |
657 | .mdl-slider::-webkit-slider-thumb {
658 | -webkit-appearance: none;
659 | appearance: none;
660 | width: 0;
661 | height: 0;
662 | background: transparent;
663 | cursor: pointer;
664 | }
665 |
666 | .mdl-slider::-moz-range-thumb {
667 | width: 0;
668 | height: 0;
669 | background: transparent;
670 | cursor: pointer;
671 | }
672 |
673 | .mdl-slider::-ms-thumb {
674 | width: 0;
675 | height: 0;
676 | background: transparent;
677 | cursor: pointer;
678 | }
679 |
680 | .mdl-slider-background-flex,
681 | .mdl-slider-background-lower,
682 | .mdl-slider-background-upper {
683 | border-radius: var(--theme-roundness);
684 | box-shadow: inset 0 1px var(--theme-menu-shadow-colour);
685 | height: 10px;
686 | }
687 |
688 | /* Chapter Markers */
689 | .sliderMarkerContainer {
690 | position: absolute;
691 | top: 0;
692 | left: 0;
693 | width: 100%;
694 | height: 10px;
695 | pointer-events: none;
696 | z-index: 1;
697 | }
698 |
699 | .sliderMarker {
700 | position: absolute;
701 | top: 0;
702 | width: 2px;
703 | height: 10px;
704 | background-color: var(--theme-chapter-marker-colour);
705 | opacity: 0.6;
706 | border-radius: 1px;
707 | pointer-events: auto;
708 | cursor: pointer;
709 | transition: opacity 0.2s ease, width 0.2s ease, background-color 0.2s ease;
710 | }
711 |
712 | .sliderMarker.unwatched {
713 | background-color: var(--theme-chapter-marker-colour);
714 | }
715 |
716 | .sliderMarker.watched {
717 | background-color: var(--theme-chapter-marker-watched-colour);
718 | }
719 |
720 | .mdl-slider-background-upper {
721 | margin-left: -3px;
722 | }
723 |
724 | .mdl-slider-background-flex-container {
725 | top: 5px;
726 | }
727 |
728 | .innerCardFooter .itemProgressBarForeground,
729 | .playbackProgress > div,
730 | .mdl-slider-background-lower,
731 | .iconOsdProgressInner,
732 | .taskProgressInner,
733 | progress {
734 | background-color: var(--theme-progress-bar-colour) !important;
735 | }
736 |
737 | /* These need to remain separate for browser compatibility */
738 | progress::-moz-progress-bar {
739 | background-color: var(--theme-progress-bar-colour);
740 | }
741 | progress::-webkit-progress-bar {
742 | background-color: var(--theme-progress-bar-colour);
743 | }
744 | progress::-ms-thumb {
745 | background-color: var(--theme-progress-bar-colour);
746 | }
747 |
748 | .transcodingProgress > div {
749 | background-color: var(--theme-progress-bar-transcoding-colour) !important;
750 | }
751 |
752 | .innerCardFooter .itemProgressBar,
753 | .backgroundProgress > div,
754 | .mdl-slider-background-flex,
755 | .taskProgressOuter,
756 | progress {
757 | background-color: var(--theme-progress-bar-background-colour) !important;
758 | }
759 |
760 | .layout-desktop .dashboardDocument .content-primary:not(.layout-desktop #dashboardPage .content-primary) {
761 | padding-left: 2.5em;
762 | padding-right: 2.5em;
763 | }
764 |
765 | [dir="ltr"] .formDialogHeaderTitle:first-child {
766 | margin-left: unset;
767 | }
768 |
769 | /* Login Form */
770 |
771 | #loginPage {
772 | background-color: var(--theme-menu-background-colour);
773 | border-radius: var(--theme-roundness);
774 | box-shadow: inset 0 1px var(--theme-menu-shadow-colour);
775 | padding: unset !important;
776 | max-width: 750px;
777 | max-height: 500px;
778 | margin: 150px auto 0;
779 | }
780 |
781 | .manualLoginForm .raised.button-submit.block.emby-button {
782 | margin-bottom: -3px;
783 | }
784 |
785 | .chapterThumbTextContainer {
786 | width: fit-content;
787 | margin: auto;
788 | }
789 |
790 | .chapterThumbText {
791 | width: fit-content;
792 | }
793 |
--------------------------------------------------------------------------------