/* 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 {
  font-size: 16px !important; font-weight: 500 !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;
}

/* ── 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;
}
body.app-tv .video-card .card-creator,
body.app-tv .video-card .card-creator-name { font-size: 14px !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) */
/* #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;
}
/* 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) ──────────────────────── */
body.app-tv #theme-popup-box {
  background: var(--pc-surface) !important; border: 1px solid var(--pc-border) !important; border-radius: 18px !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;
}

/* ════════════════════════════════════════════════════════════════════════════
   §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;
}
/* 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;
  box-shadow: 0 0 0 2px var(--pc-accent), 0 0 20px 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) ─── */
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;
}

/* ── §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. */
body.app-tv #hint-bar > 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); }

/* ── §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); }
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; }
body.app-tv #player-chat .plc-scroll { flex: 1 1 auto; min-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 {
  top: 72px !important;
  left: 40px !important;
  right: auto !important;
  bottom: auto !important;
  width: calc(100% - 40px - var(--tv-right)) !important;
  height: calc(100vh - 72px - 248px) !important;   /* iframe = ersetztes Element: Höhe EXPLIZIT (auto nähme die 150px-Intrinsic); 248 = untere Bänder-Reserve, deckungsgleich mit #player-controls bottom:152+height:64+Lücken */
  border-radius: 12px !important;
  overflow: hidden !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: 152px !important;
  height: 64px !important;
  display: block !important;
  overflow-x: auto !important;
  overflow-y: hidden !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;
}

/* Meta-Band unten (Name → Titel → Zuschauer/Kategorie) — feste Höhe. */
body.app-tv #player-overlay.tv-videopage #player-info {
  position: absolute !important;
  top: auto !important;
  left: 40px !important;
  right: var(--tv-right) !important;
  bottom: 56px !important;
  height: 72px !important;
  overflow: hidden !important;
}

/* 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: 6px;
  font-size: 20px;
  line-height: 1.3;
  color: var(--pc-muted, #9aa0b5);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
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; }

/* ── VOD-Neubudgetierung (:not(.tv-vp-live) überschreibt 3b-1 nur für VOD) ──
   Stapel (720p-Beispiel, Bänder schneiden sich nie):
     topbar [0,64] · player [72,320] · controls [328,376] · meta [388,460] · reco [468,704] */
body.app-tv #player-overlay.tv-videopage:not(.tv-vp-live) #player,
body.app-tv #player-overlay.tv-videopage:not(.tv-vp-live) #yt-player,
body.app-tv #player-overlay.tv-videopage:not(.tv-vp-live) #av-player,
body.app-tv #player-overlay.tv-videopage:not(.tv-vp-live) #dm-player {
  top: 72px !important;
  left: 40px !important;
  right: auto !important;
  bottom: auto !important;
  width: calc(100% - 80px) !important;
  height: calc(100vh - 72px - 400px) !important;  /* 400 = untere Reserve (Controls+Meta+Reco+Lücken) */
}
body.app-tv #player-overlay.tv-videopage:not(.tv-vp-live) #player-controls {
  bottom: 344px !important; height: 48px !important;
}
body.app-tv #player-overlay.tv-videopage:not(.tv-vp-live) #player-info {
  bottom: 260px !important; height: 72px !important;
}

/* ── Reco-Sektion (NUR VOD) ── unteres Band: Titel/Tabs-Kopf + horizontale Rail. */
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; left: 40px; right: 40px; bottom: 16px; height: 236px;
  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; gap: 14px;
  overflow-x: auto; overflow-y: hidden;
}
body.app-tv .tv-reco-tile {
  width: 220px; flex: none; display: flex; flex-direction: column; cursor: pointer;
}
body.app-tv .tv-reco-thumb {
  position: relative; width: 100%; height: 124px; 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;
  box-shadow: 0 0 0 3px var(--pc-accent), 0 0 22px var(--pc-glow) !important;
  border-color: var(--pc-accent) !important;
  border-radius: 10px;
}
