Für den Zugang von Windows aus, wo es keine App gibt und auch keine geben wird. Ein Kleid, kein Umbau. Variablennamen und Klassen stammen aus einer laufenden Jellyfin-Instanz, nicht aus dem Gedächtnis: Jellyfin baut auf einer MUI-Palette auf, und wer die umbiegt, erwischt auch Bauteile, die dieses CSS gar nicht kennt. Direkt überschrieben wird nur dort, wo Jellyfin an der Palette vorbei setzt — der Seitenhintergrund und die Kartenrundung tun das. Live gegen die öffentliche Jellyfin-Demo geprüft: Farben, Systemschrift, Kartenrundung, Akzent und die schwebende Kopfleiste greifen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
335 lines
11 KiB
CSS
335 lines
11 KiB
CSS
/* ============================================================================
|
|
Flixy für Jellyfin Web
|
|
----------------------------------------------------------------------------
|
|
Bringt Jellyfins Weboberfläche auf die Farben, Schrift und Formen der
|
|
Flixy-App. Es ist ein Kleid, kein Umbau: die Oberfläche bleibt Jellyfins,
|
|
sie sieht nur anders aus.
|
|
|
|
EINBAUEN
|
|
Jellyfin-Dashboard → Allgemein → „Benutzerdefiniertes CSS“ — alles hier
|
|
hineinkopieren, speichern, Seite neu laden. Gilt serverweit für alle
|
|
Browser, also auch auf Windows. Wieder loswerden: Feld leeren.
|
|
|
|
AUFGEBAUT AUF MESSUNG, NICHT AUF VERMUTUNG
|
|
Die Variablennamen und Klassen stammen aus einer laufenden Jellyfin-
|
|
Instanz (Stand 09/2026), nicht aus dem Gedächtnis. Der größte Teil der
|
|
Wirkung entsteht dadurch, dass Jellyfins **eigene** Farbvariablen
|
|
umgebogen werden — das hält das Ganze kurz und überlebt Updates besser
|
|
als eine Sammlung einzeln überschriebener Regeln.
|
|
========================================================================= */
|
|
|
|
:root {
|
|
/* ---- Die Akzentfarbe -----------------------------------------------
|
|
Zum Wechseln nur diese eine Zeile ändern. Die Palette der App:
|
|
Ember #E5484D · Tangerine #F76B15 · Amber #FFB224 · Lime #99D52A
|
|
Mint #3DD68C · Teal #12A594 · Sky #52A9FF · Indigo #7C77E8
|
|
Orchid #C04AC9 · Rose #F76190
|
|
Voreingestellt ist Orchid — die Farbe, die auf dem iPad eingestellt
|
|
ist. Die App selbst kommt ab Werk mit Mint. */
|
|
--flixy-accent: #C04AC9;
|
|
|
|
/* ---- Die Flächen der App, von hinten nach vorn ---------------------- */
|
|
--flixy-canvas: #0B0B0D; /* Seitenhintergrund */
|
|
--flixy-surface: #141417; /* Karten, Kopfbereiche */
|
|
--flixy-elevated: #1D1D21; /* Blätter, Menüs */
|
|
--flixy-placeholder: #26262B; /* Platzhalter, gedrückte Zustände */
|
|
|
|
--flixy-text: #F5F5F7;
|
|
--flixy-text-secondary: #A0A0A8;
|
|
--flixy-text-muted: #6E6E76;
|
|
--flixy-destructive: #E5484D;
|
|
--flixy-separator: rgba(255, 255, 255, 0.10);
|
|
|
|
/* ---- Formen --------------------------------------------------------- */
|
|
--flixy-radius-card: 8px;
|
|
--flixy-radius-control: 10px;
|
|
--flixy-radius-sheet: 16px;
|
|
--flixy-radius-panel: 22px; /* die schwebende Leiste */
|
|
|
|
/* ---- Schrift --------------------------------------------------------
|
|
Der größte einzelne Hebel. Jellyfin liefert Noto Sans aus; die
|
|
Systemschrift macht aus derselben Seite sofort eine, die auf den
|
|
Rechner gehört — SF auf Mac und iPhone, Segoe UI Variable auf
|
|
Windows 11. */
|
|
--flixy-font: -apple-system, BlinkMacSystemFont, "SF Pro Text",
|
|
"Segoe UI Variable Text", "Segoe UI", system-ui,
|
|
Roboto, "Helvetica Neue", sans-serif;
|
|
|
|
/* ---- Jellyfins eigene Variablen umbiegen ---------------------------
|
|
Hier entsteht der Großteil der Wirkung: Jellyfin baut auf einer
|
|
MUI-Palette auf, und wer die verstellt, verstellt alles, was darauf
|
|
aufsetzt — inklusive Bauteilen, die dieses CSS gar nicht kennt. */
|
|
--jf-palette-background-default: var(--flixy-canvas);
|
|
--jf-palette-background-defaultChannel: 11 11 13;
|
|
--jf-palette-background-paper: var(--flixy-surface);
|
|
--jf-palette-background-paperChannel: 20 20 23;
|
|
|
|
--jf-palette-primary-main: var(--flixy-accent);
|
|
--jf-palette-primary-dark: var(--flixy-accent);
|
|
--jf-palette-primary-light: var(--flixy-accent);
|
|
--jf-palette-secondary-main: var(--flixy-accent);
|
|
--jf-palette-secondary-dark: var(--flixy-accent);
|
|
--jf-palette-secondary-light: var(--flixy-accent);
|
|
/* Schrift auf dem Akzent: hell, weil die Palette der App durchweg
|
|
kräftige Farben hat. Bei einem hellen Akzent (Amber, Lime) hier auf
|
|
#101013 stellen, sonst verschwindet die Beschriftung. */
|
|
--jf-palette-primary-contrastText: #FFFFFF;
|
|
--jf-palette-secondary-contrastText: #FFFFFF;
|
|
|
|
--jf-palette-text-primary: var(--flixy-text);
|
|
--jf-palette-text-secondary: var(--flixy-text-secondary);
|
|
--jf-palette-text-disabled: var(--flixy-text-muted);
|
|
--jf-palette-text-icon: var(--flixy-text-secondary);
|
|
--jf-palette-divider: var(--flixy-separator);
|
|
|
|
--jf-palette-error-main: var(--flixy-destructive);
|
|
--jf-palette-error-dark: #B4373B;
|
|
--jf-palette-error-light: #EC6E72;
|
|
|
|
--jf-palette-action-hover: rgba(255, 255, 255, 0.06);
|
|
--jf-palette-action-selected: rgba(255, 255, 255, 0.12);
|
|
--jf-palette-action-disabled: var(--flixy-text-muted);
|
|
|
|
/* Die Kopfleiste trägt die Insel — sie selbst bleibt durchsichtig. */
|
|
--jf-palette-AppBar-defaultBg: transparent;
|
|
--jf-palette-AppBar-darkBg: transparent;
|
|
|
|
--jf-card-borderRadius: var(--flixy-radius-card);
|
|
--jf-shape-borderRadius: var(--flixy-radius-control);
|
|
}
|
|
|
|
/* ---- Grundfläche und Schrift --------------------------------------------
|
|
`html` bekommt seinen Hintergrund bei Jellyfin unmittelbar gesetzt und
|
|
nicht über die Palette — deshalb steht er hier noch einmal ausdrücklich. */
|
|
html {
|
|
background-color: var(--flixy-canvas) !important;
|
|
font-family: var(--flixy-font) !important;
|
|
color: var(--flixy-text);
|
|
}
|
|
|
|
body,
|
|
button,
|
|
input,
|
|
select,
|
|
textarea,
|
|
.emby-button,
|
|
.emby-input,
|
|
.emby-select,
|
|
.cardText,
|
|
.sectionTitle {
|
|
font-family: var(--flixy-font) !important;
|
|
}
|
|
|
|
.backgroundContainer,
|
|
.mainAnimatedPage {
|
|
background-color: var(--flixy-canvas) !important;
|
|
}
|
|
|
|
/* ---- Die Kopfleiste als schwebende Insel --------------------------------
|
|
Das Merkmal der App: die Navigation ist eine Fläche mit Abstand ringsum,
|
|
nicht ein Balken, der am Rand klebt. Der Inhalt läuft dahinter durch.
|
|
|
|
`backdrop-filter` ist der Kern — und der Grund, warum es auf Safari und
|
|
Chrome überzeugender aussieht als auf älteren Firefox-Fassungen. Wo er
|
|
fehlt, bleibt eine schlicht gefüllte Fläche; unschön ist das nicht. */
|
|
.skinHeader {
|
|
background: rgba(20, 20, 23, 0.72) !important;
|
|
backdrop-filter: saturate(180%) blur(20px);
|
|
-webkit-backdrop-filter: saturate(180%) blur(20px);
|
|
border: 1px solid var(--flixy-separator);
|
|
border-radius: var(--flixy-radius-panel);
|
|
margin: 10px 12px 0;
|
|
width: calc(100% - 24px);
|
|
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.45);
|
|
}
|
|
|
|
.skinHeader-withBackground {
|
|
background: rgba(20, 20, 23, 0.72) !important;
|
|
}
|
|
|
|
/* ---- Die Seitenleiste ---------------------------------------------------- */
|
|
.mainDrawer {
|
|
background-color: var(--flixy-surface) !important;
|
|
border-right: 1px solid var(--flixy-separator);
|
|
}
|
|
|
|
.navMenuOption {
|
|
border-radius: var(--flixy-radius-control);
|
|
margin: 2px 8px;
|
|
}
|
|
|
|
.navMenuOption-selected {
|
|
background: var(--flixy-elevated) !important;
|
|
color: var(--flixy-accent) !important;
|
|
}
|
|
|
|
/* ---- Karten -------------------------------------------------------------
|
|
Die Poster sind das, was man auf einer Startseite hauptsächlich sieht;
|
|
ihre Rundung bestimmt den Eindruck stärker als jede Farbe. Acht Punkt,
|
|
wie in der App. */
|
|
.cardImageContainer,
|
|
.cardContent,
|
|
.cardScalable,
|
|
.cardOverlayContainer {
|
|
border-radius: var(--flixy-radius-card) !important;
|
|
}
|
|
|
|
.cardBox {
|
|
margin: 0.5em !important;
|
|
}
|
|
|
|
.cardText {
|
|
color: var(--flixy-text);
|
|
}
|
|
|
|
.cardText-secondary {
|
|
color: var(--flixy-text-secondary);
|
|
}
|
|
|
|
.defaultCardBackground,
|
|
.defaultCardBackground1,
|
|
.defaultCardBackground2,
|
|
.defaultCardBackground3,
|
|
.defaultCardBackground4,
|
|
.defaultCardBackground5 {
|
|
background-color: var(--flixy-placeholder) !important;
|
|
}
|
|
|
|
/* Der Fortschrittsbalken auf angefangenen Titeln — in der App trägt er den
|
|
Akzent, und er ist dünner als Jellyfins Voreinstellung. */
|
|
.itemProgressBarForeground {
|
|
background-color: var(--flixy-accent) !important;
|
|
}
|
|
|
|
.itemProgressBar {
|
|
height: 3px !important;
|
|
border-radius: 2px;
|
|
background-color: rgba(255, 255, 255, 0.18) !important;
|
|
}
|
|
|
|
/* ---- Knöpfe -------------------------------------------------------------- */
|
|
.emby-button,
|
|
.button-flat,
|
|
.detailButton {
|
|
border-radius: var(--flixy-radius-control) !important;
|
|
font-family: var(--flixy-font) !important;
|
|
}
|
|
|
|
.emby-button.raised {
|
|
background: var(--flixy-elevated);
|
|
color: var(--flixy-text);
|
|
}
|
|
|
|
.emby-button.raised.button-submit,
|
|
.button-submit {
|
|
background: var(--flixy-accent) !important;
|
|
color: #FFFFFF !important;
|
|
}
|
|
|
|
/* Die Kapselform der App für die Hauptknöpfe einer Detailseite. */
|
|
.detailPagePrimaryContainer .emby-button,
|
|
.mainDetailButtons .emby-button {
|
|
border-radius: 999px !important;
|
|
}
|
|
|
|
/* ---- Eingabefelder ------------------------------------------------------- */
|
|
.emby-input,
|
|
.emby-select,
|
|
.emby-textarea {
|
|
background-color: var(--flixy-elevated) !important;
|
|
border: 1px solid var(--flixy-separator) !important;
|
|
border-radius: var(--flixy-radius-control) !important;
|
|
color: var(--flixy-text) !important;
|
|
}
|
|
|
|
.emby-input:focus,
|
|
.emby-select:focus {
|
|
border-color: var(--flixy-accent) !important;
|
|
outline: none;
|
|
}
|
|
|
|
.inputLabel,
|
|
.selectLabel,
|
|
.fieldDescription {
|
|
color: var(--flixy-text-secondary) !important;
|
|
}
|
|
|
|
/* ---- Blätter, Menüs, Dialoge --------------------------------------------- */
|
|
.dialog,
|
|
.formDialog,
|
|
.actionSheet,
|
|
.paper-icon-button-light + .actionSheet {
|
|
background-color: var(--flixy-elevated) !important;
|
|
border-radius: var(--flixy-radius-sheet) !important;
|
|
border: 1px solid var(--flixy-separator);
|
|
}
|
|
|
|
.actionSheetMenuItem:hover,
|
|
.listItem:hover {
|
|
background-color: var(--jf-palette-action-hover) !important;
|
|
}
|
|
|
|
/* ---- Detailseite --------------------------------------------------------- */
|
|
.detailPagePrimaryContainer,
|
|
.detailPageSecondaryContainer,
|
|
.detailRibbon {
|
|
background: transparent !important;
|
|
}
|
|
|
|
.detailSectionContent,
|
|
.detailTableBodyCell {
|
|
color: var(--flixy-text-secondary);
|
|
}
|
|
|
|
/* Das Hintergrundbild soll nach unten in die Seitenfarbe auslaufen, statt an
|
|
einer Kante aufzuhören — dieselbe Verlaufsidee wie im Aufmacher der App. */
|
|
.itemBackdrop {
|
|
-webkit-mask-image: linear-gradient(to bottom,
|
|
rgba(0, 0, 0, 1) 0%,
|
|
rgba(0, 0, 0, 0.85) 45%,
|
|
rgba(0, 0, 0, 0) 100%);
|
|
mask-image: linear-gradient(to bottom,
|
|
rgba(0, 0, 0, 1) 0%,
|
|
rgba(0, 0, 0, 0.85) 45%,
|
|
rgba(0, 0, 0, 0) 100%);
|
|
}
|
|
|
|
/* ---- Überschriften ------------------------------------------------------- */
|
|
.sectionTitle {
|
|
color: var(--flixy-text) !important;
|
|
font-weight: 600;
|
|
letter-spacing: -0.01em;
|
|
}
|
|
|
|
/* ---- Trennlinien und Kleinkram ------------------------------------------- */
|
|
.listItem-border,
|
|
.detailTableBodyCell,
|
|
hr {
|
|
border-color: var(--flixy-separator) !important;
|
|
}
|
|
|
|
::selection {
|
|
background: var(--flixy-accent);
|
|
color: #FFFFFF;
|
|
}
|
|
|
|
/* Die Bildlaufleisten dunkel halten — eine helle Leiste am Rand ist das
|
|
Erste, was eine sonst dunkle Seite verrät. */
|
|
::-webkit-scrollbar {
|
|
width: 10px;
|
|
height: 10px;
|
|
}
|
|
|
|
::-webkit-scrollbar-track {
|
|
background: transparent;
|
|
}
|
|
|
|
::-webkit-scrollbar-thumb {
|
|
background: rgba(255, 255, 255, 0.14);
|
|
border-radius: 999px;
|
|
}
|
|
|
|
::-webkit-scrollbar-thumb:hover {
|
|
background: rgba(255, 255, 255, 0.22);
|
|
}
|