/* ============================================================================ Halo für Jellyfin Web ---------------------------------------------------------------------------- Bringt Jellyfins Weboberfläche auf die Farben, Schrift und Formen der Halo-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. */ --halo-accent: #C04AC9; /* ---- Die Flächen der App, von hinten nach vorn ---------------------- */ --halo-canvas: #0B0B0D; /* Seitenhintergrund */ --halo-surface: #141417; /* Karten, Kopfbereiche */ --halo-elevated: #1D1D21; /* Blätter, Menüs */ --halo-placeholder: #26262B; /* Platzhalter, gedrückte Zustände */ --halo-text: #F5F5F7; --halo-text-secondary: #A0A0A8; --halo-text-muted: #6E6E76; --halo-destructive: #E5484D; --halo-separator: rgba(255, 255, 255, 0.10); /* ---- Formen --------------------------------------------------------- */ --halo-radius-card: 8px; --halo-radius-control: 10px; --halo-radius-sheet: 16px; --halo-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. */ --halo-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(--halo-canvas); --jf-palette-background-defaultChannel: 11 11 13; --jf-palette-background-paper: var(--halo-surface); --jf-palette-background-paperChannel: 20 20 23; --jf-palette-primary-main: var(--halo-accent); --jf-palette-primary-dark: var(--halo-accent); --jf-palette-primary-light: var(--halo-accent); --jf-palette-secondary-main: var(--halo-accent); --jf-palette-secondary-dark: var(--halo-accent); --jf-palette-secondary-light: var(--halo-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(--halo-text); --jf-palette-text-secondary: var(--halo-text-secondary); --jf-palette-text-disabled: var(--halo-text-muted); --jf-palette-text-icon: var(--halo-text-secondary); --jf-palette-divider: var(--halo-separator); --jf-palette-error-main: var(--halo-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(--halo-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(--halo-radius-card); --jf-shape-borderRadius: var(--halo-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(--halo-canvas) !important; font-family: var(--halo-font) !important; color: var(--halo-text); } body, button, input, select, textarea, .emby-button, .emby-input, .emby-select, .cardText, .sectionTitle { font-family: var(--halo-font) !important; } .backgroundContainer, .mainAnimatedPage { background-color: var(--halo-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(--halo-separator); border-radius: var(--halo-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(--halo-surface) !important; border-right: 1px solid var(--halo-separator); } .navMenuOption { border-radius: var(--halo-radius-control); margin: 2px 8px; } .navMenuOption-selected { background: var(--halo-elevated) !important; color: var(--halo-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(--halo-radius-card) !important; } .cardBox { margin: 0.5em !important; } .cardText { color: var(--halo-text); } .cardText-secondary { color: var(--halo-text-secondary); } .defaultCardBackground, .defaultCardBackground1, .defaultCardBackground2, .defaultCardBackground3, .defaultCardBackground4, .defaultCardBackground5 { background-color: var(--halo-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(--halo-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(--halo-radius-control) !important; font-family: var(--halo-font) !important; } .emby-button.raised { background: var(--halo-elevated); color: var(--halo-text); } .emby-button.raised.button-submit, .button-submit { background: var(--halo-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(--halo-elevated) !important; border: 1px solid var(--halo-separator) !important; border-radius: var(--halo-radius-control) !important; color: var(--halo-text) !important; } .emby-input:focus, .emby-select:focus { border-color: var(--halo-accent) !important; outline: none; } .inputLabel, .selectLabel, .fieldDescription { color: var(--halo-text-secondary) !important; } /* ---- Blätter, Menüs, Dialoge --------------------------------------------- */ .dialog, .formDialog, .actionSheet, .paper-icon-button-light + .actionSheet { background-color: var(--halo-elevated) !important; border-radius: var(--halo-radius-sheet) !important; border: 1px solid var(--halo-separator); } .actionSheetMenuItem:hover, .listItem:hover { background-color: var(--jf-palette-action-hover) !important; } /* ---- Detailseite --------------------------------------------------------- */ .detailPagePrimaryContainer, .detailPageSecondaryContainer, .detailRibbon { background: transparent !important; } .detailSectionContent, .detailTableBodyCell { color: var(--halo-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(--halo-text) !important; font-weight: 600; letter-spacing: -0.01em; } /* ---- Trennlinien und Kleinkram ------------------------------------------- */ .listItem-border, .detailTableBodyCell, hr { border-color: var(--halo-separator) !important; } ::selection { background: var(--halo-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); }