/* reskin-tv.css — §RESKIN-TV (Cloder 2026-07-23)
   ────────────────────────────────────────────────────────────────────────────
   TV-Startseite nach publicore-reskin-preview-tv_2.html. Eigene, disjunkte Ebene
   NEBEN dem Desktop-Reskin (reskin-startseite.css): gescoped auf `body.app-tv`
   (echter TV-Marker, App.IS_TV = Tizen/webOS — NICHT app-desktop, das auf einem
   echten TV gar nicht gesetzt ist). Nutzt die GLOBALE --pc-*-Token-Ebene aus
   reskin-startseite.css (themeabhängig, geräteunabhängig) → Farben stimmen von
   selbst; hier nur Layout/Optik. `!important` + hohe Spezifität, weil die Theme-
   CSS (theme-*.css) für TV eigene Regeln setzt und teils NACH dieser Datei lädt.

   Optische Wahrheit: publicore-reskin-preview-tv_2.html. Fokusring = HOSTERFARBE
   der markierten Kachel (var(--card-glow), pro Kachel inline gesetzt). Kein Deploy
   ohne User-Go (BUG-13).
   ════════════════════════════════════════════════════════════════════════════ */

/* ── 1) Sidebar-Nav (250px-Kontext, größere TV-Items) ───────────────────────── */
body.app-tv #sidebar .nav-item {
  flex-direction: row !important;
  align-items: center !important;
  justify-content: flex-start !important;
  text-align: left !important;
  height: 46px !important;
  gap: 14px !important;
  padding: 0 14px !important;
  border-radius: 11px !important;
  color: var(--pc-muted) !important;
  margin-bottom: 3px !important;
}
body.app-tv #sidebar .nav-item .nav-label {
  /* #493: Nav-Text an die Icon-Größe (23px) angeglichen — 16→20px, 500→600 für
     bessere Lesbarkeit auf 3 m TV-Abstand (Icon davor bleibt 23px, s. .nav-icon). */
  font-size: 20px !important; font-weight: 600 !important; line-height: 1.2 !important;
}
body.app-tv #sidebar .nav-icon { width: 23px !important; height: 23px !important; color: inherit !important; }
/* Aktiv = getönte Fläche + Akzent-Streifen (kein Puls-Glow), auch wenn zugleich .focused. */
body.app-tv #sidebar .nav-item.active,
body.app-tv #sidebar .nav-item.active.focused {
  background: var(--pc-active) !important;
  border-color: transparent !important;
  color: var(--pc-text) !important;
  box-shadow: inset 4px 0 0 var(--pc-accent) !important;
  animation: none !important;
}
body.app-tv #sidebar .nav-item.active .nav-icon,
body.app-tv #sidebar .nav-item.active.focused .nav-icon { color: var(--pc-text) !important; }
/* D-Pad-Fokus auf ein Nav-Item: Akzent-Umrandung. */
body.app-tv #sidebar .nav-item.focused:not(.active) {
  background: var(--pc-soft) !important;
  box-shadow: inset 0 0 0 2px var(--pc-accent) !important;
  color: var(--pc-text) !important;
}

/* ── 2) Topbar: Suchleiste + Aktionen ───────────────────────────────────────── */
body.app-tv #search-bar {
  background: var(--pc-surface2) !important;
  border: 1px solid var(--pc-border) !important;
  border-radius: 11px !important;
  box-shadow: none !important; animation: none !important;
  color: var(--pc-muted) !important;
}
body.app-tv #search-bar.focused {
  border-color: var(--pc-accent) !important;
  box-shadow: 0 0 0 1px var(--pc-accent), 0 0 18px var(--pc-glow) !important;
}
body.app-tv #header-actions { display: flex !important; align-items: center !important; gap: 16px !important; }

/* ── 3) Connect-Banner (nur ohne verbundenes Konto sichtbar; Logik in App) ─────
   UI-TV-CONNECT-BANNER-FOCUS: Die Theme-Dateien blenden den Banner auf dem TV
   hart aus (`body.app-tv .connect-banner { display:none !important }`) — die
   Begruendung stand in core.js: er war per D-Pad nicht erreichbar und damit ein
   nicht bedienbarer Fremdkoerper im Leanback-Grid. Diese Regeln hier waren
   dadurch bis jetzt tot. Mit der neuen Fokus-Zone 'connect' (core.js:
   App.connectBannerButtons) faellt der Grund weg → hier gezielt wieder
   einblenden. Hoehere Spezifitaet (#connect-banner + :not(.hidden)) als die
   Theme-Regel, aber `.hidden` (App.ConnectBanner.refresh) behaelt das letzte
   Wort — der Banner bleibt unsichtbar, sobald ein Konto verbunden, die
   Login-Wall aktiv oder er weggeklickt ist. */
body.app-tv #connect-banner {
  background: var(--pc-surface2) !important;
  border: 1px solid var(--pc-border) !important;
  border-radius: 12px !important;
  margin-bottom: 22px !important;
}
body.app-tv #connect-banner:not(.hidden) { display: flex !important; }
/* D-Pad-Fokus auf den beiden Knoepfen — dieselbe Sprache wie die Settings-Buttons
   (§20) und die Hoster-Chips: Akzentring + Glow, Schrift auf volle Textfarbe. */
body.app-tv #connect-banner .connect-banner-cta.focused,
body.app-tv #connect-banner .connect-banner-x.focused {
  border-color: var(--pc-accent) !important;
  color: var(--pc-text) !important;
  box-shadow: 0 0 0 2px var(--pc-accent), 0 0 18px var(--pc-glow) !important;
}
/* Der CTA ist der Primaer-Knopf (gefuellte Akzentflaeche) → dunkle Schrift
   beibehalten, sonst hell auf hell (gleiche Invertierung wie §20/§34). */
body.app-tv #connect-banner .connect-banner-cta {
  background: var(--pc-accent) !important;
  border: 1px solid var(--pc-accent) !important;
  color: #0a0c12 !important;
}
body.app-tv #connect-banner .connect-banner-cta.focused {
  color: #0a0c12 !important;
  box-shadow: 0 0 0 2px var(--pc-bg), 0 0 0 4px var(--pc-accent), 0 0 18px var(--pc-glow) !important;
}
/* TV-Lesbarkeit auf Sofa-Distanz. */
body.app-tv #connect-banner .connect-banner-title { font-size: 19px !important; }
body.app-tv #connect-banner .connect-banner-desc  { font-size: 15px !important; }
body.app-tv #connect-banner .connect-banner-cta   { font-size: 15px !important; padding: 10px 22px !important; }
body.app-tv #connect-banner .connect-banner-x     { font-size: 18px !important; min-width: 40px !important; min-height: 40px !important; }
/* Cyberpunk auf dem TV: Neon-Gelb wie Sidebar/Filter (§32). */
body.app-tv.theme-cyberpunk #connect-banner .connect-banner-cta {
  background: #faff00 !important; border-color: #faff00 !important; color: #12131a !important;
}
body.app-tv.theme-cyberpunk #connect-banner .connect-banner-cta.focused {
  color: #12131a !important;
  box-shadow: 0 0 0 2px var(--pc-bg), 0 0 0 4px #faff00, 0 0 18px rgba(250, 255, 0, 0.45) !important;
}
body.app-tv.theme-cyberpunk #connect-banner .connect-banner-x.focused {
  border-color: #faff00 !important;
  box-shadow: 0 0 0 2px #faff00, 0 0 18px rgba(250, 255, 0, 0.45) !important;
}

/* ── 4) Sektions-Segment „Alle | Live | Videos" ─────────────────────────────── */
body.app-tv #filter-tabs .filter-tab.active {
  background: var(--pc-accent) !important; color: #0a0c12 !important; border-color: var(--pc-accent) !important;
}
body.app-tv #filter-tabs .filter-tab.active svg { stroke: #0a0c12 !important; }
body.app-tv #filter-tabs .filter-tab:not(.active) {
  background: transparent !important; color: var(--pc-muted) !important;
}
body.app-tv #filter-tabs .filter-tab.focused {
  box-shadow: inset 0 0 0 2px var(--pc-accent) !important;
}

/* ── 5) Hoster-Chips (dunkle Flächen-Pillen, Logo im hosterfarbenen Quadrat) ──── */
body.app-tv #session-platform-bar .sc-bubble {
  background: var(--pc-surface) !important;
  border: 1.5px solid var(--pc-border) !important;
  color: var(--pc-text) !important;
  border-radius: 21px !important;
}
body.app-tv #session-platform-bar .sc-bubble.focused {
  border-color: var(--pc-accent) !important;
  box-shadow: 0 0 0 1px var(--pc-accent) !important;
}

/* ════════════════════════════════════════════════════════════════════════════
   #TVVP20 (User): GLOBALER, überall sichtbarer D-Pad-Fokus-Glow.
   Problem: die per-Component-Fokusringe nutzen `box-shadow: … var(--pc-accent)` —
   auf AKTIVEN/hellen Elementen (Hoster-Pillen & Filter-Tabs sind im aktiven Zustand
   akzentgefüllt) ist ein Akzent-Ring quasi unsichtbar („weiß auf weiß"), man sieht
   nicht, wo der D-Pad steht. Fix: ein ADDITIVER Glow über `filter: drop-shadow` —
   dieser wird von KEINER der ~30 bestehenden .focused-Regeln gesetzt (die nutzen
   box-shadow), kollidiert also nicht und legt sich global über ALLE fokussierten
   Elemente. drop-shadow umschließt die ELEMENT-FORM und leuchtet auf dem dunklen
   Seiten-Hintergrund UNABHÄNGIG von der Füllung → der Fokus ist überall sichtbar,
   auch auf akzentgefüllten Pillen/Tabs. Zweistufig: enger heller Akzent-Halo +
   weiterer weicher Glow. AUSGENOMMEN Kacheln (.video-card) — sie tragen ihren eigenen
   Thumbnail-Ring/Glow (reskin-tv.css:169), sollen laut User NICHT den globalen Glow. */
body.app-tv .focused:not(.video-card) {
  filter: drop-shadow(0 0 4px var(--pc-accent)) drop-shadow(0 0 9px var(--pc-glow)) !important;
}
/* #TVVP20-Fix: Die Hoster-/Filter-Pillen tragen aus #29 (BUG-FILTER-TAB-WHITE-ON-WHITE,
   ui-auth74-73.css) ein `filter: none !important` MIT ID-Spezifität
   (`#session-platform-bar .sc-bubble`, (0,1,1,0)) → der globale Glow oben (nur Klassen,
   (0,0,3,1)) verliert dagegen und die fokussierte Pille bleibt „unsichtbar" (genau das
   User-Symptom: weißer Rahmen auf weißer aktiver Pille). Deshalb HIER ein spezifitäts-
   stärkerer Glow-Override MIT der Container-ID ((0,1,3,1) schlägt (0,1,1,0)), NUR im
   .focused-Zustand — das unbedingte filter:none (Kontrast-Fix) bleibt außerhalb Fokus
   unangetastet. Deckt alle Bubble-Container ab (Home/Shorts/Clips/Subs). */
body.app-tv #session-platform-bar .sc-bubble.focused,
body.app-tv #session-platform-bar .hoster-toggle.focused,
body.app-tv #shorts-bubbles .sc-bubble.focused,
body.app-tv #clips-bubbles .sc-bubble.focused,
body.app-tv #subs-bubbles .sc-bubble.focused {
  filter: drop-shadow(0 0 4px var(--pc-accent)) drop-shadow(0 0 9px var(--pc-glow)) !important;
}

/* ── 6) Kacheln: Hosterfarben-Rahmen, TV-Textgrößen, FOKUSRING = HOSTERFARBE ──── */
/* Titel 2 Zeilen reserviert (Ausrichtung von Creator/Views bleibt stabil). */
body.app-tv .video-card .card-title {
  font-size: 17px !important; line-height: 1.28 !important;
  min-height: calc(1.28em * 2) !important; max-height: calc(1.28em * 2) !important;
}
/* #TVVP29: Creator-Name auf TV auf Logo-Höhe anheben (14→20px, halbfett),
   damit Buchstaben und Hoster-Logo etwa gleich hoch lesen. */
/* #TVVP29-FU2 (User 2026-08-15): lange Kanalnamen (z.B. „Videos from New Ellijay
   Television") brachen auf TV in eine 2. Zeile und sprengten die Kachel. Desktop
   hat die Einzeilig-mit-Ellipsis-Regel (reskin-startseite.css:1303 body.app-desktop),
   app-tv fehlte sie → hier gespiegelt: .card-creator wrappt nicht (Icon+Name bleiben
   in EINER Zeile), der Name schrumpft (flex:1 1 auto + min-width:0) und kürzt mit „…". */
body.app-tv .video-card .card-creator { font-size: 14px !important; flex-wrap: nowrap !important; }
body.app-tv .video-card .card-creator-name {
  font-size: 20px !important; font-weight: 600 !important; line-height: 1.2 !important;
  overflow: hidden !important; text-overflow: ellipsis !important; white-space: nowrap !important;
  flex: 1 1 auto !important; min-width: 0 !important;
}
body.app-tv .video-card .card-views,
body.app-tv .video-card .card-viewers-live,
body.app-tv .video-card .card-meta-row,
body.app-tv .video-card .card-uploaded,
body.app-tv .video-card .card-duration { font-size: 15px !important; } /* #267: 13→15px, ganze Meta-Gruppe gemeinsam (kein Größensprung in der Zeile) */
/* #455: Kategorie-Overlay (card.game) am Thumbnail auf TV vergrößern — 12px war
   auf 4 m Sitzabstand zu klein. Nur das Overlay-Badge, nicht die Meta-Zeile.
   Der Platzhalter-Fall ("unbekannt" u.ä.) wird bereits im Markup (core.js
   isPlaceholderCategory) unterdrückt, hier geht es rein um die Größe. */
body.app-tv .video-card .card-thumbnail .card-live-game {
  font-size: 17px !important;
  padding: 4px 12px !important;
  border-radius: 8px !important;
}
/* #267: Views/Live-Zuschauer auf TV heller — das blasse Theme-Grau (#bcc3cc o.ä.)
   ist auf 4 m zu kontrastarm. Nur die Zähl-Zeile, nicht die Sekundär-Meta. */
body.app-tv .video-card .card-views,
body.app-tv .video-card .card-viewers-live {
  color: var(--pc-text) !important;
}
/* #TVVP29: Uploadzeit/Live-Laufzeit war theme-dim (--pc-muted ~#7f8aa1 → grau
   auf grau, auf 4 m unlesbar). Auf helle Sekundärfarbe heben — lesbar, aber
   unter den Zählwerten (via Opazität statt voller --pc-text-Helligkeit). */
body.app-tv .video-card .card-uploaded,
body.app-tv .video-card .card-live-uptime {
  color: var(--pc-text) !important; opacity: 0.82 !important;
}
/* #TVVP29: Hoster-Logo-Rahmen auf TV einheitlich größer (18→22px), passend zur
   größeren Creator-Schrift. object-fit:contain (Theme) hält jedes Logo im
   gleich hohen Außenrahmen — YT ist breiter als hoch, der Rahmen bleibt gleich. */
body.app-tv .video-card .card-creator .card-platform-icon,
body.app-tv .video-card .card-creator .logo-slot.card-platform-icon {
  width: 22px !important; height: 22px !important; flex: 0 0 22px !important;
}
/* Thumbnail-Rahmen in Hosterfarbe (--card-glow ist pro Kachel inline gesetzt). */
body.app-tv .video-card .card-thumbnail {
  border: 1.5px solid var(--card-glow, var(--pc-border)) !important;
  border-radius: 14px !important;
}
/* D-Pad-Fokus: kräftiger Hosterfarben-Ring + Glow (das TV-Kernmerkmal). */
body.app-tv .video-card.focused .card-thumbnail {
  outline: 3px solid var(--card-glow, var(--pc-accent)) !important;
  outline-offset: 4px !important;
  box-shadow: 0 0 0 8px color-mix(in srgb, var(--card-glow, var(--pc-accent)) 15%, transparent),
              0 0 30px color-mix(in srgb, var(--card-glow, var(--pc-accent)) 35%, transparent) !important;
}
body.app-tv .video-card.focused .card-title { color: var(--pc-text) !important; }

/* #297: Multi-Hoster-Ring/Halo-Harmonisierung auf TV. Der segmentierte Mehrfarb-Ring
   (::before, aus reskin-startseite.css) BLEIBT als Multi-Hoster-Kennung — er sitzt um die
   ganze Kachel, der TV-Fokusring dagegen als Outline am inneren .card-thumbnail, also auf
   verschiedenen Radien (kein Doppelrahmen-Matsch). Nur der ::after-Halo wird gedaempft,
   damit er sich mit dem starken TV-Fokus-Glow (outline + box-shadow) nicht zu einem
   Doppel-Halo addiert. */
body.app-tv .video-card.card-multi::after { filter: blur(6px) !important; opacity: .3 !important; }
body.app-tv .video-card.card-multi.focused::after,
body.app-tv .video-card.card-multi:focus::after { opacity: .48 !important; }

/* ── 7) Bottom-Bar (#hint-bar = native D-Pad-Leiste; auf TV BEHALTEN + stylen) ── */
body.app-tv #hint-bar {
  background: var(--pc-surface) !important;
  border-top: 1px solid var(--pc-border) !important;
  color: var(--pc-muted) !important;
}
body.app-tv #content { padding-bottom: 76px !important; }

/* ════════════════════════════════════════════════════════════════════════════
   §RESKIN-TV EINSTELLUNGEN (Phase T2, Cloder 2026-07-24)
   TV-Einstellungen nach nocturne-Designsprache (identisch zur abgenommenen
   Startseite). Optische Wahrheit: PubliCore-Reskin-Spec §4.2/§7.2 + die bereits
   abgenommene reskin-startseite-Sprache. Gescoped body.app-tv, GLOBALE --pc-*.
   D-Pad-Fokusmodell (verifiziert settings.js:1355 getButtons + :1375 getTabButtons):
   NUR `#settings-tabbar .settings-tab` (Tab-Bubbles) und `.platform-btn:not(.settings-tab)`
   + `.platform-accordion-toggle` bekommen `.focused`. Toggles/Inputs/Karten liegen
   NICHT im TV-D-Pad-Strom → dafür keine erfundenen Fokusregeln. Kein Deploy (BUG-13).
   ════════════════════════════════════════════════════════════════════════════ */

/* ── 8) Seiten-Titel „Einstellungen" ────────────────────────────────────────── */
body.app-tv #section-settings .section-title {
  color: var(--pc-text) !important;
  font-size: 26px !important; font-weight: 700 !important; letter-spacing: 0.2px !important;
}

/* ── 9) Tab-Bubbles (Schnell-Kopplung | Accounts | Darstellung | Rechtliches) ── */
body.app-tv #settings-tabbar { gap: 10px !important; }
body.app-tv #settings-tabbar .settings-tab {
  background: var(--pc-surface2) !important;
  border: 1px solid var(--pc-border) !important;
  color: var(--pc-muted) !important;
  border-radius: 21px !important;
  font-size: 15px !important;
  box-shadow: none !important; animation: none !important;
}
body.app-tv #settings-tabbar .settings-tab.active {
  background: var(--pc-accent) !important; color: #0a0c12 !important; border-color: var(--pc-accent) !important;
}
body.app-tv #settings-tabbar .settings-tab.focused {
  border-color: var(--pc-accent) !important; color: var(--pc-text) !important;
  box-shadow: 0 0 0 2px var(--pc-accent), 0 0 20px var(--pc-glow) !important;
}
body.app-tv #settings-tabbar .settings-tab.active.focused {
  color: #0a0c12 !important;
  box-shadow: 0 0 0 2px var(--pc-accent), 0 0 20px var(--pc-glow) !important;
}

/* ── 10) Gruppen-Panels + Titel ─────────────────────────────────────────────── */
body.app-tv #section-settings .settings-group {
  background: var(--pc-surface) !important;
  border: 1px solid var(--pc-border) !important;
  border-radius: 16px !important;
  margin-bottom: 18px !important;
}
body.app-tv #section-settings .settings-group-title {
  color: var(--pc-text) !important;
  font-size: 18px !important; font-weight: 600 !important;
  border-bottom: 1px solid var(--pc-border) !important;
}

/* ── 11) Optionszeilen (Pillen) ─────────────────────────────────────────────── */
body.app-tv #section-settings .settings-info,
body.app-tv #section-settings .settings-info-pill {
  background: var(--pc-surface2) !important;
  border: 1px solid var(--pc-border) !important;
  border-radius: 12px !important;
}
body.app-tv #section-settings .settings-info-title,
body.app-tv #section-settings .profile-name-label { color: var(--pc-text) !important; font-size: 16px !important; }
body.app-tv #section-settings .settings-info-desc { color: var(--pc-muted) !important; font-size: 14px !important; }
body.app-tv #section-settings .settings-info-icon { font-size: 22px !important; }

/* ── 12) Toggle-Schalter — AN-Zustand in Akzentfarbe (statt neon-pink) ───────── */
/* (Toggles sind auf TV nicht im D-Pad-Strom; nur die Optik ans Theme angleichen.) */
body.app-tv .pc-switch input:checked + .pc-switch-track {
  background: var(--pc-accent) !important; border-color: var(--pc-accent) !important;
}
body.app-tv .pc-switch input:focus + .pc-switch-track {
  box-shadow: 0 0 0 2px var(--pc-accent) !important;
}

/* ── 13) Buttons (Verknüpfen/Trennen/Design-Dropdown/Accordion) ─────────────── */
body.app-tv #section-settings .platform-btn {
  background: var(--pc-surface2) !important;
  border: 1px solid var(--pc-border) !important;
  color: var(--pc-text) !important;
  border-radius: 11px !important;
  font-size: 15px !important;
  box-shadow: none !important; animation: none !important;
}
/* Primär (Verknüpfen / Speichern) = Akzent-Füllung, dunkle Schrift. */
body.app-tv #section-settings .platform-btn.link {
  background: var(--pc-accent) !important; border-color: var(--pc-accent) !important; color: #0a0c12 !important;
}
/* Sekundär/Destruktiv (Trennen / Zurücksetzen) = Live-Rot-Kontur. */
body.app-tv #section-settings .platform-btn.unlink {
  background: transparent !important; border-color: var(--pc-live) !important; color: var(--pc-live) !important;
}
/* D-Pad-Fokus auf jeden Settings-Button/Accordion = Akzent-Ring (TV-Kernmerkmal). */
body.app-tv #section-settings .platform-btn:not(.settings-tab).focused,
body.app-tv #section-settings .platform-accordion-toggle.focused,
body.app-tv #section-settings .pc-dd-trigger.focused {
  border-color: var(--pc-accent) !important;
  color: var(--pc-text) !important;
  box-shadow: 0 0 0 2px var(--pc-accent), 0 0 18px var(--pc-glow) !important;
}
/* Fokus auf primärem Button: dunkle Schrift beibehalten, nur Ring dazu. */
body.app-tv #section-settings .platform-btn.link.focused { color: #0a0c12 !important; }
/* Fokus auf destruktivem Button: Rot-Ring statt Akzent. */
body.app-tv #section-settings .platform-btn.unlink.focused {
  border-color: var(--pc-live) !important; color: var(--pc-live) !important;
  box-shadow: 0 0 0 2px var(--pc-live), 0 0 18px color-mix(in srgb, var(--pc-live) 40%, transparent) !important;
}

/* ── 14) Design-Dropdown-Feld + Farbwähler-Zeilen ──────────────────────────── */
body.app-tv #section-settings .pc-dd-trigger {
  background: var(--pc-surface2) !important; border: 1px solid var(--pc-border) !important; color: var(--pc-text) !important;
}
body.app-tv #section-settings .pc-dd-caret { color: var(--pc-muted) !important; }
body.app-tv #section-settings .ct-pick { color: var(--pc-muted) !important; }
body.app-tv #section-settings .ct-name-input {
  background: var(--pc-surface) !important; border: 1px solid var(--pc-border) !important; color: var(--pc-text) !important;
}

/* ── 15) Theme-Popup (Design-Auswahl mit Theme-Karten) ──────────────────────── */
/* #424 UI-TV-THEME-POPUP-TOO-SMALL: die Basis-Sheets deckeln die Box auf 680px
   (TV-Override bisher nur 760px) + das Karten-Grid auf 400px Höhe → auf einem
   1920×1080-TV nutzte der Dialog nur ~40% der Fläche. Hier großzügig aufziehen
   (reskin-tv.css ist das global geladene TV-Sheet, unabhängig vom aktiven Theme
   — die Basis-Deckel stehen dreifach in theme-classic/cyberpunk/dark-cyber.css,
   darum die Korrektur zentral hier statt je Theme). */
body.app-tv #theme-popup-box {
  background: var(--pc-surface) !important; border: 1px solid var(--pc-border) !important; border-radius: 18px !important;
  width: 90vw !important; max-width: 1280px !important; max-height: calc(100vh - 72px) !important;
}
body.app-tv #theme-popup .theme-popup-grid {
  max-height: calc(100vh - 260px) !important;
  /* #446: Das Grid ist der Scroll-Container (overflow-y:auto). Ohne Innen-Abstand
     wird der Fokus-Ring (.theme-card.focused: 3px Ring + 22px Glow) der Rand-Karten
     exakt an der Grid-Kante abgeschnitten. Innen-Padding gibt dem Ring Luft. */
  padding: 22px !important;
}
/* #446: Beide Popup-Tabs (Themes / Customize) gleich groß halten — der Customize-Pane
   hat weniger Inhalt als das Themes-Grid, wodurch die Box beim Tab-Wechsel sichtbar
   sprang. Eine gemeinsame Mindesthöhe auf dem Scroll-Body fixiert die Box-Größe. */
body.app-tv #theme-popup .theme-popup-body {
  min-height: calc(100vh - 260px) !important;
}
body.app-tv #theme-popup .theme-popup-title { color: var(--pc-text) !important; }
body.app-tv #theme-popup .theme-popup-tabs .settings-tab {
  background: var(--pc-surface2) !important; border: 1px solid var(--pc-border) !important; color: var(--pc-muted) !important;
}
body.app-tv #theme-popup .theme-popup-tabs .settings-tab.active {
  background: var(--pc-accent) !important; color: #0a0c12 !important; border-color: var(--pc-accent) !important;
}
body.app-tv #theme-popup .theme-card {
  background: var(--pc-surface2) !important; border: 1.5px solid var(--pc-border) !important;
  color: var(--pc-text) !important; border-radius: 12px !important;
}
/* Aktives (aktuelles) Theme = Akzent-Kontur (JS setzt ' active' auf die Karte). */
body.app-tv #theme-popup .theme-card.active {
  border-color: var(--pc-accent) !important;
  box-shadow: 0 0 0 1px var(--pc-accent) !important;
}
/* D-Pad-Fokus im Theme-Grid = Akzent-Ring + Glow. */
body.app-tv #theme-popup .theme-card.focused {
  border-color: var(--pc-accent) !important;
  box-shadow: 0 0 0 3px var(--pc-accent), 0 0 22px var(--pc-glow) !important;
}

/* ── 15b) #425 FEAT-TV-THEME-CUSTOM-FREE-COLOR-DPAD ──────────────────────────── */
/* Freier, D-Pad-bedienbarer RGB-Farbwähler. Am TV ersetzt der .cpc-free-btn den
   toten <input type=color> (OS-Farbkreis) in 5 der 6 Farbzeilen; in der Akzent-
   Zeile ergänzt er das #285-Preset-Grid. Der Picker (#rgb-picker) öffnet als
   verschachteltes Modal ÜBER dem Theme-Popup (z-index 1600 > #theme-popup 1100).
   Global geladenes TV-Sheet → theme-unabhängig, nur body.app-tv. Kein Deploy (BUG-13). */
body.app-tv .cpc-free-btn {
  display: inline-flex; align-items: center; gap: 12px;
  background: var(--pc-surface2); border: 1.5px solid var(--pc-border);
  border-radius: 12px; color: var(--pc-text);
  padding: 8px 16px; min-height: 46px; cursor: pointer;
  font-size: 16px; font-weight: 600; letter-spacing: .2px;
}
body.app-tv .cpc-free-sw {
  width: 28px; height: 28px; border-radius: 7px; flex: 0 0 auto;
  border: 1px solid rgba(255, 255, 255, .35);
}
body.app-tv .cpc-free-hex { font-variant-numeric: tabular-nums; letter-spacing: .5px; }
/* D-Pad-Fokus (JS setzt .focused auf die umschließende .cpc-row) = Akzent-Ring + Glow. */
body.app-tv .cpc-row.focused .cpc-free-btn,
body.app-tv .cpc-free-btn:focus {
  border-color: var(--pc-accent);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .9), 0 0 0 3px var(--pc-accent), 0 0 22px var(--pc-glow);
  outline: none;
}

/* Nested Picker-Overlay. */
body.app-tv #rgb-picker {
  position: fixed; inset: 0; z-index: 1600;
  display: flex; align-items: center; justify-content: center;
  padding: 16px; box-sizing: border-box;
  background: rgba(0, 0, 8, .72);
  -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
}
body.app-tv #rgb-picker.hidden { display: none !important; }
body.app-tv #rgb-picker-box {
  background: var(--pc-surface); border: 1px solid var(--pc-border);
  border-radius: 18px; padding: 30px 34px; width: 90vw; max-width: 560px;
  color: var(--pc-text); box-shadow: 0 24px 80px rgba(0, 0, 0, .6);
}
body.app-tv #rgb-picker-title {
  font-size: 24px; font-weight: 700; text-align: center;
  margin: 0 0 20px; color: var(--pc-text);
}
body.app-tv .rgb-preview-wrap {
  display: flex; align-items: center; justify-content: center; gap: 18px; margin-bottom: 24px;
}
body.app-tv #rgb-preview {
  width: 72px; height: 72px; border-radius: 14px; flex: 0 0 auto;
  border: 2px solid var(--pc-border); background: #000;
}
body.app-tv #rgb-hex {
  font-size: 26px; font-weight: 700; letter-spacing: 1px;
  font-variant-numeric: tabular-nums; color: var(--pc-text);
}
body.app-tv .rgb-channels {
  display: flex; flex-direction: column; gap: 12px; margin-bottom: 26px;
}
body.app-tv .rgb-chan {
  display: flex; align-items: center; gap: 16px;
  padding: 10px 16px; border-radius: 12px;
  background: var(--pc-surface2); border: 2px solid transparent;
}
body.app-tv .rgb-chan-label {
  width: 24px; font-size: 20px; font-weight: 700; color: var(--pc-text);
}
body.app-tv .rgb-bar {
  flex: 1 1 auto; height: 14px; border-radius: 8px;
  background: rgba(255, 255, 255, .12); overflow: hidden;
}
body.app-tv .rgb-bar-fill {
  display: block; height: 100%; width: 0; border-radius: 8px;
  background: var(--pc-accent); transition: width .08s linear;
}
body.app-tv .rgb-chan-val {
  width: 48px; text-align: right; font-size: 20px; font-weight: 700;
  font-variant-numeric: tabular-nums; color: var(--pc-text);
}
body.app-tv .rgb-chan.rgb-focused {
  border-color: var(--pc-accent);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .85), 0 0 18px var(--pc-glow);
}
/* #447/#448: Aktionszeile mit Fertig (primär, Akzent) + Abbrechen (sekundär). */
body.app-tv .rgb-actions {
  display: flex; gap: 12px; margin-top: 6px;
}
body.app-tv #rgb-done,
body.app-tv #rgb-cancel {
  flex: 1 1 0; padding: 14px 0; border-radius: 12px;
  font-size: 19px; font-weight: 700; cursor: pointer; text-align: center;
}
body.app-tv #rgb-done {
  background: var(--pc-accent); color: #0a0c12; border: 2px solid var(--pc-accent);
}
body.app-tv #rgb-cancel {
  background: var(--pc-surface2); color: var(--pc-text); border: 2px solid var(--pc-border);
}
body.app-tv #rgb-done.rgb-focused,
body.app-tv #rgb-cancel.rgb-focused {
  box-shadow: inset 0 0 0 2px rgba(255, 255, 255, .9), 0 0 0 3px var(--pc-accent), 0 0 24px var(--pc-glow);
}
/* .rgb-hint: ehemaliger Nur-Text-Abbrechen-Hinweis — durch echten #rgb-cancel-Button
   ersetzt (#448); Regel bleibt harmlos, falls Alt-Markup gecacht ist. */
body.app-tv .rgb-hint {
  margin-top: 14px; text-align: center; font-size: 14px; color: var(--pc-muted);
}

/* ════════════════════════════════════════════════════════════════════════════
   §RESKIN-TV PLAYER (Phase T3, Cloder 2026-07-24)
   TV-Player-Chrome nach nocturne. Auf echtem TV läuft der D-Pad-Player
   (#player-controls + .player-ctl + #player-info) — NICHT #player-desktop
   (das ist App.IS_DESKTOP-exklusiv, player-desktop.js:7). D-Pad-Fokus auf
   .player-ctl verifiziert (player.js:149 bar.querySelectorAll('.player-ctl')),
   .sub-choice-btn (player.js:3127/3148). Gescoped body.app-tv, globale --pc-*.
   Kein Deploy (BUG-13).
   ════════════════════════════════════════════════════════════════════════════ */

/* ── 16) Info-Leiste unten (Name → Titel → Zuschauer/Kategorie) ─────────────── */
body.app-tv #player-info {
  background: var(--pc-surface) !important;
  border-top: 1px solid var(--pc-border) !important;
}
body.app-tv #player-info-name { color: var(--pc-text) !important; }
body.app-tv #player-info-title { color: var(--pc-muted) !important; }
body.app-tv .pi-viewers { color: var(--pc-live) !important; }   /* Live-Zahl bleibt rot */
body.app-tv .pi-game { color: var(--pc-muted) !important; }

/* ── 17) Steuer-Buttons (Zurück / Profil / Folgen) + D-Pad-Fokus ────────────── */
body.app-tv .player-ctl {
  background: var(--pc-surface) !important;   /* deckend: universell (kein color-mix) + auf 4 m über Video gut lesbar */
  border: 1px solid var(--pc-border) !important;
  color: var(--pc-text) !important;
  border-radius: 12px !important;
  /* FIX-3 (#368③-FU): wertigere, einheitliche TV-Button-Optik statt „flacher grauer
     Textknopf". Feste Pillen-Höhe + zentriertes Icon/Label (die vorhandenen Glyphen
     „←"/„+" im Label bleiben inline, gap trennt sie vom Text), ruhigere Typo. Nur
     body.app-tv → Web/Handy unberührt. Default-Optik; Fokus/Hover s. u. (FIX-1-Ring). */
  min-height: 48px !important;
  padding: 0 24px !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  gap: 8px !important;
  font-size: 17px !important;
  font-weight: 600 !important;
  letter-spacing: .2px !important;
  line-height: 1 !important;
}
/* D-Pad-Fokus = statischer Akzent-Ring + Glow (kein breathe-sys-Puls, wie im
   restlichen TV-Reskin). */
body.app-tv .player-ctl:hover,
body.app-tv .player-ctl.focused {
  border-color: var(--pc-accent) !important;
  color: var(--pc-text) !important;
  /* FIX-1 (#368③-FU-B): deutlich prominenterer Fokusring. Weiße Innen-Haarlinie
     (kontrastiert den Akzent auf jeder Themefläche, kein color-mix → universell) +
     3px heller Akzentring + kräftigerer Glow. Der Ring paintet jetzt frei, weil das
     Button-Band (#player-controls, s. u.) den Clip aufgehoben hat. */
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.9), 0 0 0 3px var(--pc-accent), 0 0 26px 3px var(--pc-glow) !important;
  animation: none !important;
}
/* „Gefolgt"-Zustand behält die semantische Grün-Rückmeldung (verknüpft = grün). */
body.app-tv .player-ctl-follow.following {
  border-color: rgba(34,197,94,0.6) !important; color: var(--linked, #4ade80) !important;
}
body.app-tv .player-ctl-follow.following.focused {
  border-color: var(--linked, #4ade80) !important; color: #dcfce7 !important;
  box-shadow: 0 0 0 2px var(--linked, #4ade80), 0 0 20px rgba(34,197,94,0.35) !important;
}

/* ── 18) Fehler-Box + Aktions-Button ────────────────────────────────────────── */
body.app-tv #player-error {
  background: var(--pc-surface) !important;
  border: 1px solid var(--pc-border) !important;
  color: var(--pc-text) !important;
}
body.app-tv #player-error .pd-err-action {
  background: var(--pc-accent) !important; border-color: var(--pc-accent) !important; color: #0a0c12 !important;
}

/* ── 19) Player-Dialoge (Folgen-QR / Abo-Auswahl / Playlist) ─────────────────── */
body.app-tv #follow-modal-box,
body.app-tv #sub-choice-box,
body.app-tv #playlist-picker-box {
  background: var(--pc-surface) !important;
  border: 1px solid var(--pc-border) !important;
  color: var(--pc-text) !important;
}
body.app-tv #follow-modal-title,
body.app-tv #sub-choice-title,
body.app-tv #playlist-picker-title { color: var(--pc-text) !important; }
body.app-tv #follow-modal-desc,
body.app-tv #follow-modal-hint,
body.app-tv #sub-choice-desc { color: var(--pc-muted) !important; }
/* Abo-Auswahl-Optionen: Pillen mit Akzent-Fokusring. */
body.app-tv .sub-choice-btn {
  background: var(--pc-surface2) !important;
  border: 1px solid var(--pc-border) !important;
  color: var(--pc-text) !important;
}
body.app-tv .sub-choice-btn:hover,
body.app-tv .sub-choice-btn.focused {
  border-color: var(--pc-accent) !important; color: var(--pc-text) !important;
  box-shadow: 0 0 0 2px var(--pc-accent), 0 0 18px var(--pc-glow) !important;
  animation: none !important;
}
body.app-tv #playlist-picker-newname {
  background: var(--pc-surface2) !important; border: 1px solid var(--pc-border) !important; color: var(--pc-text) !important;
}

/* ════════════════════════════════════════════════════════════════════════════
   §RESKIN-TV v2 — TV auf den Stand der ABGENOMMENEN Web-Startseite (Cloder 2026-07-26)

   ANLASS (User 2026-07-26): "Web und Mobile sind umgebaut, die TV-Version noch
   nicht." Befund: reskin-tv.css (§1–§19) stammt vom 24.07. und bildet den damaligen
   Web-Reskin-Stand (~v20) ab. reskin-startseite.css ist seither bis v46 gewachsen —
   aber 278 ihrer Regeln sind auf `body.app-desktop` gescoped, und diese Klasse ist
   auf einem ECHTEN TV nie gesetzt (core.js: `if (App.IS_TV) body.classList.add('app-tv')`,
   app-desktop nur bei App.IS_DESKTOP). Der TV hat davon also NICHTS gesehen.

   ANSATZ: TV bekommt hier die TV-gescopten Gegenstuecke der Desktop-Regeln — gleiche
   Designsprache (nocturne), aber 10-Fuss-Masse + D-Pad-Fokus statt Hover. Die Datei
   reskin-startseite.css bleibt UNANGETASTET (kein Web-/Mobile-Regressionsrisiko).

   OPTISCHE WAHRHEIT: Reskin/publicore-reskin-preview-tv_2.html (= tv.html = tv_1.html,
   byte-identisch geprueft) + HANDOFF.md §TV. Masse daraus 1:1 uebernommen.

   PRUEFMODUS: body.app-tv laesst sich auf PC ueber den Sidebar-Umschalter "TV Ansicht"
   erzwingen (App.forceViewport('tv'), Marker body.forced-tv) — sonst waere die TV-
   Oberflaeche ausserhalb eines echten Tizen/webOS-Geraets gar nicht pruefbar.

   BEWUSSTE ABWEICHUNG von der Vorlage: das Connect-Banner bleibt auf dem TV
   ausgeblendet (theme-classic.css:4249). Grund: es liegt NICHT in der D-Pad-Fokus-
   Kette (App.state.area kennt nur search-bar/nav/sidebar-footer/hoster-bar/header/
   grid/…) — sichtbar, aber weder bedien- noch wegklickbar waere schlechter als
   unsichtbar. Einblenden = eigenes Ticket (Fokus-Zone ergaenzen). Kein Deploy (BUG-13).
   ════════════════════════════════════════════════════════════════════════════ */

/* ── §20) Viewport-Umschalter: auf einem ECHTEN TV sinnlos → nur im Pruefmodus ─── */
body.app-tv:not(.forced-tv) #sidebar-viewport { display: none !important; }

/* ── §21) Sidebar: 250px (Vorlage), eingeklappt 56px, flache Flaeche + Kantenlinie ─ */
body.app-tv #sidebar {
  width: 250px !important;
  background: var(--pc-surface) !important;
  border-right: 1px solid var(--pc-border) !important;
}
body.app-tv.sidebar-collapsed #sidebar { width: 56px !important; }
body.app-tv.sidebar-collapsed #sidebar-logo { width: 56px !important; max-width: 56px !important; }
body.app-tv.sidebar-collapsed #nav-list { padding-left: 6px !important; padding-right: 6px !important; }
/* Logo-Block "aus einem Guss": gleiche Hoehe wie die Topbar-Zeile, keine Trennlinie. */
body.app-tv #sidebar-logo {
  height: 84px !important;
  border-bottom: none !important;
  padding: 0 16px !important;
  gap: 12px !important;
}
body.app-tv #nav-list { padding: 14px 12px !important; }
/* Rechts-Links + Versions-String am Fuss (Vorlage: side-legal mit Trennlinie oben). */
body.app-tv #sidebar-legal {
  border-top: 1px solid var(--pc-border) !important;
  padding-top: 10px !important;
}
body.app-tv .sidebar-legal-link { color: var(--pc-muted) !important; font-size: 13px !important; }
body.app-tv #sidebar-build { color: var(--pc-muted) !important; }

/* ── §22) Einklapp-Chevron: runder Knopf MITTIG auf der Sidebar-Kante ──────────── */
/* (Basis .sidebar-toggle sitzt bereits mit translate(-50%,-50%) auf `left`; hier nur
   die TV-Breiten nachziehen + Akzent-Kontur/Glow wie in der Vorlage.) */
body.app-tv .sidebar-toggle {
  left: 250px !important;
  background: var(--pc-surface2) !important;
  border: 1px solid var(--pc-accent) !important;
  color: var(--pc-accent) !important;
  box-shadow: 0 0 0 4px var(--pc-bg), 0 0 14px var(--pc-soft) !important;
}
body.app-tv.sidebar-collapsed .sidebar-toggle { left: 56px !important; }
/* D-Pad-Fokus (der Chevron IST Teil der Sidebar-Fokuskette, s. UI-112). */
body.app-tv .sidebar-toggle.focused {
  color: var(--pc-text) !important;
  box-shadow: 0 0 0 3px var(--pc-accent), 0 0 20px var(--pc-glow) !important;
}

/* ── §23) Topbar: eigene Flaeche + Unterlinie, Suche mittig, Aktionen rechts ───── */
body.app-tv #header {
  background: var(--pc-surface) !important;
  border-bottom: 1px solid var(--pc-border) !important;
  margin-bottom: 16px !important;
}
body.app-tv #search-bar {
  height: 46px !important;
  flex: 1 1 auto !important;
  width: auto !important;
  max-width: 640px !important;
  min-width: 200px !important;
  padding: 0 16px !important;
  font-size: 15px !important;
}
body.app-tv #search-input { font-size: 15px !important; background: transparent !important; border: none !important; }
body.app-tv #header-actions {
  width: auto !important; min-width: max-content !important; flex: 0 0 auto !important;
  margin-left: auto !important; margin-right: 24px !important;
  justify-content: flex-end !important; overflow: visible !important;
}
body.app-tv #notif-bell { width: 44px !important; height: 44px !important; border-radius: 11px !important; }
/* Avatar rechts (wird von js/reskin-tv.js gebaut — auf TV OHNE Theme-Punkte, das
   Theme wird laut HANDOFF ausschliesslich in den Einstellungen gewechselt). */
body.app-tv #rsk-avatar { width: 40px !important; height: 40px !important; font-size: 15px !important; }
body.app-tv #rsk-topbar-extra { display: none !important; }

/* ── §24) Sections + Header fuellen die Content-Spalte (Pendant zu Web-§v20) ───── */
/* Ohne das deckelt die App jede .section auf max-width:1440px + auto-Zentrierung →
   beim Einklappen der Sidebar entstuende rechts eine tote Luecke. */
body.app-tv .section,
body.app-tv #header {
  max-width: none !important; width: 100% !important;
  margin-left: 0 !important; margin-right: 0 !important;
}

/* ── §25) Sektions-Titel + Filter-Segment (Pendant zu Web-§v12/§v19/§v23) ──────── */
body.app-tv .section-title {
  text-transform: none !important;
  font-family: 'Inter','Segoe UI',system-ui,sans-serif !important;
  font-size: 22px !important; font-weight: 700 !important; letter-spacing: -0.01em !important;
  color: var(--pc-text) !important;
}
/* Segment-Control: EIN Rechteck mit Innen-Optionen. 2 IDs (#content #filter-tabs)
   schlagen ui-auth74-73.css (1,3,1) unabhaengig von der Ladereihenfolge. */
/* KORREKTUR (User-Feedback 2026-07-26, Punkte 6+8): `display` gehoert hier NICHT
   pauschal hin. Die App steuert die SICHTBARKEIT des Filters selbst — u.a.
   `body.nav-categories #filter-tabs {display:none!important}` (theme-*.css),
   `.filter-tab-groups/-calendar {display:none}` (nur Abo-Box) und
   `body.nav-shorts/.nav-clips #filter-tabs {display:none!important}`. Die erste
   Fassung dieser Regel trug zwei IDs + !important und hat ALLE diese Abschalter
   ueberstimmt: dadurch tauchten „Gruppen"/„Kalender" auf dem TV in jedem Feed auf
   und der Filter blieb auch in den Kategorien stehen. Jetzt wird `display` nur noch
   dort gesetzt, wo der Filter laut App ohnehin sichtbar ist. */
body.app-tv:not(.nav-categories):not(.nav-shorts):not(.nav-clips) #content #filter-tabs {
  display: inline-flex !important;
}
body.app-tv #content #filter-tabs {
  flex-wrap: nowrap !important; align-items: center !important;
  width: auto !important; max-width: none !important;
  padding: 3px !important; gap: 2px !important;
  background: var(--pc-surface2) !important;
  border: 1px solid var(--pc-border) !important;
  border-radius: 12px !important; box-shadow: none !important;
}
/* Ebenso: `display` nur fuer die Tabs, die die App auch zeigen will — sonst
   ueberstimmt es `.filter-tab-groups/.filter-tab-calendar {display:none}`. */
body.app-tv #content #filter-tabs .filter-tab:not(.filter-tab-groups):not(.filter-tab-calendar) {
  display: inline-flex !important;
}
body.app-tv:not(.nav-subscriptions) #content #filter-tabs .filter-tab-groups,
body.app-tv:not(.nav-subscriptions) #content #filter-tabs .filter-tab-calendar {
  display: none !important;
}
body.app-tv #content #filter-tabs .filter-tab {
  align-items: center !important; justify-content: center !important;
  height: 36px !important; min-height: 0 !important; padding: 0 18px !important; margin: 0 !important;
  border: none !important; border-radius: 9px !important; box-shadow: none !important;
  background: transparent !important; color: var(--pc-muted) !important;
  font-size: 14px !important; font-weight: 600 !important; line-height: 1 !important;
}
body.app-tv #content #filter-tabs .filter-tab.active {
  background: var(--pc-accent) !important; color: #07080d !important; font-weight: 600 !important;
}
body.app-tv #content #filter-tabs .filter-tab.active svg { stroke: #07080d !important; }
/* D-Pad-Fokus im Segment: Akzent-Ring INNEN (outline wuerde am Container clippen). */
body.app-tv #content #filter-tabs .filter-tab.focused {
  box-shadow: inset 0 0 0 2px var(--pc-accent) !important; color: var(--pc-text) !important;
}
body.app-tv #content #filter-tabs .filter-tab.active.focused { color: #07080d !important; }
/* Home zeigt wie die Vorlage nur Alle/Live/Videos — Gruppen/Kalender sind Abo-Box. */
body.app-tv:not(.nav-subscriptions) #section-home #filter-tabs .filter-tab-groups,
body.app-tv:not(.nav-subscriptions) #section-home #filter-tabs .filter-tab-calendar {
  display: none !important;
}

/* ── §26) Hoster-Chips: Logo im Rundquadrat + Name, Pillenform (Vorlage .chip) ─── */
/* #282-H: TV-Parität zu Desktop/Mobile — app-tv-Bar unabhängig von body.nav-home sichtbar
   (Defense-in-Depth für #282). BEWUSST OHNE !important: der globale .hidden-Collapse
   (reskin-startseite.css:1008) und nav-shorts/nav-clips {display:none !important}
   (theme-*.css:4287-4288) MÜSSEN weiterhin gewinnen. */
body.app-tv .session-platform-bar {
  display: flex;
  flex-wrap: wrap;
}
body.app-tv #session-platform-bar { gap: 12px !important; }
body.app-tv #session-platform-bar .sc-bubble {
  height: 42px !important; padding: 0 18px 0 9px !important; gap: 10px !important;
  font-size: 15px !important; font-weight: 600 !important;
}
body.app-tv #session-platform-bar .sc-bubble .logo-slot-sm,
body.app-tv #session-platform-bar .sc-bubble .logo-slot {
  width: 28px !important; height: 28px !important; border-radius: 8px !important;
  overflow: hidden !important; flex: none !important; margin-right: 0 !important;
}
body.app-tv #session-platform-bar .sc-bubble .logo-slot-sm img,
body.app-tv #session-platform-bar .sc-bubble .logo-slot img {
  width: 100% !important; height: 100% !important; object-fit: cover !important;
}
/* Aktiver Chip = Akzent-Fuellung mit dunkler Schrift (wie das Segment). */
body.app-tv #session-platform-bar .sc-bubble.active,
body.app-tv #session-platform-bar .sc-bubble.on {
  background: var(--pc-accent) !important; border-color: var(--pc-accent) !important; color: #07080d !important;
}
/* #TVVP13 (User: „die Hoster-Pillen auf die gleiche Höhe wie Alle/Live/Videos, damit die
   Kacheln etwas höher rücken"). Spiegelt #378 (app-desktop, reskin-startseite.css:2288) auf
   app-tv: die Filter-Tabs sind hier bereits inline-flex in-flow (§25 oben), die Pillen-Leiste
   lag aber als eigener Block-Flex DARUNTER (§26, display:flex) → zweite Zeile. Jetzt als
   inline-flex direkt neben die Tabs → EINE Reihe, Feed rückt eine Zeile hoch.
   `:not(.hidden)` lässt den globalen .hidden-Collapse (nav-shorts/clips, #282-H) unberührt —
   im versteckten Zustand greift diese Regel gar nicht erst. */
body.app-tv #section-home #session-platform-bar:not(.hidden) {
  display: inline-flex !important;
  vertical-align: middle !important;
  width: auto !important;
  margin: 0 0 0 14px !important;
}
/* Vertikaler Gewinn: Titel-Abstand nach unten straffen (mirror #378 (3)). */
body.app-tv #section-home .section-title { margin-bottom: 10px !important; }

/* ── §27) Kacheln: Meta-Zeilen exakt gleich hoch (Pendant zu Web-§v17b) ────────── */
/* Ohne das sitzen Live-Zuschauer und Video-Aufrufe auf unterschiedlicher Hoehe und die
   ganze Reihe "wackelt" — auf 4 m Distanz besonders auffaellig. */
body.app-tv .video-card .card-meta-row {
  height: 26px !important; min-height: 26px !important; align-items: center !important;
}
body.app-tv .video-card .card-viewers-live,
body.app-tv .video-card .card-views {
  height: 26px !important; min-height: 26px !important; line-height: 26px !important;
  margin-top: 0 !important; align-self: center !important; overflow: hidden !important;
}
body.app-tv .video-card .card-live-uptime,
body.app-tv .video-card .card-uploaded { line-height: 26px !important; align-self: center !important; }
/* Grid: 4 Spalten wie die Vorlage. */
body.app-tv .video-grid { grid-template-columns: repeat(4, 1fr) !important; gap: 24px 22px !important; }

/* ── §28) Bottom-Bar: EINE Leiste (D-Pad · OK · Zurueck · Farbtasten) ──────────── */
/* Vorher zwei getrennte Elemente: #hint-bar (40px Monospace-Text, volle Breite) UND
   die schwebende #osd-color-bar-Pille darueber. Die Vorlage hat EINE 70px-Leiste, die
   an der Sidebar-Kante beginnt. js/reskin-tv.js haengt die Farbleiste in #hint-bar ein
   (und wieder heraus, sobald der Player laeuft oder PiP aktiv ist — dort MUSS sie als
   schwebendes Overlay ueber dem Video bleiben). */
body.app-tv #hint-bar {
  left: 250px !important; right: 0 !important;
  height: 70px !important;
  background: var(--pc-surface) !important;
  border-top: 1px solid var(--pc-border) !important;
  display: flex !important; align-items: center !important; justify-content: center !important;
  gap: 26px !important;
  font-family: 'Inter','Segoe UI',system-ui,sans-serif !important;
  font-size: 14px !important; letter-spacing: normal !important;
  color: var(--pc-muted) !important;
}
body.app-tv.sidebar-collapsed #hint-bar { left: 56px !important; }
body.app-tv #content { padding-bottom: 86px !important; }
/* Die drei ORIGINAL-Spans (data-i18n="hint_nav|hint_enter|hint_back") bleiben im DOM
   liegen — sie sind die Schreibziele des indexbasierten Sprach-Passes in core.js:9961
   (`hintBar.querySelectorAll('span')[0..2].textContent = …`). Wuerde man sie
   entfernen oder verschachteln, schriebe der naechste Sprachwechsel in die falschen
   Knoten. Deshalb: nur verstecken. Sichtbar sind die <i>-Gruppen von reskin-tv.js.
   #464: Das Verstecken ist an data-rsk-tv="1" gekoppelt — reskin-tv.js setzt das
   Attribut ERST, nachdem es die <i>-Ersatzgruppen eingehaengt hat. Laeuft decorateHints()
   auf webOS (langsamer Boot / SW-Timing) einmal nicht durch, bleibt data-rsk-tv leer →
   die Roh-Spans zeigen ihren i18n-Wortlaut ("Steuerkreuz: Navigieren" …) als Fallback,
   statt dass die Leiste voellig LEER (nur Farbtasten) erscheint. Ist dekoriert, greift
   die Regel wie bisher und blendet die Roh-Spans aus. */
body.app-tv #hint-bar[data-rsk-tv="1"] > span[data-i18n] { display: none !important; }
/* Hinweis-Gruppe: Piktogramm + Kurz-Label (Markup von js/reskin-tv.js, alles <i>,
   damit die span-Indizes des Sprach-Passes unberuehrt bleiben). */
body.app-tv #hint-bar .tv-hint {
  display: inline-flex !important; align-items: center !important; gap: 9px !important;
  margin: 0 !important; color: var(--pc-muted) !important; white-space: nowrap !important;
  font-style: normal !important;
}
body.app-tv #hint-bar .tv-hint-label { font-style: normal; color: var(--pc-muted); }
body.app-tv #hint-bar .tv-hint-glyph { width: 30px; height: 30px; color: var(--pc-text); flex: none; }
body.app-tv #hint-bar .tv-hint-glyph svg { width: 100%; height: 100%; display: block; }
body.app-tv #hint-bar .tv-ok-pill {
  height: 30px; padding: 0 13px; border-radius: 15px;
  border: 1.5px solid var(--pc-border); background: var(--pc-surface2);
  color: var(--pc-text); font-size: 13px; font-weight: 700; font-style: normal;
  display: inline-flex; align-items: center; flex: none;
}
/* Farbleiste EINGEHAENGT: aus der schwebenden Pille werden Inline-Chips. */
body.app-tv #hint-bar #osd-color-bar {
  position: static !important; transform: none !important;
  left: auto !important; right: auto !important; bottom: auto !important;
  background: transparent !important; border: none !important; box-shadow: none !important;
  padding: 0 !important; margin-left: 8px !important; gap: 12px !important;
  z-index: auto !important;
}
body.app-tv #hint-bar .osd-color-chip {
  height: 40px; padding: 0 15px; border-radius: 12px; gap: 9px;
  border: 1px solid var(--pc-border); background: var(--pc-surface2);
  color: var(--pc-text); font-size: 13.5px; font-weight: 600;
}
body.app-tv #hint-bar .osd-color-dot { width: 12px; height: 12px; }
body.app-tv #hint-bar .osd-color-label { font-size: 13.5px; color: var(--pc-text); }
/* #TVVP14 (User: „die Beschriftung in der Bottom-Bar wirkt verloren, so weit weg von dem
   jeweiligen Punkt"). Ursache: die Theme-Regel `#hint-bar span { margin: 0 20px }`
   (theme-*.css) legt je 20px links+rechts auf die <span>-Kinder der Farbchips (Dot + Label)
   → 40px Rand zwischen Punkt und Label ZUSÄTZLICH zum 9px chip-gap (gemessen 49px). Die
   Hinweis-Gruppen (D-Pad/OK/Zurück) sind <i>-Elemente und daher nicht betroffen (saubere
   9px). Fix: Rand der Chip-Kinder auf 0 → nur der 9px chip-gap bleibt, Punkt sitzt dicht
   am Label. */
body.app-tv #hint-bar .osd-color-chip .osd-color-dot,
body.app-tv #hint-bar .osd-color-chip .osd-color-label { margin: 0 !important; }

/* ── §29) Suche: Ergebnis-Tabs + Kategorie-Chips in derselben Sprache ──────────── */
body.app-tv #search-tabs .filter-tab,
body.app-tv .search-cat-chip { font-size: 15px !important; color: var(--pc-muted) !important; }
body.app-tv #search-tabs .filter-tab.active,
body.app-tv .search-cat-chip.active {
  background: var(--pc-accent) !important; color: #07080d !important; border-color: var(--pc-accent) !important;
}
body.app-tv #search-tabs .filter-tab.focused,
body.app-tv .search-cat-chip.focused {
  box-shadow: 0 0 0 2px var(--pc-accent), 0 0 18px var(--pc-glow) !important;
}

/* ── §30) Leerzustaende/Ladehinweise: neutral statt Neon ───────────────────────── */
body.app-tv .load-more-hint,
body.app-tv .pc-empty-title,
body.app-tv .pc-empty-text { color: var(--pc-muted) !important; }
body.app-tv .pc-empty-filter-icon-wrap { color: var(--pc-accent) !important; }

/* ══════════════════════════════════════════════════════════════════════════
   §RESKIN-TV v2 §31 — User-Feedback 2026-07-26 (TV-spezifisch)
   ══════════════════════════════════════════════════════════════════════════ */

/* ── (6) Gruppen/Kalender gehoeren NUR in die Abo-Box ──────────────────────────
   REGRESSION AUS §25 (eigener Fund): dort steht
   `body.app-tv #content #filter-tabs .filter-tab { display:inline-flex !important }`
   fuer ALLE Tabs. Das schlug die Basis-Regel `.filter-tab-groups{display:none}`
   (theme-*.css) — dadurch tauchten „Gruppen" und „Kalender" auf dem TV in JEDEM
   Feed auf, u.a. in den Trends. Hier gezielt wieder ausgeblendet; das
   Abo-Box-Verhalten (body.nav-subscriptions) bleibt unveraendert.
   §25 hatte das nur fuer #section-home nachgezogen — jetzt fuer alle Feeds. */
body.app-tv:not(.nav-subscriptions) #content #filter-tabs .filter-tab-groups,
body.app-tv:not(.nav-subscriptions) #content #filter-tabs .filter-tab-calendar {
  display: none !important;
}

/* ── (10) Einstellungen: doppelt hohe Topbar ───────────────────────────────────
   GEMESSEN: #header waechst beim Wechsel in die Einstellungen von 89 px auf 133 px,
   weil `.header-row-bottom` (die Zeile mit #filter-tabs) dort 44 px hoch wird. In
   den Feeds wird #filter-tabs in die Sektion umgehaengt und die Zeile faellt auf 0
   zusammen — in den Einstellungen gibt es kein Umhaenge-Ziel, also bleibt sie
   stehen. Die Einstellungen haben keinen „Alle | Live | Videos"-Filter → Zeile weg. */
body.app-tv.nav-settings .header-row-bottom { display: none !important; }

/* ══════════════════════════════════════════════════════════════════════════
   §RESKIN-TV §32 — Cyberpunk-Highlight in GELB auf dem TV (User 2026-07-26, Pkt 6)
   Ausdrueckliche Entscheidung: „cyberpunk theme das highlight, das hatten wir ja
   auf gelb gesetzt. Das soll auf TV auf gelb sein." Also NUR theme-cyberpunk und
   NUR im TV-Layout — Dark-Cyber und Nocturne behalten ihre Akzentfarbe, Web/Mobile
   bleiben unangetastet. Deckend statt getoent (Transparenz raus) und in den
   Einstellungen exakt derselbe Highlight wie in der Sidebar (der zweite Teil der
   Meldung: „die einstellung ist optisch vom highlight nicht wie die sidebar").
   ════════════════════════════════════════════════════════════════════════════ */
body.app-tv.theme-cyberpunk {
  --pc-glow: rgba(250, 255, 0, 0.45);
  --pc-soft: rgba(250, 255, 0, 0.16);
}
/* Sidebar: aktives Nav-Item = deckendes Neon-Gelb, dunkle Schrift/Piktogramme. */
body.app-tv.theme-cyberpunk #sidebar .nav-item.active,
body.app-tv.theme-cyberpunk #sidebar .nav-item.active.focused {
  background: #faff00 !important;
  color: #12131a !important;
  box-shadow: inset 4px 0 0 rgba(0, 0, 0, 0.45) !important;
}
body.app-tv.theme-cyberpunk #sidebar .nav-item.active .nav-icon,
body.app-tv.theme-cyberpunk #sidebar .nav-item.active.focused .nav-icon { color: #12131a !important; }
/* Reiner D-Pad-Fokus (noch nicht aktiv): gelber Ring, KEINE getoente Flaeche. */
body.app-tv.theme-cyberpunk #sidebar .nav-item.focused:not(.active) {
  background: transparent !important;
  box-shadow: inset 0 0 0 2px #faff00 !important;
  color: #faff00 !important;
}
/* Einstellungen: Tab-Bubbles identisch zur Sidebar behandeln. */
body.app-tv.theme-cyberpunk #settings-tabbar .settings-tab.active {
  background: #faff00 !important; border-color: #faff00 !important; color: #12131a !important;
}
body.app-tv.theme-cyberpunk #settings-tabbar .settings-tab.focused {
  border-color: #faff00 !important; color: #faff00 !important;
  box-shadow: 0 0 0 2px #faff00, 0 0 20px rgba(250, 255, 0, 0.45) !important;
}
body.app-tv.theme-cyberpunk #settings-tabbar .settings-tab.active.focused { color: #12131a !important; }
/* Buttons/Accordions in den Einstellungen: gelber Fokusring statt Akzent. */
body.app-tv.theme-cyberpunk #section-settings .platform-btn:not(.settings-tab).focused,
body.app-tv.theme-cyberpunk #section-settings .platform-accordion-toggle.focused,
body.app-tv.theme-cyberpunk #section-settings .pc-dd-trigger.focused {
  border-color: #faff00 !important; color: #faff00 !important;
  box-shadow: 0 0 0 2px #faff00, 0 0 18px rgba(250, 255, 0, 0.45) !important;
}
body.app-tv.theme-cyberpunk #section-settings .platform-btn.link {
  background: #faff00 !important; border-color: #faff00 !important; color: #12131a !important;
}
body.app-tv.theme-cyberpunk #section-settings .platform-btn.link.focused { color: #12131a !important; }
/* Segment + Hoster-Chips: „gehighlightet" ist auch hier gelb. */
body.app-tv.theme-cyberpunk #content #filter-tabs .filter-tab.active {
  background: #faff00 !important; color: #12131a !important;
}
body.app-tv.theme-cyberpunk #content #filter-tabs .filter-tab.focused {
  box-shadow: inset 0 0 0 2px #faff00 !important; color: #faff00 !important;
}
body.app-tv.theme-cyberpunk #content #filter-tabs .filter-tab.active.focused { color: #12131a !important; }
body.app-tv.theme-cyberpunk #session-platform-bar .sc-bubble.active,
body.app-tv.theme-cyberpunk #session-platform-bar .sc-bubble.on {
  background: #faff00 !important; border-color: #faff00 !important; color: #12131a !important;
}
body.app-tv.theme-cyberpunk #session-platform-bar .sc-bubble.focused {
  border-color: #faff00 !important;
  box-shadow: 0 0 0 2px #faff00, 0 0 18px rgba(250, 255, 0, 0.45) !important;
}

/* ── §33 (User 2026-07-26, Pkt 5): „Design speichern" war unlesbar ─────────────
   #ct-save traegt `.platform-btn.link` (Akzent-Fuellung + dunkle Schrift), bekam
   aber zusaetzlich den generischen Rahmen/Fokusring — Schrift und Rahmen lagen
   farblich uebereinander. Fuer den Primaer-Button den Kontrast explizit erzwingen.
   GERAETEUEBERGREIFEND gewuenscht („alle Plattformen") → daher ohne app-tv-Scope. */
#ct-save.platform-btn.link,
#ct-save.platform-btn.link:hover,
#ct-save.platform-btn.link.focused {
  background: var(--pc-accent) !important;
  border: 1px solid var(--pc-accent) !important;
  color: #0a0c12 !important;
  text-shadow: none !important;
  font-weight: 700 !important;
}
body.theme-cyberpunk #ct-save.platform-btn.link,
body.theme-cyberpunk #ct-save.platform-btn.link:hover,
body.theme-cyberpunk #ct-save.platform-btn.link.focused {
  background: #faff00 !important; border-color: #faff00 !important; color: #12131a !important;
}

/* ══════════════════════════════════════════════════════════════════════════
   §RESKIN-TV §34 — UI-TV-PIP-SETTINGS-FOCUS: PiP-Standardgroesse/-position
   ────────────────────────────────────────────────────────────────────────────
   Befund (live gegen die CSSOM-Kaskade geprueft, nicht gegen computed styles):
   Die sieben Knoepfe (#pip-size-s/-m/-l, #pip-corner-tl/-tr/-bl/-br) SIND laengst
   im TV-D-Pad-Fokusstrom — App.Settings.getButtons() sammelt
   `.platform-btn:not(.settings-tab)` und liefert sie im Player-Tab alle sieben.
   Unsichtbar war der AKTIVE Zustand: player.css setzt
   `.pip-seg-btn.active/.pip-corner-btn.active { background/border-color/color }`
   OHNE `!important`, waehrend §20 oben
   `body.app-tv #section-settings .platform-btn { background/border/color !important }`
   setzt. Auf dem TV gewinnt §20 → die aktuell gewaehlte Groesse/Ecke sah exakt aus
   wie die uebrigen, es gab keine Rueckmeldung, was eingestellt ist.
   Hier deshalb der aktive Zustand als deckende Akzentflaeche mit DUNKLEM
   Piktogramm/Label — dieselbe Sprache wie `#settings-tabbar .settings-tab.active`
   in §20 und die Sidebar in §32.
   ════════════════════════════════════════════════════════════════════════════ */
body.app-tv #section-settings .pip-seg-btn.active,
body.app-tv #section-settings .pip-corner-btn.active {
  background: var(--pc-accent) !important;
  border-color: var(--pc-accent) !important;
  color: #0a0c12 !important;
  font-weight: 700 !important;
}
/* Aktiv UND fokussiert: §20's Fokusregel zwingt `color: var(--pc-text)` (hell) —
   auf der hellen Akzentflaeche waere das Piktogramm/Label unlesbar. Schrift also
   zurueck auf dunkel invertieren (gleiches Muster wie `.settings-tab.active.focused`
   in §20). Der Ring bekommt zusaetzlich einen Trennsaum in Hintergrundfarbe, damit
   der Fokus auf der bereits akzentfarbenen Flaeche ueberhaupt ablesbar bleibt. */
body.app-tv #section-settings .pip-seg-btn.active.focused,
body.app-tv #section-settings .pip-corner-btn.active.focused {
  color: #0a0c12 !important;
  box-shadow: 0 0 0 2px var(--pc-bg), 0 0 0 4px var(--pc-accent), 0 0 18px var(--pc-glow) !important;
}
/* Cyberpunk auf dem TV: Highlight ist Neon-Gelb (§32) — Piktogramm bleibt dunkel. */
body.app-tv.theme-cyberpunk #section-settings .pip-seg-btn.active,
body.app-tv.theme-cyberpunk #section-settings .pip-corner-btn.active {
  background: #faff00 !important; border-color: #faff00 !important; color: #12131a !important;
}
body.app-tv.theme-cyberpunk #section-settings .pip-seg-btn.active.focused,
body.app-tv.theme-cyberpunk #section-settings .pip-corner-btn.active.focused {
  color: #12131a !important;
  box-shadow: 0 0 0 2px var(--pc-bg), 0 0 0 4px #faff00, 0 0 18px rgba(250, 255, 0, 0.45) !important;
}
/* TV-Treffflaeche: die 4 Ecken-Knoepfe sind auf 42x36 CSS-Pixel ausgelegt (Maus).
   Auf 1080p-TV-Distanz ist das Piktogramm zu klein, um die gewaehlte Ecke zu
   erkennen — Raster und Glyphe anheben, Layout bleibt dasselbe Grid. */
body.app-tv #section-settings .pip-corner-grid {
  grid-template-columns: repeat(2, 56px) !important;
  grid-template-rows: repeat(2, 48px) !important;
}
body.app-tv #section-settings .pip-corner-btn { font-size: 24px !important; }

/* ── 19) TV-Chat-Leiste (P1/#249, UI-MOBILE-VIEWPORT-2026-07-29) ─────────────
   Eigenständiger Container #player-chat (index.html, Begründung dort) — feste
   rechte Spalte ÜBER dem Fast-Fullscreen-Video, kein Reflow des Players.
   10-Fuß-lesbare Schriftgrößen (deutlich größer als die Desktop-Chat-Karte). */
body.app-tv #player-chat {
  position: fixed;
  top: 0; right: 0; bottom: 0;
  width: 360px;
  max-width: 32vw;
  z-index: 250;
  background: var(--pc-surface) !important;
  border-left: 1px solid var(--pc-border) !important;
  display: flex;
  flex-direction: column;
}
body.app-tv #player-chat.hidden { display: none !important; }
body.app-tv #player-chat-body { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
body.app-tv #player-chat-frame { flex: 1 1 auto; width: 100%; border: 0; background: var(--pc-bg); }
/* #TVVP6: `.hidden` ist in diesem Projekt KEIN global verdrahtetes display:none (Lesson
   [[project_empty_bar_collapse_286b]] / [[project_desktop_blackbar_playerchat]]). Ohne
   explizite Regel blieb der Chat-iframe trotz class="hidden" mit flex:1 1 auto im Layout
   (gemessen 812px hoch, top:72) und lag ÜBER der nativen Kick/Twitch-Nachrichtenliste
   (.plc-scroll) — die quoll nur als 20px-Streifen am unteren Rand raus. chat.js setzt die
   Klasse korrekt (frame.src='about:blank'+add('hidden') bei nativem Chat); es fehlte allein
   diese CSS-Regel, damit der leere iframe die Rail nicht mehr belegt/verdeckt. */
body.app-tv #player-chat-frame.hidden { display: none !important; }
/* #TVVP6-FU: gleicher `.hidden`-nicht-verdrahtet-Fallstrick beim Platzhalter. `#player-chat-
   placeholder` ist per Default `class="hidden"` UND `flex:1 1 auto` (s.u.); ohne Kollaps grabt
   der LEERE Platzhalter die obere Hälfte der Rail (flex:1) und drückt den nativen Chat
   (`#player-chat-native.plc`, ebenfalls flex:1, ins selbe #player-chat-body appended) nach
   unten → obere Rail-Hälfte leer, Chat nur unten. Sichtbar erst NACHDEM der #TVVP6-Frame-Fix
   den iframe rausnahm. mountNative() setzt korrekt add('hidden') — es fehlte nur der Kollaps. */
body.app-tv #player-chat-placeholder.hidden { display: none !important; }
body.app-tv #player-chat-placeholder {
  flex: 1 1 auto; display: flex; align-items: center; justify-content: center;
  padding: 24px; text-align: center; color: var(--pc-muted); font-size: 20px;
}
/* .plc-* baut App.Chat._buildNativeDom() geräteunabhängig dynamisch (Kick-/
   Dailymotion-Relay) — hier nur auf TV-Sitzabstand skaliert, keine eigene Logik. */
body.app-tv #player-chat .plc-head { padding: 14px 16px; font-size: 18px; }
/* #375: flex-basis 0 + height:0 statt basis:auto — auf alten webOS/Tizen-WebViews
   liess der auto-Basis die Nachrichtenliste mit dem Content mitwachsen (Chat baute
   sich von unten nach oben auf statt intern zu scrollen). Hoehe rein aus flex-grow. */
body.app-tv #player-chat .plc-scroll { flex: 1 1 0; min-height: 0; height: 0; overflow-y: auto; padding: 10px 16px; font-size: 18px; line-height: 1.5; }
body.app-tv #player-chat .plc-msg { margin-bottom: 8px; word-break: break-word; }
body.app-tv #player-chat .plc-readonly { padding: 8px 16px; font-size: 14px; color: var(--pc-muted); }
/* Bewusste Entscheidung (Ticket-Rahmen: "Chat laden/wechseln", keine D-Pad-
   Texteingabe verlangt): TV zeigt Chat nur LESEND. Ein Eingabefeld ohne
   erreichbare Tastatur wäre irreführende UX; das Nur-Lesen-Banner bliebe sonst
   inkonsistent sichtbar/unsichtbar je nach Server-Schreibrecht, obwohl auf dem
   TV so oder so nie getippt werden kann. */
body.app-tv #player-chat .plc-input-row { display: none !important; }
body.app-tv #section-settings .pip-seg-btn { min-width: 56px !important; }

/* ════════════════════════════════════════════════════════════════════════════
   TICKET-PLAYER-SHELL-CROSSPLATFORM Increment 3a — TV IMMERSIV-Zustand (TOS)
   Zwei-Zustands-Maschine (App.Player.setTvView, player.js): die Klasse .tv-immersive
   an #player-overlay = reiner Hoster-Player, NICHTS über dem Video. webOS honoriert
   die FS-API visuell nicht → Immersiv ist ein CSS-Zustand (nicht requestFullscreen).
   #player füllt den Overlay bereits (inset:0, theme-*.css:1508) — hier nur die
   PERSISTENTE Chrome-Schicht restlos ausblenden, die sonst über dem Player liegt:
     • #player-controls  = Auto-Hide-HUD inkl. #player-controls-bar (Zurück/Profil/
       Folgen + injizierte Ext-Buttons Snap/A/B/Loop/PiP + D-Pad-Farbtasten).
     • #player-chat      = feste rechte 360px-Rail (position:fixed, z-250).
     • #player-info      = unteres Info-Band (Name/Titel/Zuschauer).
   Transiente Elemente (Volume-HUD/Toasts, pointer-events:none) bleiben — sie sind
   keine persistente Bedien-Chrome. 1× BACK → .tv-videopage (Chrome in Bändern; das
   Mockup-Grid ergänzt Increment 3b — bis dahin die bestehende TV-Detailansicht).
   ════════════════════════════════════════════════════════════════════════════ */
body.app-tv #player-overlay.tv-immersive #player-controls,
body.app-tv #player-overlay.tv-immersive #player-chat,
body.app-tv #player-overlay.tv-immersive #player-info,
/* Increment 3b-3: die neuen persistenten Video-Seiten-Knoten (Top-Leiste + Reco-
   Sektion) MÜSSEN im Immersiv-Zustand ebenfalls restlos verschwinden (TOS: nichts
   über dem Player). */
body.app-tv #player-overlay.tv-immersive #tv-vp-topbar,
body.app-tv #player-overlay.tv-immersive #tv-vp-recos { display: none !important; }

/* ════════════════════════════════════════════════════════════════════════════
   TICKET-PLAYER-SHELL-CROSSPLATFORM Increment 3b-1 — TV VIDEO-SEITE (Layout-Grid)
   .tv-videopage formt die BESTEHENDEN Knoten in nicht-überlappende Bänder/Rails um,
   damit „nichts über dem Player" AUCH auf der Video-Seite gilt (TOS) — 0-Schnitt per
   Konstruktion: der Player sitzt in einem oberen Feld, die Chrome darum in reservierten
   Zonen. KEINE neuen persistenten Knoten in 3b-1 (Top-Suchleiste/Reco-Rail = 3b-2 mit
   Fokuskette), daher bleibt die Immersiv-Allowlist oben unverändert gültig.
   Reservierte Zonen (Koordinaten so gewählt, dass sie sich nie schneiden):
     • --tv-right = rechter Rand des Players/Bänder: 40px (VOD) bzw. 424px (Live, macht
       Platz für die 360px-Chat-Rail + 24px Lücke → Rail schneidet den Player nie).
     • #player (+yt/av/dm): oberes Feld  top:72 … bottom≈(100vh-220).
     • #player-controls: Button-Band ~ bottom:140 (unter dem Player).
     • #player-info: Meta-Band unten (bottom:72).
     • #player-chat: rechte Rail top:72 bottom:72 width:360 (nur .tv-vp-live).
   ════════════════════════════════════════════════════════════════════════════ */
body.app-tv #player-overlay.tv-videopage {
  background: var(--pc-bg, #0b0e14) !important;
  --tv-right: 40px;                 /* VOD: kein Chat → Player nutzt die Breite */
}
body.app-tv #player-overlay.tv-videopage.tv-vp-live { --tv-right: 424px; }  /* 40 + 360 Rail + 24 Lücke */

/* Video-Ebenen → oberes zentrales Feld (nie über die Bänder/Rail hinaus).
   WICHTIG: #player ist ein <iframe> = ERSETZTES Element → `width:auto` nimmt die
   iframe-Intrinsic-Breite (300px), NICHT die left/right-Constraint. Deshalb die Breite
   EXPLIZIT per calc (100% − linker Rand − rechter Rand) und `right:auto`. top+bottom
   spannen die Höhe deterministisch auf (keine 100vh-Rechnung, die mit der Bänder-Höhe
   kollidieren könnte). */
body.app-tv #player-overlay.tv-videopage #player,
body.app-tv #player-overlay.tv-videopage #yt-player,
body.app-tv #player-overlay.tv-videopage #av-player,
body.app-tv #player-overlay.tv-videopage #dm-player,
body.app-tv #player-overlay.tv-videopage #hls-video {
  /* #TVVP5: #hls-video (Kick nativer HLS im Browser-/Sim-Modus) war NICHT in dieser
     Box-Regel → das Video füllte die ganze linke Spalte und lag ÜBER dem Meta-Band
     (Titel/Creator standen auf dem Live-Video). Jetzt gleiche 66vh-Box wie die anderen
     Player-Flächen → Meta sitzt sauber DARUNTER. */
  top: 72px !important;
  left: 40px !important;
  right: auto !important;
  bottom: auto !important;
  width: calc(100% - 40px - var(--tv-right)) !important;
  height: calc(66vh - 72px) !important;   /* iframe = ersetztes Element: Höhe EXPLIZIT (auto nähme die 150px-Intrinsic). #TVVP3: von fester 392px-Reserve auf VIEWPORT-RELATIV umgestellt — Player oben:72, Unterkante bei 66vh. Der frühere feste 392px-Abzug fraß auf dem KÜRZEREN (nicht-vollbild) webOS-Browser-Viewport fast die ganze Höhe → winziger Player + große Leere darunter. 66vh hält den Player auf ~55-59% der Höhe (1080p: 641px, 730px-Fenster: 409px). Meta-Band beginnt bei 66vh+12 (direkt darunter), Controls-Band bleibt bottom:40+height:64 (Oberkante 100vh-104). */
  border-radius: 12px !important;
  overflow: hidden !important;
}

/* ════════════════════════════════════════════════════════════════════════════
   #TVVP16 — Echtes TV-PiP (Mini-Player) reparieren.
   Regression aus #TVVP10: der Power-Flip (webOS→'power', core.js) aktivierte den
   PiP-Button, aber App.Player.minimize() verkleinert #player-overlay IN-PLACE zur
   Mini-Box (Klassen is-mini-player + mini-tv) OHNE die tv-videopage/tv-vp-live-
   Layoutklassen zu entfernen. Deren !important-Geometrie direkt oben (Zeile 1021,
   width:calc(100% − 40 − var(--tv-right))) drückt in der ~380px-Mini-Box das Video
   mit NEGATIVER Breite raus (bei Live --tv-right:424 → calc(380−40−424)) → LEERE Box.
   Zusätzlich bleibt die position:fixed-Chat-Rail #player-chat (360px, z-250) stehen
   und liegt über der freigelegten Home-Seite (User-Symptom). Fix rein CSS, KEIN
   State-Machine-Eingriff:
   (1) Im Mini-Zustand das Video die Mini-Box füllen lassen — höhere Spezifität
       (…is-mini-player.mini-tv…#player = (0,2,3,1)) sticht die tv-videopage-Regel
       ((0,2,2,1)) trotz deren !important.
   (2) Chat-Rail im Mini kollabieren — [[project_desktop_blackbar_playerchat]]:
       .hidden ist projektweit KEIN globales display:none; hier greift der Mini-
       Zustand (body.player-mini / .is-mini-player.mini-tv), nicht .hidden. */
body.app-tv #player-overlay.is-mini-player.mini-tv #player,
body.app-tv #player-overlay.is-mini-player.mini-tv #yt-player,
body.app-tv #player-overlay.is-mini-player.mini-tv #av-player,
body.app-tv #player-overlay.is-mini-player.mini-tv #dm-player,
body.app-tv #player-overlay.is-mini-player.mini-tv #hls-video {
  top: 0 !important;
  left: 0 !important;
  right: 0 !important;
  bottom: 0 !important;
  width: 100% !important;
  height: 100% !important;
  border-radius: 0 !important;
}
/* Chat-Rail (position:fixed → schrumpft NICHT mit dem Overlay) im Mini ausblenden,
   sonst liegt sie über Home. Doppelt verankert (Body-Mini-Klasse UND Overlay-Mini-
   Zustand), damit sie in beiden Zuständen sicher kollabiert. #player-info deckt der
   Theme-Mini-Ausblendsatz bereits ab — hier defensiv mitgenommen. */
body.app-tv.player-mini #player-chat,
body.app-tv.player-mini #player-chat-frame,
body.app-tv #player-overlay.is-mini-player.mini-tv #player-chat,
body.app-tv #player-overlay.is-mini-player.mini-tv #player-info {
  display: none !important;
}

/* #459: Im TV-Mini-Player (PiP) darf NICHTS über dem Video liegen — bei YouTube ist jegliches
   Overlay über dem Player ein ToS-Verstoß, generell wirkt es unsauber. Der Mini-Zustand behält
   die .tv-videopage-Klasse (#TVVP16 entfernt sie bewusst nicht), daher rendert sonst die volle
   Videopage-Chrome (Button-Band Zurück/Profil/Folgen/Pause, Topbar, Empfehlungs-Rail) über bzw.
   um die ~380px-Mini-Box. Chat/Info deckt der Satz darüber bereits ab; hier die restlichen
   Chrome-Ebenen hart kollabieren, damit die Mini-Box ausschließlich das reine Video zeigt. */
body.app-tv #player-overlay.is-mini-player.mini-tv #player-controls,
body.app-tv #player-overlay.is-mini-player.mini-tv #player-controls-bar,
body.app-tv #player-overlay.is-mini-player.mini-tv #tv-vp-topbar,
body.app-tv #player-overlay.is-mini-player.mini-tv #tv-vp-recos {
  display: none !important;
}

/* Button-Band (Zurück/Profil/Folgen + Ext) UNTER dem Player — aus dem inset:0-HUD zu
   einem flachen Band mit FESTER Höhe (deterministischer 0-Schnitt zum Player oben und
   zum Meta-Band unten). #player-controls-top (Titel/Sub) in videopage ausgeblendet (die
   Meta steht in #player-info). Horizontaler Überlauf scrollt, KEIN vertikaler (→ das
   Band wächst nie in den Player). */
body.app-tv #player-overlay.tv-videopage #player-controls {
  position: absolute !important;
  top: auto !important;
  left: 40px !important;
  right: var(--tv-right) !important;
  bottom: 40px !important;   /* #TVVP-DESIGN: von 152→40 nach GANZ UNTEN verlegt, da das Meta-Band jetzt DIREKT unter dem Player steht (Stapel Player → Meta → Controls). */
  height: 64px !important;
  display: block !important;
  /* FIX-1 (#368③-FU-B): overflow war `overflow-x:auto; overflow-y:hidden` — das
     schnitt den Fokusring/Glow der Buttons oben/unten (und links/rechts) ab. Die
     Anti-Wachstum-Garantie („Band wächst nie in den Player") kommt NICHT vom overflow,
     sondern von position:absolute + fixer height:64px (Content kann das Band nie
     dehnen). Darum overflow:visible → der Ring paintet frei, das Band bleibt trotzdem
     64px hoch. Auf dem TV passen die ≤5 Buttons (Zurück/Profil/Folgen[/PiP/PiP-Toggle])
     immer in die Bandbreite (calc(100% − 40 − --tv-right)); horizontaler Scroll wird
     nie gebraucht, sein Wegfall ist folgenlos. */
  overflow: visible !important;
  pointer-events: none;
}
body.app-tv #player-overlay.tv-videopage #player-controls-top { display: none !important; }
body.app-tv #player-overlay.tv-videopage #player-controls-bar {
  pointer-events: auto;
  justify-content: flex-start !important;
}
/* #TVVP4: „Abonnieren" lebt wieder als reguläre Taste in der Leiste (Mockup-Layout:
   Zurück · Pause · PiP · Profil · Abonnieren). Die frühere #TVVP3-Ausblendung entfällt.
   Stattdessen: die Meta-Pille ausblenden (Follow ist nur noch die Leisten-Taste), den
   Spacer ausblenden (Tasten links zusammen), die neue Pause-Taste in Akzentfarbe. */
body.app-tv #player-overlay.tv-videopage #player-info-follow { display: none !important; }
body.app-tv #player-overlay.tv-videopage #player-controls-bar .player-ctl-spacer { display: none !important; }
body.app-tv #player-overlay.tv-videopage #player-controls-bar .player-ctl-accent {
  background: var(--pc-accent) !important; color: #0b0714 !important;
  border-color: var(--pc-accent) !important;
}
/* #TVVP25 / #439: Like/Dislike-Reaktions-Buttons. Aktive Reaktion = Akzentfläche,
   analog zur „+ Folgen"-Pille (deckungsgleiche On-Akzent-Konstante #0b0714). Der D-Pad-
   Fokusring kommt weiter global vom .focused-State (#TVVP20). Greift für ALLE TV-Player
   (Video + Live).
   #439: Emoji-Daumen → Outline-Daumen-SVG (Reskin-Vorlage „PubliCore Web - Player").
   Das SVG erbt currentColor → folgt dem Theme-Text bzw. dem On-Akzent (#0b0714) im
   .active-Zustand. Dislike = derselbe Daumen um 180° gedreht. Like-Zähler (card.likes)
   nur sichtbar, wenn renderTvReactions .has-count setzt (YT-VOD); sonst reines Icon. */
body.app-tv #player-controls-bar .player-ctl-react { font-size: 17px !important; line-height: 1 !important; gap: 8px !important; }
body.app-tv #player-controls-bar .player-ctl-react .pcr-ic {
  display: inline-flex !important; align-items: center !important; justify-content: center !important;
  width: 22px !important; height: 22px !important; flex: none !important;
}
body.app-tv #player-controls-bar .player-ctl-react .pcr-ic svg { width: 22px !important; height: 22px !important; display: block !important; }
body.app-tv #player-controls-bar .player-ctl-react .pcr-ic-down svg { transform: rotate(180deg) !important; }
body.app-tv #player-controls-bar .player-ctl-react .pcr-count { font-size: 16px !important; font-weight: 600 !important; line-height: 1 !important; }
body.app-tv #player-controls-bar .player-ctl-react:not(.has-count) .pcr-count { display: none !important; }
body.app-tv #player-controls-bar .player-ctl-react.active {
  background: var(--pc-accent) !important; color: #0b0714 !important;
  border-color: var(--pc-accent) !important;
}

/* #469: Vollbild-Button (Expand-Icon) — gleiche Icon-Metrik wie die Reaktions-Daumen. */
body.app-tv #player-controls-bar .player-ctl-fs .pcr-ic {
  display: inline-flex !important; align-items: center !important; justify-content: center !important;
  width: 22px !important; height: 22px !important; flex: none !important;
}
body.app-tv #player-controls-bar .player-ctl-fs .pcr-ic svg { width: 22px !important; height: 22px !important; display: block !important; }

/* #469: Like/Dislike optisch zu EINER geteilten Pille verschmelzen (schafft Platz für den
   Vollbild-Button). Der Wrapper .pcr-pill ist REIN Layout (kein eigener Button, kein D-Pad-
   Ziel); die zwei Segmente bleiben eigenständige .player-ctl → D-Pad-Kette + .focused-Glow
   je Hälfte unverändert. Mittige Trennlinie = linker Rand des Dislike-Segments; äußere
   Pillen-Rundung nur an den beiden Aussenkanten. Segmente liegen bündig (kein bar-gap im
   Wrapper), sodass sie als eine Pille lesen. */
body.app-tv #player-controls-bar .pcr-pill { display: inline-flex !important; align-items: stretch !important; }
body.app-tv #player-controls-bar .pcr-pill .player-ctl-react { border-radius: 0 !important; }
body.app-tv #player-controls-bar .pcr-pill .player-ctl-react-like {
  border-top-left-radius: 999px !important; border-bottom-left-radius: 999px !important;
  border-right-width: 0 !important;   /* Trennlinie kommt vom linken Rand des Dislike-Segments */
}
body.app-tv #player-controls-bar .pcr-pill .player-ctl-react-dislike {
  border-top-right-radius: 999px !important; border-bottom-right-radius: 999px !important;
}

/* #TVVP-DESIGN: Meta-Band DIREKT unter dem Player (Vorlage Panel 01) — top-anchored,
   auto-Höhe, überlaufsichtbar (Fokusglow der Follow-Pille). Stapel: Player (bis
   100vh-392) → 16px Lücke → Meta (ab 100vh-376) → Controls-Band (ab 100vh-104). Als
   Flex-Spalte gestapelt: Titel → Creator-Zeile (Avatar+Name/Zähler+Folgen) → Beschreibung.
   KEIN Surface-Band mehr (transparent); nur die Beschreibungsbox trägt ein Surface. */
body.app-tv #player-overlay.tv-videopage #player-info {
  position: absolute !important;
  /* #TVVP3: direkt unter dem Player (Unterkante 66vh) + fest über dem Controls-Band
     (bottom:104 = Oberkante des 40+64-Bands). Dadurch skaliert das Meta-Band mit dem
     Player mit und die frühere große Leere zwischen Meta und Controls verschwindet. */
  top: calc(66vh + 12px) !important;
  left: 40px !important;
  right: var(--tv-right) !important;
  bottom: 104px !important;
  height: auto !important;
  /* #TVVP5: Meta ist jetzt eine KARTE (Follow-Pille wohnt seit #TVVP4 in der Leiste, kein
     Fokus-Glow mehr zu schützen) → overflow hidden, damit der Karten-Rahmen sauber clippt. */
  overflow: hidden !important;
  /* Theme-Basis (#player-info) versteckt via transform:translateY(110%); auf der
     Video-Seite steht das Band top-anchored sichtbar unter dem Player → Transform aus. */
  transform: none !important;
  display: flex !important;
  flex-direction: column;
  align-items: stretch;   /* #TVVP2: Kinder spannen die linke Spalte, linksbündig. */
  text-align: left !important;
  gap: 10px;
  /* #TVVP5 (User: „einen Rahmen geben, nicht so leer"): Meta als Surface-Karte statt
     freistehendem Text — Hintergrund, Rahmen, Radius, Innenabstand. */
  background: var(--pc-surface) !important;
  border: 1px solid var(--pc-border) !important;
  border-top: 1px solid var(--pc-border) !important;
  border-radius: 12px;
  padding: 16px 18px;
  box-sizing: border-box;
}
/* Titel groß, voller Textkontrast. #TVVP25: 24→28px (User: „Text unter Video zu klein
   für den TV, wir haben ja den Platz darunter"). Überschreibt die Basis-muted-Regel. */
body.app-tv #player-overlay.tv-videopage #player-info-title {
  font-size: 28px !important;
  font-weight: 600;
  line-height: 1.3;
  color: var(--pc-text) !important;
  white-space: normal;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
/* Creator-Zeile: Avatar (48px) · Name+Zähler-Spalte · „+ Folgen"-Pille rechts. */
body.app-tv #player-overlay.tv-videopage #player-info-row {
  display: flex; align-items: center; gap: 16px;
}
body.app-tv #player-overlay.tv-videopage #player-info-avatar {
  /* #TVVP25: Avatar 48→56px, passend zur größeren Creator-Zeile. */
  width: 56px; height: 56px; flex: none; border-radius: 50%; object-fit: cover;
  border: 1px solid var(--pc-border); background: var(--pc-surface2);
}
body.app-tv #player-overlay.tv-videopage #player-info-avatar:not([src]),
body.app-tv #player-overlay.tv-videopage #player-info-avatar[src=""] { display: none; }
body.app-tv #player-overlay.tv-videopage #player-info-idcol {
  /* #TVVP5 (User: „Hoster-Icon rechts neben den Streamer"): idcol NICHT mehr dehnen
     (flex 1→0), damit die Creator-Zeile links zusammenpackt und das Hoster-Badge direkt
     rechts neben der Namensspalte sitzt statt am fernen rechten Rand. */
  flex: 0 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px;
}
body.app-tv #player-overlay.tv-videopage #player-info-name {
  /* #TVVP15/#TVVP25 (User: „Streamername + Infos von der Schrift her größer — massiv
     Platz darunter"): Name 17→22→26px. */
  font-size: 26px !important; font-weight: 600; color: var(--pc-text) !important;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* #TVVP2: Hoster-Badge (Plattform-Logo). #TVVP15 (User: „Hoster-Logo nach ganz links"):
   per order:-1 vor Avatar+Namensspalte als führendes Element der Creator-Zeile — statt
   wie zuvor rechts neben der Namensspalte. Leer → ausgeblendet. */
body.app-tv #player-overlay.tv-videopage #player-info-host {
  order: -1;
  /* #TVVP25: Hoster-Badge 44→52px, passend zur größeren Creator-Zeile. */
  width: 52px; height: 52px; flex: none; border-radius: 50%; object-fit: contain;
  padding: 10px; box-sizing: border-box;
  background: var(--pc-surface2); border: 1px solid var(--pc-border);
}
body.app-tv #player-overlay.tv-videopage #player-info-host:not([src]),
body.app-tv #player-overlay.tv-videopage #player-info-host[src=""] { display: none; }
/* „+ Folgen"-Pille (Vorlage: Akzent-Fläche, radius 23, ~46px). Akzent-Vordergrund
   #0b0714 = fileweite On-Akzent-Konstante (deckungsgleich .tv-reco-tab.active); es
   existiert kein --pc-onaccent-Token, alle 9 Akzente sind dunkel-genug für dunklen Text. */
body.app-tv #player-overlay.tv-videopage #player-info-follow {
  flex: none; height: 46px; padding: 0 24px; border-radius: 23px;
  background: var(--pc-accent); color: #0b0714; border: none;
  font-size: 16px; font-weight: 600; cursor: pointer; white-space: nowrap;
}
body.app-tv #player-overlay.tv-videopage #player-info-follow:empty { display: none; }
/* #TVVP5: Beschreibung SCHLICHT im Kartenrahmen (die Meta-Karte #player-info trägt jetzt
   Surface+Rahmen) — keine eigene Box mehr, sonst Doppel-Rahmen. */
body.app-tv #player-overlay.tv-videopage #player-info-desc {
  padding: 0; border-radius: 0;
  background: transparent; border: none;
  color: var(--pc-muted); font-size: 17px; line-height: 1.55;
  /* #TVVP3-Claufix / #TVVP25: Beschreibung auf 3 Zeilen (der User will den Platz unter
     dem Player genutzt sehen). Titel 2Z + Creator-Zeile + Zähler 2Z + Beschreibung 3Z
     bleiben unter der festen Bandhöhe (top 66vh+12 → bottom 104), die opake Box
     überlappt die Steuerleiste nicht. */
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
  white-space: pre-line;
}
body.app-tv #player-overlay.tv-videopage #player-info-desc:empty { display: none; }
/* pi-meta (Zuschauer/Spiel) trägt auf der TV-Video-Seite keine Daten (Zähler stehen in
   .tv-meta-counts) → aus dem Fluss nehmen, damit keine Leerlücke entsteht. */
body.app-tv #player-overlay.tv-videopage .pi-meta { display: none; }

/* Live-Chat-Rail rechts — reserviert, NEBEN dem Player (nur .tv-vp-live). Überschreibt
   die feste Vollhöhen-Immersiv-Rail (reskin-tv.css:854 fixed right:0) zu einer Rail,
   die exakt in die reservierte 360px-Zone passt → 0-Schnitt mit dem Player. */
body.app-tv #player-overlay.tv-videopage #player-chat {
  top: 72px !important;
  bottom: 56px !important;
  right: 40px !important;
  left: auto !important;
  width: 360px !important;
  max-width: 360px !important;
}
body.app-tv #player-overlay.tv-videopage:not(.tv-vp-live) #player-chat { display: none !important; }

/* Increment 3b-2: Meta-Zähler-Zeile im Meta-Band (nur Video-Seite). Kind von
   #player-info → im Immersiv automatisch mit-ausgeblendet (TOS). */
body.app-tv #player-overlay.tv-videopage .tv-meta-counts {
  margin-top: 0;
  /* #TVVP15/#TVVP25: Meta-Infos (sehen zu · seit · Hoster · Follower bzw. Aufrufe ·
     Abonnenten · Upload) 15→18→22px — der User will Streamername/Zeit/Viewer deutlich
     größer, es ist massiv Platz unter dem Meta-Band. */
  font-size: 22px;
  line-height: 1.4;
  color: var(--pc-muted, #9aa0b5);
  /* #TVVP-DESIGN: nowrap/ellipsis ENTFERNT → mehrzeilige Zähler-Zeile erlaubt.
     Claufix (Claudit-LOW): auf 2 Zeilen clampen, damit der Meta-Block auch im
     Extremfall (sehr lange Zähler-Zeile) die 14px-Reserve zum Controls-Band nie
     überschreitet → garantiert keine Band-Kollision. */
  white-space: normal;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
}
body.app-tv #player-overlay.tv-videopage .tv-meta-counts:empty { display: none; }

/* ════════════════════════════════════════════════════════════════════════════
   TICKET-PLAYER-SHELL-CROSSPLATFORM Increment 3b-3 — Top-Leiste + Reco-Sektion
   (nur app-tv Video-Seite). Fortsetzung des 3b-1-Prinzips: reservierte, sich NIE
   schneidende Bänder → 0-Schnitt zum #player PER KONSTRUKTION (kein Overlay-Scroll,
   der die Top-Leiste über den Player schieben könnte). Beide neuen Knoten stehen in
   der Immersiv-Allowlist (oben) → im Immersiv-Zustand display:none (TOS).
     • Top-Leiste  = Band 0…64px OBERHALB des Players (Player beginnt bei top:72).
     • Reco-Sektion = unteres Band (NUR VOD); Player/Controls/Meta neu budgetiert,
       damit alles überlappungsfrei stapelt. Live (Panel 02) behält das 3b-1-Layout
       (Player + rechte Chat-Rail), die Reco-Sektion ist dort ausgeblendet.
   iframe-Höhen weiterhin EXPLIZIT per calc (ersetztes Element, s. 3b-1).
   ════════════════════════════════════════════════════════════════════════════ */

/* Neue Knoten NUR auf der TV-Video-Seite sichtbar (sonst aus dem Weg — Geräteklassen-
   Gating: reine app-tv-Chrome, greift auf Desktop/Handy nie). */
body.app-tv #tv-vp-topbar, body.app-tv #tv-vp-recos { display: none; }

/* ── Top-Leiste (VOD + Live) ── Band über dem Player, scrollt nicht/überlappt nie. */
body.app-tv #player-overlay.tv-videopage #tv-vp-topbar {
  display: flex; align-items: center; gap: 18px;
  position: absolute; top: 0; left: 0; right: 0; height: 64px;
  padding: 0 40px; box-sizing: border-box;
  border-bottom: 1px solid var(--pc-border);
  background: var(--pc-bg, #0b0e14); z-index: 6;
}
body.app-tv #tv-vp-back {
  flex: none; display: inline-flex; align-items: center; height: 40px; padding: 0 18px;
  border-radius: 12px; background: var(--pc-surface2, #1d1435);
  border: 1px solid var(--pc-border); color: var(--pc-muted); font-size: 16px; cursor: pointer;
}
body.app-tv #tv-vp-search {
  flex: 1 1 auto; min-width: 0; display: inline-flex; align-items: center; height: 44px;
  padding: 0 20px; border-radius: 22px; background: var(--pc-surface2, #1d1435);
  border: 1px solid var(--pc-border); color: var(--pc-muted); font-size: 16px;
  text-align: left; overflow: hidden; cursor: pointer;
}
body.app-tv #tv-vp-search-label { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
body.app-tv .tv-vp-wordmark { flex: none; font-size: 18px; color: var(--pc-text); }
body.app-tv .tv-vp-wordmark span:first-child { font-weight: 700; }

/* ── FIX-#368 VOD-Rechts-Rail-Reserve (ersetzt die frühere Unten-Band-Budgetierung) ──
   Die Reco-Empfehlungen stehen jetzt als rechte VERTIKALE Rail (analog zur Live-Chat-
   Rail #player-chat), nicht mehr als unteres horizontales Band. Statt den Player nach
   UNTEN zu budgetieren, reservieren wir RECHTS Platz über --tv-right — exakt das Muster
   der Live-Chat-Rail (dort 40 + 360 Rail + 24 Lücke = 424). Hier: 40 + 420 Reco-Rail +
   24 Lücke = 484. Dadurch fallen #player / #player-controls / #player-info auf das
   Basis-3b-1-Layout zurück (Breite = calc(100% − 40 − var(--tv-right)), volle nutzbare
   Höhe, Controls/Meta rechts an --tv-right geklemmt) → das Video schrumpft nach LINKS,
   die Reco-Rail füllt die reservierte Rechts-Spalte. Kein Player-Override mehr nötig. */
body.app-tv #player-overlay.tv-videopage:not(.tv-vp-live) { --tv-right: 484px; }

/* ── Reco-Sektion (NUR VOD) ── FIX-#368: rechte VERTIKALE Rail (analog Live-Chat-Rail
   #player-chat: top:72 bottom:56 right:40). Kopf (Titel/Tabs) oben fix, darunter die
   vertikal scrollende Kartenliste. Die Spalten-Reserve kommt aus --tv-right (484). */
body.app-tv #player-overlay.tv-videopage.tv-vp-live #tv-vp-recos { display: none !important; }
body.app-tv #player-overlay.tv-videopage:not(.tv-vp-live) #tv-vp-recos {
  display: flex; flex-direction: column;
  position: absolute; top: 72px; bottom: 56px; right: 40px; left: auto; width: 420px;
  z-index: 5;
}
body.app-tv #tv-vp-recos-head {
  flex: none; display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px;
}
body.app-tv #tv-vp-recos-title { font-size: 20px; font-weight: 600; color: var(--pc-text); }
body.app-tv #tv-vp-tabs { display: flex; gap: 8px; }
body.app-tv .tv-reco-tab {
  height: 34px; padding: 0 16px; border-radius: 17px;
  background: var(--pc-surface2, #1d1435); border: 1px solid var(--pc-border);
  color: var(--pc-muted); font-size: 15px; cursor: pointer;
}
body.app-tv .tv-reco-tab.active {
  background: var(--pc-accent); color: #0b0714; border-color: var(--pc-accent); font-weight: 600;
}
body.app-tv #tv-vp-rail {
  flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; gap: 14px;
  overflow-y: auto; overflow-x: hidden;
  scrollbar-width: none;   /* #TVVP-DESIGN: Scrollbalken weg (Fokus-Scroll bleibt). */
  /* FIX-1 (#368③-FU-B): overflow-x:hidden (+ scrollendes overflow-y) beschnitt sonst
     den 3px-Fokusring der Reco-Kacheln seitlich/oben/unten. Etwas Innenabstand gibt
     dem Ring Luft im Scrollport, ohne das Rail-Layout (width:420) spürbar zu ändern. */
  padding: 4px 6px;
}
body.app-tv #tv-vp-rail::-webkit-scrollbar { display: none; }   /* #TVVP-DESIGN */
body.app-tv .tv-reco-tile {
  width: 100%; flex: none; display: flex; flex-direction: column; cursor: pointer;
}
body.app-tv .tv-reco-thumb {
  /* #RECOTHUMB-169 (User): die feste Höhe 124px ergab bei ~408px Rail-Breite ~3:1 →
     background-size:cover schnitt oben/unten weg (Creator legen dort Text/Infos ab).
     Jetzt echtes 16:9 per padding-bottom-Technik (height:0 + padding-bottom:56.25%) —
     bewusst NICHT `aspect-ratio` (auf alten TV-Browsern/chrome53 nicht garantiert). Bei
     16:9-Thumbnail füllt cover exakt, ohne Beschnitt; die absolut positionierten Badges
     (LIVE/Dauer, bottom:6) sitzen weiter am unteren Rand des sichtbaren Bildes. */
  position: relative; width: 100%; height: 0; padding-bottom: 56.25%; border-radius: 9px;
  background-size: cover; background-position: center; border: 1px solid var(--pc-border);
}
body.app-tv .tv-reco-live {
  position: absolute; bottom: 6px; right: 6px; padding: 0 6px; height: 18px;
  display: inline-flex; align-items: center; gap: 4px; border-radius: 4px;
  background: var(--pc-live, #ff3d81); font-size: 11px; font-weight: 700; color: #fff;
}
body.app-tv .tv-reco-dur {
  position: absolute; bottom: 6px; right: 6px; padding: 0 5px; height: 17px;
  display: inline-flex; align-items: center; border-radius: 4px;
  background: rgba(8,9,14,.85); font-size: 12px; color: #fff;
}
body.app-tv .tv-reco-tmeta { padding: 6px 2px 0; min-height: 0; }
body.app-tv .tv-reco-title {
  font-size: 15px; line-height: 1.3; color: var(--pc-text);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
body.app-tv .tv-reco-chan { display: flex; align-items: center; gap: 6px; margin-top: 4px; }
body.app-tv .tv-reco-logo { width: 16px; height: 16px; flex: none; }
body.app-tv .tv-reco-chan span {
  font-size: 13px; color: var(--pc-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
body.app-tv .tv-reco-empty { color: var(--pc-muted); font-size: 15px; padding: 8px 2px; }

/* ── Fokusring (2-D-Zonen) ── deckungsgleich mit .player-ctl.focused (Akzent + Glow),
   konsistent über alle Zonen inkl. Player-Feld, Reco-Kacheln, Chat-Rail. */
body.app-tv #player-overlay.tv-videopage .tv-focus {
  outline: none !important;
  /* FIX-1 (#368③-FU-B): deckungsgleich mit .player-ctl.focused verstärkt — weiße
     Innen-Haarlinie (Hochkontrast in dunklen Themes) + 3px Akzentring + kräftigerer
     Glow. Gilt für alle 2-D-Zonen (Topbar Back/Search, Player-Feld, Reco-Tabs/-Kacheln,
     Chat-Rail). */
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.9), 0 0 0 3px var(--pc-accent), 0 0 26px 3px var(--pc-glow) !important;
  border-color: var(--pc-accent) !important;
  border-radius: 10px;
}

/* #TVVP12: „Drücke OK, um mit Ton abzuspielen"-Hinweis im Immersiv-Zustand. Standard aus;
   nur im echten Immersiv-Zustand (#player-overlay.tv-immersive) + .show sichtbar → auf der
   Videoseite automatisch weg. Rein informativ (pointer-events:none), fängt keine Tasten ab. */
#tv-unmute-prompt { display: none; }
body.app-tv #player-overlay.tv-immersive #tv-unmute-prompt.show {
  display: block;
  position: absolute;
  left: 50%;
  bottom: 12%;
  transform: translateX(-50%);
  z-index: 40;
  max-width: 80vw;
  padding: 0.7em 1.5em;
  border-radius: 999px;
  background: rgba(6, 10, 20, 0.82);
  border: 2px solid var(--pc-accent, #21d4fd);
  box-shadow: 0 0 20px 2px var(--pc-glow, rgba(33, 212, 253, 0.5));
  color: #fff;
  font-size: 1.2rem;
  font-weight: 600;
  line-height: 1.3;
  text-align: center;
  pointer-events: none;
  animation: tvUnmutePulse 1.8s ease-in-out infinite;
}
@keyframes tvUnmutePulse {
  0%, 100% { opacity: 0.92; }
  50%      { opacity: 0.6; }
}

/* #467: „Press OK to play"-Hinweis auf der TV-Video-Seite (kleiner Player) für Twitch,
   das auf webOS pausiert startet. Über dem Player (linke Spalte, obere Hälfte), NICHT über
   der unteren Steuerleiste. Rein informativ (pointer-events:none); JS auto-hide nach 6s /
   erste OK-Geste. Positionierung ggf. on-device feinjustieren. */
#tv-play-prompt { display: none; }
body.app-tv #player-overlay.tv-videopage #tv-play-prompt.show {
  display: block;
  position: absolute;
  left: 40px;
  top: 30vh;
  right: var(--tv-right, 33%);
  margin: 0 auto;
  z-index: 41;
  width: max-content;
  max-width: 46vw;
  padding: 0.65em 1.4em;
  border-radius: 999px;
  background: rgba(6, 10, 20, 0.85);
  border: 2px solid var(--pc-accent, #21d4fd);
  box-shadow: 0 0 20px 2px var(--pc-glow, rgba(33, 212, 253, 0.5));
  color: #fff;
  font-size: 1.15rem;
  font-weight: 600;
  line-height: 1.3;
  text-align: center;
  pointer-events: none;
  animation: tvUnmutePulse 1.8s ease-in-out infinite;
}

/* ── #TVVP19: D-Pad-Fokus im Creator-/Streamer-Profil-Overlay ─────────────────
   Das Overlay war auf dem TV per D-Pad unbedienbar (keine Fokuszone). Die drei
   Ebenen (Header-Aktionen / Tabs / Karten) bekommen einen klaren Akzent-Ring.
   Die Karten (.video-card.focused) nutzen bereits die bestehende TV-Fokus-Optik
   weiter oben in dieser Datei — hier nur Header-Aktionen und Tabs ergänzt.
   box-shadow statt outline, da die Buttons runde Ecken/clippende Container haben. */
body.app-tv #creator-overlay #creator-close.focused,
body.app-tv #creator-overlay #creator-group-btn.focused,
body.app-tv #creator-overlay #creator-follow.focused,
body.app-tv #creator-overlay #creator-report.focused {
  border-color: var(--pc-accent) !important;
  color: var(--pc-text) !important;
  box-shadow: 0 0 0 2px var(--pc-accent), 0 0 18px var(--pc-glow) !important;
  outline: none !important;
}
body.app-tv #creator-overlay .creator-tab.focused {
  color: var(--pc-text) !important;
  box-shadow: inset 0 0 0 2px var(--pc-accent) !important;
  border-radius: 8px !important;
}
/* #496: Aktiver Tab braucht auf TV-Distanz (3 m) mehr als einen dünnen Unterstrich.
   Gefüllte Fläche mit Accent-Farbe analog zu .creator-chan-chip.active. */
body.app-tv #creator-overlay .creator-tab.active {
  background: var(--pc-accent) !important;
  color: var(--pc-accent-contrast, #fff) !important;
  border-bottom-color: transparent !important;
  border-radius: 8px !important;
}
/* ── #462: Profil-Overlay-Header auf TV entzerren + lesbarer machen ──────────────
   Alle Fixes NUR auf TV; Desktop/Mobile unberührt.
   (a) „zu nah am X": die Aktions-Buttons (Gruppe/Folgen/Melden) standen nur ~4px vom
       absolut positionierten ✕ entfernt (und überlappten vertikal) → margin-right
       schafft klaren Abstand zum Schließen-Button.
   (b) „Gruppen-Button nicht erkennbar": der icon-only Ordner-Button hatte einen
       fast unsichtbaren Rahmen (0.09 alpha) → sichtbarer Rahmen + Flächen-Ton, damit
       er als Button lesbar ist (Fokus-Ring aus dem Block oben bleibt vorrangig).
   (c) „Hoster nicht sichtbar genug": die Plattform-Zeile (#creator-meta) war grau
       (rgb144) + 13px + 16px-Logo → auf 10-Fuß-Distanz zu blass/klein. */
body.app-tv #creator-overlay #creator-header-actions { margin-right: 52px; }
body.app-tv #creator-overlay #creator-group-btn {
  background: rgba(255,255,255,0.10) !important;
  /* Explizite Rahmenfarbe statt var(--pc-border) — letzteres ist rgba(255,255,255,0.09)
     (fast unsichtbar, gleicher Wert wie die .player-ctl-Basis). */
  border: 1px solid rgba(255,255,255,0.40) !important;
}
body.app-tv #creator-overlay #creator-meta {
  color: var(--pc-text, #f2f4f8) !important;
  font-size: 15px !important;
}

/* ── #514: Kalender-Einträge im Profil auf TV lesbar machen ──────────────────────
   Die Basis (.cal-when=var(--purple), .cal-title=var(--text), .cal-cat=var(--text-dim))
   war auf 3-m-Distanz zu blass (User-Screenshot: kaum lesbar). Kontraste + Größe hoch,
   klarere Kartenfläche. Nur app-tv. */
body.app-tv #creator-overlay .cal-item {
  background: var(--pc-surface2, #29292c) !important;
  border: 1px solid rgba(255,255,255,0.14) !important;
  padding: 14px 16px !important;
}
body.app-tv #creator-overlay .cal-when {
  color: var(--pc-accent2, #d8dade) !important;
  font-size: 15px !important;
  min-width: 168px !important;
}
body.app-tv #creator-overlay .cal-title {
  color: var(--pc-text, #f2f4f8) !important;
  font-size: 17px !important;
}
body.app-tv #creator-overlay .cal-cat {
  color: var(--pc-text, #eaeaec) !important;
  opacity: 0.72 !important;
  font-size: 14px !important;
}
/* ── #515: Info-Folgen-Chip + Kalender-Erinnerungsglocke auf TV größer/lesbarer.
   Der D-Pad-Fokusring erbt die generische app-tv `.focused:not(.video-card)`-Optik
   (reskin-tv.css:159) — kein Extra-Ring nötig. Nur Größe/Kontrast fürs 3-m-Sofa. */
body.app-tv #creator-overlay .cal-bell {
  font-size: 15px !important; padding: 9px 15px !important;
}
body.app-tv #creator-overlay .creator-chan-follow {
  font-size: 14px !important; padding: 6px 13px !important;
}

/* ── #516: Profil-Overlay auf TV groesser — mehr Flaeche fuer den Content ────────
   Ohne app-tv-Override nutzte das Overlay die generische Desktop-Box (max-width:1280px
   / height:86vh). Auf dem grossen TV-Screen ist das zu klein → prominenter machen. */
body.app-tv #creator-box {
  max-width: 1680px !important;
  width: 94vw !important;
  height: 92vh !important;
  max-height: 92vh !important;
}

/* ── #518: TV-Top-Bar schmaler — mehr Platz fuer den Main-Frame ──────────────────
   Die obere Header-Zeile (Suchleiste + Glocke/Avatar) war deutlich hoeher als noetig
   (~89px). Padding + Suchleisten-Hoehe reduzieren; die untere Tab-/Hoster-Zeile bleibt. */
body.app-tv #header {
  padding-top: 8px !important;
  padding-bottom: 8px !important;
  margin-bottom: 10px !important;
}
body.app-tv #search-bar { height: 42px !important; }

/* ── #519: „Alle/Live/Videos"-Content-Pillen auf Hoster-Pillen-Groesse angleichen ─
   Startseite/Trends: die Content-Typ-Pillen waren 36px/14px, die Hoster-Pillen 42px/15px
   → uneinheitlich. Auf dieselbe Hoehe + Schriftgroesse wie die Hoster-Pillen bringen. */
body.app-tv #content #filter-tabs .filter-tab {
  height: 42px !important;
  font-size: 15px !important;
}
body.app-tv #content #filter-tabs { padding: 3px !important; }
