A companion stylesheet that makes ElegantFin work on Jellyfin 12's Modern layout, so you don't have to switch Display Mode back to Legacy to keep your theme.
It layers on top of upstream ElegantFin rather than forking it, so everything that still works keeps flowing from upstream.
I made this for myself because switching Display Mode back to Legacy on every device got annoying enough to fix.
It's meant to be temporary. ElegantFin's maintainer has declined to support the Modern UI for now, which is fair: the Jellyfin team is still actively developing it, and it's a moving target. This fills the gap until either the UI settles down or upstream takes it on. When that happens, this repo has done its job.
It is not a fork and not a replacement. It bundles none of ElegantFin's code; it only layers on top. The design work is all lscambo13's, and every update to the theme itself still comes from them.
ElegantFin on Jellyfin 12's Modern layout, without this sheet and with it. The untreated side pushes the poster grid down the page and paints the active tab and Play All in MUI's indigo instead of the theme's own colours.
Desktop: app bar, home, library, sort menu, item details, episode, player, login
| Before | After | |
|---|---|---|
| App bar | ![]() | ![]() |
| Home | ![]() | ![]() |
| Library | ![]() | ![]() |
| Sort menu | ![]() | ![]() |
| Item details | ![]() | ![]() |
| Episode | ![]() | ![]() |
| Player | ![]() | ![]() |
| Login | ![]() | ![]() |
Mobile: app bar, home, library, sort menu, item details, episode, drawer, player, login
| Before | After | |
|---|---|---|
| App bar | ![]() | ![]() |
| Home | ![]() | ![]() |
| Library | ![]() | ![]() |
| Sort menu | ![]() | ![]() |
| Item details | ![]() | ![]() |
| Episode | ![]() | ![]() |
| Drawer | ![]() | ![]() |
| Player | ![]() | ![]() |
| Login | ![]() | ![]() |
Paste into Dashboard → General → Custom CSS (server-wide) or Settings → Display → Custom CSS (just you):
/* Main ElegantFin CSS */
@import url("https://cdn.jsdelivr.net/gh/lscambo13/ElegantFin@main/Theme/ElegantFin-jellyfin-theme-build-latest-minified.css");
/* ElegantFin Media Bar CSS */
@import url("https://cdn.jsdelivr.net/gh/lscambo13/ElegantFin@main/Theme/assets/add-ons/media-bar-plugin-support-latest-min.css");
/* ElegantFin 12 Companion CSS */
@import url("https://cdn.jsdelivr.net/gh/mihaif7/elegantfin-jf12@main/Theme/ElegantFin-jf12-modern-latest.css");Line 1 is ElegantFin itself. Line 2 is its Media Bar add-on, it's harmless without the Media Bar plugin, needed with it. Line 3 is this sheet, and it has to come last.
If you'd rather not import from a URL, paste the contents of
ElegantFin-jf12-modern-latest.css
in place of that third line.
Optional sheets that load after the companion one. Import none of them and nothing changes.
/* Classic navbar: the server button as a library pill, as it was before v26.09.18 */
@import url("https://cdn.jsdelivr.net/gh/mihaif7/elegantfin-jf12@main/Theme/assets/add-ons/classic-navbar-latest.css");| Add-on | What it does |
|---|---|
classic-navbar |
Puts the app bar's server button back to a library pill: the fill, the 400 weight, the glyph-sized mark and the pills' hover it had before v26.09.18 made a masthead of it. |
| Without it | With classic-navbar |
|---|---|
![]() |
![]() |
Plugins this sheet styles for the Modern layout:
- Media Bar, with or without ElegantFin's Media Bar add-on
- Media Bar Enhanced, with or without ElegantFin's Media Bar add-on
- Jellyfin Enhanced
- InPlayerEpisodePreview
- Plugin Update Notifier
- Jellyfin Episodes Ratings Grid, loaded through the JavaScript Injector
The URL above tracks the newest release, so updates arrive on their own, but your browser caches the file for up to a week, so hard-refresh to pull one in sooner. What changed in each version is on the releases page.
To pin a version instead, name it in the URL. It will then never change:
@import url("https://cdn.jsdelivr.net/gh/mihaif7/[email protected]/Theme/ElegantFin-jf12-modern-v26.09.10.css");Override any of these in your own Custom CSS, after the imports:
:root {
--ef12-appBarHeight: 3.5rem;
--ef12-navPillBackground: none;
}| Variable | Default | What it does |
|---|---|---|
--ef12-appBarHeight |
4rem |
App bar height |
--ef12-appBarHeightDesktop |
4.5rem |
App bar height, desktop layout only |
--ef12-libraryToolbarHeight |
3.75rem |
Secondary toolbar on library pages |
--ef12-libraryToolbarGap |
0.75rem |
Space under the wrapped toolbar row on mobile |
--ef12-appBarFade |
2.5rem |
How far the bar's fill carries below itself when scrolled; 0 for a hard edge |
--ef12-navRadius |
1rem |
Library nav button corners |
--ef12-navPaddingInline |
1.1rem |
Horizontal room inside the nav pills |
--ef12-navGap |
0.6rem |
Gap between adjacent nav pills |
--ef12-navPillBackground |
--darkerGradientPointAlpha |
none for flat nav buttons |
--ef12-iconButtonGap |
0.58rem |
Gap between header icon buttons |
--ef12-appBarIconSize |
1.25rem |
App bar icon glyph size |
--ef12-surfaceRadius |
1rem |
Menu / popover / dialog corners |
--ef12-surfaceBlur |
--blurDefault |
Blur behind menus and dialogs; none to disable |
--ef12-menuGap |
0.5rem |
Space between a dropdown and the control that opened it |
--ef12-userMenuFontSize |
1.15rem |
Avatar menu type on narrow viewports, where MUI holds the rows at 48px |
--ef12-osdToolbarHeight |
5rem |
Toolbar height inside the video OSD header |
--ef12-episodePreviewIcon |
"video_library" |
Glyph for the in-player episode picker |
--ef12-linkMarkHeight |
1.4cap |
Logo mark height in the external-links row |
--ef12-detailsSectionGap |
15px |
Space between an item page's sections |
--ef12-detailsSectionGapDesktop |
23px |
The same gap, desktop layout only |
--ef12-mediaBarHeight |
62vh |
Media Bar only: bar height, and what the home sections clear |
--ef12-mediaBarGap |
1.25rem |
Media Bar only: the gap above and below the bar |
--ef12-itemBarEnter |
0.35s |
How long an item page's app bar takes to fade up to home's background on scroll |
--ef12-ratingsGridOpen |
0.24s |
Episodes Ratings Grid only: how long its card takes to unfold; 0s for no animation |
Upstream ElegantFin's own knobs still work too, including the solid and fully transparent app bar presets from its README.
- Jellyfin 12.0, Modern layout, desktop and mobile.
- ElegantFin v26.09.05 or later.
- Safe to leave installed on Legacy, everything structural is scoped with
:has(.MuiAppBar-root), which only matches the Modern layout. - Non-dark colour schemes fall back to ElegantFin's dark tokens, as they do upstream.
If content sits far down the page under a large gap, or buttons come out indigo, this sheet isn't loading last. Check the import order.
ElegantFin by lscambo13 - If you like the design go and thank them for the effort :)
GPL-2.0, matching upstream.


































