/* LK21 Live Hub — Android TV first
 * 10ft UI: base 22px, focus rings, big cards, scroll-snap rows.
 * D-pad nav via tabindex order. Mouse hover keeps for desktop debug. */

/* Immersive mode — hide site chrome (top header, bottom nav, breadcrumb,
 * banner ads bar) on /nonton-bareng for full Android-TV feel. Reveal on
 * D-pad UP or mouse-move near top via .lh-chrome-visible class. */
body.page-livehub-tv > .header,
body.page-livehub-tv > .breadcrumb,
body.page-livehub-tv .bottom-nav,
body.page-livehub-tv .header-banner-strip {
    display: none !important;
}
body.page-livehub-tv.lh-chrome-visible > .header,
body.page-livehub-tv.lh-chrome-visible > .breadcrumb,
body.page-livehub-tv.lh-chrome-visible .bottom-nav {
    display: revert !important;
    animation: lh-chrome-slide-in .25s ease both;
    position: fixed;
    left: 0; right: 0;
    z-index: 9000;
}
body.page-livehub-tv.lh-chrome-visible > .header,
body.page-livehub-tv.lh-chrome-visible > .breadcrumb { top: 0; }
body.page-livehub-tv.lh-chrome-visible .bottom-nav { bottom: 0; top: auto; }
@keyframes lh-chrome-slide-in {
    from { transform: translateY(-100%); opacity: 0; }
    to   { transform: translateY(0); opacity: 1; }
}

/* Slim TV-app top nav. Fixed top-center, semi-transparent, always visible.
 * Six items: Home / Nobar / Premium Sports / Premium TV / Sports / TV.
 * Big focus rings for D-pad. Falls back to wrap on small screens. */
.lh-tv-topnav {
    position: fixed;
    top: 28px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 8500;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 12px;
    background: rgba(10, 10, 15, 0.6);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 999px;
    backdrop-filter: blur(12px);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
    max-width: calc(100% - 24px);
    overflow-x: auto;
    scrollbar-width: none;
}
.lh-tv-topnav::-webkit-scrollbar { display: none; }
.lh-tv-navitem {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 8px 16px;
    font-size: 14px;
    font-weight: 600;
    color: #cbd5e1;
    background: transparent;
    border: 2px solid transparent;
    border-radius: 999px;
    cursor: pointer;
    text-decoration: none;
    line-height: 1;
    white-space: nowrap;
    transition: background .2s, border-color .2s, color .2s;
    flex: 0 0 auto;
}
.lh-tv-navitem:hover,
.lh-tv-navitem:focus,
.lh-tv-navitem:focus-visible {
    background: rgba(56, 189, 248, 0.18);
    border-color: var(--lh-focus);
    color: #fff;
    outline: none;
}
/* Aggregate search dropdown — fixed-position popover spanning all
 * /nonton-bareng/* pages. Matched events + channels with section label. */
.lh-search-dropdown {
    position: fixed;
    z-index: 9000;
    max-height: 70vh;
    background: rgba(15, 15, 22, 0.97);
    border: 1px solid rgba(56, 189, 248, 0.3);
    border-radius: 14px;
    backdrop-filter: blur(12px);
    box-shadow: 0 18px 40px rgba(0, 0, 0, 0.5);
    overflow-y: auto;
    display: none;
    padding: 6px;
}
.lh-search-dropdown.is-open { display: block; }
.lh-search-dropdown::-webkit-scrollbar { width: 8px; }
.lh-search-dropdown::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.15); border-radius: 4px; }
.lh-search-empty { padding: 20px; text-align: center; color: var(--lh-fg-dim); font-size: 14px; }
.lh-search-item {
    display: flex; align-items: center; gap: 12px;
    width: 100%; padding: 10px 12px;
    background: transparent;
    border: 2px solid transparent; border-radius: 10px;
    color: #fff; cursor: pointer; text-align: left;
    transition: background .12s, border-color .12s;
}
.lh-search-item:hover, .lh-search-item:focus, .lh-search-item:focus-visible {
    background: rgba(56, 189, 248, 0.18);
    border-color: var(--lh-focus);
    outline: none;
}
.lh-search-icon {
    flex: 0 0 44px; width: 44px; height: 44px;
    background: rgba(0,0,0,0.4); border-radius: 8px;
    display: flex; align-items: center; justify-content: center;
    overflow: hidden; font-size: 22px;
}
.lh-search-icon img { max-width: 100%; max-height: 100%; object-fit: contain; }
.lh-search-text { flex: 1 1 auto; min-width: 0; }
.lh-search-title { font-size: 15px; font-weight: 600; color: #fff; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lh-search-sub { font-size: 12px; color: var(--lh-fg-dim); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; margin-top: 2px; }

.lh-tv-search {
    flex: 0 0 auto;
    min-width: 180px;
    max-width: 240px;
    padding: 8px 14px;
    background: rgba(255, 255, 255, 0.06);
    border: 2px solid transparent;
    border-radius: 999px;
    color: #fff;
    /* iOS Safari auto-zooms inputs below 16px and doesn't zoom back out
     * cleanly — keep at 16px to disable that behavior. */
    font-size: 16px;
    line-height: 1;
    outline: none;
    transition: background .2s, border-color .2s, max-width .2s;
}
.lh-tv-search::placeholder { color: rgba(203, 213, 225, 0.7); }
.lh-tv-search:hover,
.lh-tv-search:focus,
.lh-tv-search:focus-visible {
    background: rgba(56, 189, 248, 0.18);
    border-color: var(--lh-focus);
    max-width: 320px;
}
@media (max-width: 768px) {
    /* min 16px keeps iOS from auto-zooming on focus. Don't shrink below. */
    .lh-tv-search { min-width: 110px; max-width: 150px; padding: 7px 12px; font-size: 16px; }
    .lh-tv-search:focus { max-width: 220px; }
}

/* Old top-nav `.lh-tv-online` pill removed 2026-05-05 — count now lives
 * inside the player overlay (.lh-online-pill below) for both NoBar
 * iframe + Live Hub fullscreen stage. Animation kept for the in-player
 * pulsing dot. */
@keyframes lh-online-pulse {
    0%   { box-shadow: 0 0 0 0 rgba(34, 197, 94, 0.7); }
    70%  { box-shadow: 0 0 0 8px rgba(34, 197, 94, 0); }
    100% { box-shadow: 0 0 0 0 rgba(34, 197, 94, 0); }
}

/* In-player live viewer count pill — overlays the video top-right.
 * Shared by NoBar iframe + Live Hub fullscreen stage. Auto-fades to 30%
 * when video is playing so it doesn't obstruct the picture; full opacity
 * on hover. Pulsing green dot signals "live data".
 * z-index above shaka controls strip but below close/fullscreen buttons
 * (z:30) so the action buttons stay clickable. */
.lh-online-pill {
    /* Inside .lh-fs-bar (Live Hub overlay): sits inline matching button shape +
     * height (44px). Outside (NoBar iframe): falls back to absolute centered. */
    z-index: 25;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    height: 44px;
    padding: 0 14px;
    border-radius: 22px;
    background: rgba(0, 0, 0, 0.7);
    border: 1px solid rgba(34, 197, 94, 0.6);
    color: #fff;
    font-size: 14px;
    font-weight: 700;
    line-height: 1;
    white-space: nowrap;
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    pointer-events: auto;
    opacity: 0.95;
    transition: opacity .25s ease;
}
/* Eye icon dropped in fullscreen overlay — green dot already signals "live".
 * NoBar iframe still uses ::before via .nb-iframe-stage override below. */
#lh-fs-stage .lh-online-pill::before { content: none; }
.nb-iframe-stage .lh-online-pill::before,
.nb-online-pill::before {
    content: '👁';
    font-size: 16px;
    line-height: 1;
}
.lh-online-pill-dot {
    width: 9px; height: 9px; border-radius: 50%;
    background: #22c55e;
    box-shadow: 0 0 0 0 rgba(34, 197, 94, 0.7);
    animation: lh-online-pulse 1.6s ease-out infinite;
}
.lh-online-num { font-variant-numeric: tabular-nums; font-size: 14px; font-weight: 700; }
.lh-online-label { display: none; }

/* NoBar iframe (outside of .lh-fs-bar) — keep legacy absolute positioning + tighter sizing. */
.nb-online-pill, .nb-iframe-stage .lh-online-pill {
    position: absolute;
    top: 14px;
    left: 50%;
    transform: translateX(-50%);
    height: auto;
    padding: 5px 11px;
    border-radius: 999px;
}
@media (max-width: 720px) {
    .lh-online-pill { height: 40px; padding: 0 11px; gap: 6px; }
    .lh-online-pill::before { font-size: 16px; }
    .lh-online-num { font-size: 13px; }
    .lh-online-label { display: none; }
    .nb-iframe-stage .lh-online-pill { top: 10px; height: auto; padding: 4px 9px; }
}

/* Channel-count pill on each desktop nav item — tiny, neutral, hides
 * empty until the count fetch resolves. Matches the nav-item color so it
 * doesn't fight for attention. Mobile layout already drops the labels to
 * the bottom-nav; counts hidden there to save horizontal space. */
/* Compact superscript-style count badge — sits raised next to the label
 * so it reads like a footnote/notification pill rather than competing as
 * a primary tab element. */
.lh-tv-count {
    display: inline-block;
    margin-left: 4px;
    padding: 0 5px;
    border-radius: 999px;
    background: rgba(56, 189, 248, 0.18);
    color: #38bdf8;
    font-size: 0.55rem;
    font-weight: 700;
    line-height: 1.35;
    vertical-align: super;
    letter-spacing: 0.2px;
    border: 1px solid rgba(56, 189, 248, 0.32);
    transform: translateY(-1px);
    transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.lh-tv-count:empty { display: none; }
.lh-tv-navitem:hover .lh-tv-count,
.lh-tv-navitem:focus .lh-tv-count {
    background: rgba(56, 189, 248, 0.32);
    color: #fff;
    border-color: rgba(56, 189, 248, 0.55);
}
.lh-tv-navitem.is-active .lh-tv-count {
    background: rgba(0, 0, 0, 0.32);
    color: #fff;
    border-color: rgba(255, 255, 255, 0.32);
}
/* Premium nav items use gold accent for the count */
.lh-tv-navitem-premium .lh-tv-count {
    background: rgba(251, 191, 36, 0.18);
    color: #fbbf24;
    border-color: rgba(251, 191, 36, 0.32);
}
.lh-tv-navitem-premium:hover .lh-tv-count,
.lh-tv-navitem-premium:focus .lh-tv-count {
    background: rgba(251, 191, 36, 0.32);
    color: #fff;
    border-color: rgba(251, 191, 36, 0.55);
}
/* Live nav: red accent */
.lh-tv-navitem-live .lh-tv-count {
    background: rgba(239, 68, 68, 0.2);
    color: #ef4444;
    border-color: rgba(239, 68, 68, 0.4);
}
.lh-tv-navitem-live:hover .lh-tv-count,
.lh-tv-navitem-live:focus .lh-tv-count {
    background: rgba(239, 68, 68, 0.36);
    color: #fff;
    border-color: rgba(239, 68, 68, 0.6);
}
@media (max-width: 768px) { .lh-tv-count { display: none !important; } }

.lh-tv-navitem-premium { color: #fbbf24; }
.lh-tv-navitem-premium:hover,
.lh-tv-navitem-premium:focus,
.lh-tv-navitem-premium:focus-visible {
    background: rgba(245, 158, 11, 0.18);
    border-color: var(--lh-premium);
    color: #fff;
}

/* Live Now — red (matches the 🔴 emoji + LIVE pulse). Distinct from the
 * gold premium pills so the three premium-tier items (Live / Premium Sports /
 * Premium TV) read as three separate categories at a glance. */
.lh-tv-navitem-live { color: #fca5a5; }
.lh-tv-navitem-live.is-active {
    background: linear-gradient(135deg, #ef4444, #b91c1c) !important;
    border-color: #fecaca !important;
    color: #fff !important;
    box-shadow: 0 0 0 2px rgba(254, 202, 202, 0.35), 0 6px 14px rgba(185, 28, 28, 0.45);
}
.lh-tv-navitem-live:hover,
.lh-tv-navitem-live:focus,
.lh-tv-navitem-live:focus-visible {
    background: rgba(239, 68, 68, 0.22);
    border-color: #fca5a5;
    color: #fff;
}

/* Premium Sports — gold/orange (trophy 🏆 vibe). */
.lh-tv-navitem-psports { color: #fbbf24; }
.lh-tv-navitem-psports.is-active {
    background: linear-gradient(135deg, #f59e0b, #d97706) !important;
    border-color: #fbbf24 !important;
    color: #1a1408 !important;
    box-shadow: 0 0 0 2px rgba(251, 191, 36, 0.35), 0 6px 14px rgba(217, 119, 6, 0.45);
}
.lh-tv-navitem-psports:hover,
.lh-tv-navitem-psports:focus,
.lh-tv-navitem-psports:focus-visible {
    background: rgba(245, 158, 11, 0.22);
    border-color: #fbbf24;
    color: #fff;
}

/* Premium TV — purple/violet (premium-tier 💎 vibe). Distinct from gold so
 * the two pills never visually merge in the top nav. */
.lh-tv-navitem-ptv { color: #c4b5fd; }
.lh-tv-navitem-ptv.is-active {
    background: linear-gradient(135deg, #8b5cf6, #6d28d9) !important;
    border-color: #c4b5fd !important;
    color: #fff !important;
    box-shadow: 0 0 0 2px rgba(196, 181, 253, 0.35), 0 6px 14px rgba(109, 40, 217, 0.45);
}
.lh-tv-navitem-ptv:hover,
.lh-tv-navitem-ptv:focus,
.lh-tv-navitem-ptv:focus-visible {
    background: rgba(139, 92, 246, 0.22);
    border-color: #c4b5fd;
    color: #fff;
}

/* Mobile bottom-nav — same color split so the three premium tabs are
 * distinguishable on phones too. */
.lh-bn-live { color: #fca5a5; }
.lh-bn-live.is-active {
    background: linear-gradient(135deg, #ef4444, #b91c1c);
    color: #fff;
}
.lh-bn-psports { color: #fbbf24; }
.lh-bn-psports.is-active {
    background: linear-gradient(135deg, #f59e0b, #d97706);
    color: #1a1408;
}
.lh-bn-ptv { color: #c4b5fd; }
.lh-bn-ptv.is-active {
    background: linear-gradient(135deg, #8b5cf6, #6d28d9);
    color: #fff;
}

@media (max-width: 768px) {
    .lh-tv-topnav { gap: 4px; padding: 6px 8px; }
    .lh-tv-navitem { padding: 6px 12px; font-size: 12px; }
    /* Mobile: top nav shows only Home, Search (input), Favorit + online
     * pill. The category items move to the bottom-nav bar. */
    .lh-nav-mobile-hide { display: none !important; }
    /* .lh-tv-online removed — pill now in-player. See .lh-online-pill. */
}

/* Mobile bottom nav — fixed bottom, scroll-snap, mirrors top-nav modes.
 * Hidden on desktop (≥769px) since the top-nav already shows them. */
.lh-tv-bottomnav {
    display: none;
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 8400;
    padding: 10px 6px calc(env(safe-area-inset-bottom, 0px) + 10px);
    background: rgba(8, 8, 14, 0.94);
    border-top: 1px solid rgba(255, 255, 255, 0.10);
    backdrop-filter: blur(14px);
    overflow-x: auto;
    scrollbar-width: none;
    gap: 4px;
}
.lh-tv-bottomnav::-webkit-scrollbar { display: none; }
.lh-bn-item {
    flex: 1 1 0;
    min-width: 0;
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    gap: 5px;
    padding: 10px 6px;
    color: var(--lh-fg-dim);
    text-decoration: none;
    font-size: 26px;
    line-height: 1;
    border-radius: 10px;
    white-space: nowrap;
    transition: color .15s, background .15s, transform .12s;
}
.lh-bn-item:active { transform: scale(0.94); }
.lh-bn-item span {
    font-size: 13px;
    font-weight: 700;
    line-height: 1;
    color: inherit;
    letter-spacing: 0.2px;
}
.lh-bn-item.is-active {
    color: var(--lh-focus);
    background: rgba(56, 189, 248, 0.16);
}
.lh-bn-item.lh-bn-premium.is-active {
    color: var(--lh-premium);
    background: rgba(245, 158, 11, 0.18);
}
@media (max-width: 768px) {
    .lh-tv-bottomnav { display: flex; }
    /* Push page content above the bottom nav so last cards aren't covered. */
    html.lh-tv .nb-page { padding-bottom: 110px !important; }
}

/* TV mode — wide Jadwal Tayang cards, backdrop background + poster left.
 * Inspired by Netflix horizontal-tile layout. Each card ~720x300. */
html.lh-tv .nb-bottom-schedule .nb-section-title {
    font-size: 28px;
    font-weight: 700;
    margin: 18px 64px 14px;
    padding: 0;
    color: #f5f5f7;
}
html.lh-tv .nb-schedule-list {
    display: flex !important;
    flex-direction: row !important;
    gap: 22px;
    overflow-x: auto !important;
    overflow-y: visible !important;
    scroll-snap-type: x mandatory;
    scroll-behavior: smooth;
    max-height: none !important;
    padding: 4px 64px 28px !important;
    scrollbar-width: none;
}
html.lh-tv .nb-schedule-list::-webkit-scrollbar { display: none; }

/* Default state: small Netflix-style poster tile (200x300). On hover the
 * card expands to wide 720x300 with backdrop + meta + trailer button. */
html.lh-tv .nb-sched-row {
    flex: 0 0 200px;
    width: 200px;
    height: 300px;
    scroll-snap-align: start;
    background: #0d0d12;
    border-radius: 14px;
    border: 2px solid transparent;
    padding: 0 !important;
    overflow: hidden;
    transition: flex-basis .25s ease, width .25s ease, border-color .2s, box-shadow .2s;
    cursor: pointer;
    outline: none;
    position: relative;
    display: block !important;
    grid-template-columns: none !important;
    align-items: stretch !important;
}
html.lh-tv .nb-sched-row:focus,
html.lh-tv .nb-sched-row:focus-visible,
html.lh-tv .nb-sched-row:hover,
html.lh-tv .nb-sched-row.is-now {
    flex: 0 0 720px;
    width: 720px;
    border-color: var(--lh-focus);
    box-shadow: 0 16px 50px rgba(56, 189, 248, 0.45);
    z-index: 2;
}
/* Now-playing row gets a red accent border instead of the focus blue. */
html.lh-tv .nb-sched-row.is-now { border-color: #e94560; box-shadow: 0 16px 50px rgba(233, 69, 96, 0.45); }
/* Past rows (already started; either currently airing covered by .is-now,
 * or finished) — hide entirely. NoBar JS toggles .is-past based on
 * start_at < now and end_at < now logic. */
html.lh-tv .nb-sched-row.is-past { display: none !important; }
html.lh-tv .nb-sched-row::after {
    /* Soft left-side darkening so text overlays the backdrop cleanly. */
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(90deg, rgba(10,10,18,0.96) 0%, rgba(10,10,18,0.78) 35%, rgba(10,10,18,0.20) 70%, rgba(10,10,18,0.0) 100%);
    pointer-events: none;
    z-index: 1;
}
/* Backdrop hidden in compact mode, shown on hover. */
html.lh-tv .nb-sched-row .nb-sched-bg {
    position: absolute;
    inset: 0;
    background-position: center right;
    background-size: cover;
    background-repeat: no-repeat;
    z-index: 0;
    opacity: 0;
    transition: opacity .25s ease;
}
html.lh-tv .nb-sched-row:hover .nb-sched-bg,
html.lh-tv .nb-sched-row:focus .nb-sched-bg,
html.lh-tv .nb-sched-row:focus-visible .nb-sched-bg,
html.lh-tv .nb-sched-row.is-now .nb-sched-bg { opacity: 1; }

html.lh-tv .nb-sched-row .nb-sched-poster { display: none; }

/* Poster: in compact mode fills the whole card. On hover, shrinks to a
 * 160x240 inset on the left so the wide layout has room for meta. */
html.lh-tv .nb-sched-row .nb-sched-poster-inset {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: 14px;
    z-index: 2;
    background: #0a0a0f;
    transition: inset .25s ease, width .25s ease, height .25s ease,
                border-radius .25s ease, box-shadow .25s ease;
}
html.lh-tv .nb-sched-row:hover .nb-sched-poster-inset,
html.lh-tv .nb-sched-row:focus .nb-sched-poster-inset,
html.lh-tv .nb-sched-row:focus-visible .nb-sched-poster-inset,
html.lh-tv .nb-sched-row.is-now .nb-sched-poster-inset {
    inset: 30px auto auto 30px;
    width: 160px;
    height: 240px;
    border-radius: 12px;
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.6);
}

/* Time badge floats top-right over backdrop. */
html.lh-tv .nb-sched-row .nb-sched-time {
    position: absolute;
    top: 16px;
    right: 18px;
    z-index: 3;
    background: rgba(0, 0, 0, 0.72);
    color: #fff;
    padding: 8px 14px;
    border-radius: 10px;
    font-size: 15px;
    font-weight: 700;
    line-height: 1.2;
    backdrop-filter: blur(8px);
    margin: 0;
    border: 0;
    width: auto;
    min-width: 0;
    text-align: right;
}
html.lh-tv .nb-sched-row .nb-sched-time small {
    display: block;
    font-size: 12px;
    opacity: 0.85;
    font-weight: 500;
    margin-top: 2px;
}

/* Info column hidden in compact mode, fades in on hover. */
html.lh-tv .nb-sched-row .nb-sched-info {
    position: absolute;
    top: 30px;
    left: 220px;
    right: 30px;
    bottom: 20px;
    z-index: 3;
    color: #fff;
    display: flex;
    flex-direction: column;
    gap: 10px;
    overflow: hidden;
    opacity: 0;
    pointer-events: none;
    transition: opacity .2s ease .1s;
}
html.lh-tv .nb-sched-row:hover .nb-sched-info,
html.lh-tv .nb-sched-row:focus .nb-sched-info,
html.lh-tv .nb-sched-row:focus-visible .nb-sched-info,
html.lh-tv .nb-sched-row.is-now .nb-sched-info {
    opacity: 1;
    pointer-events: auto;
}

/* Bottom title gradient on compact poster — Netflix-style. */
html.lh-tv .nb-sched-row::before {
    content: '';
    position: absolute;
    inset: auto 0 0 0;
    height: 60px;
    background: linear-gradient(180deg, transparent, rgba(0,0,0,0.85));
    z-index: 2;
    transition: opacity .2s ease;
    pointer-events: none;
}
html.lh-tv .nb-sched-row:hover::before,
html.lh-tv .nb-sched-row:focus::before,
html.lh-tv .nb-sched-row:focus-visible::before,
html.lh-tv .nb-sched-row.is-now::before { opacity: 0; }
html.lh-tv .nb-sched-row .nb-sched-info h3 {
    font-size: 28px !important;
    font-weight: 800 !important;
    margin: 0 !important;
    line-height: 1.15 !important;
    color: #fff !important;
    display: flex !important;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    overflow: hidden;
}
html.lh-tv .nb-sched-row .nb-sched-info h3 a {
    color: #fff !important;
    text-decoration: none;
    flex: 1 1 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
}
html.lh-tv .nb-sched-row .nb-sched-info h3 > span:not(.nb-sched-status):not(.nb-sched-rating) {
    /* Hide redundant year span — already part of cleanTitle */
    display: none;
}

html.lh-tv .nb-sched-rating-row {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    align-items: center;
    color: #cbd5e1;
    font-size: 15px;
    font-weight: 600;
}
html.lh-tv .nb-sched-rating { color: #fbbf24; }
html.lh-tv .nb-sched-rating-row > span {
    background: rgba(0, 0, 0, 0.45);
    border: 1px solid rgba(255, 255, 255, 0.12);
    padding: 3px 10px;
    border-radius: 999px;
}

html.lh-tv .nb-sched-row .nb-sched-status {
    display: none !important;
}
html.lh-tv .nb-sched-row .nb-sched-trailer {
    align-self: flex-start;
    margin-top: auto;
    font-size: 15px;
    font-weight: 700;
    padding: 10px 22px;
    background: linear-gradient(135deg, #ec4899, #f43f5e);
    color: #fff;
    border: 0;
    border-radius: 999px;
    cursor: pointer;
    transition: transform .15s, box-shadow .15s;
    box-shadow: 0 6px 18px rgba(244, 63, 94, 0.4);
}
html.lh-tv .nb-sched-row .nb-sched-trailer:hover,
html.lh-tv .nb-sched-row .nb-sched-trailer:focus {
    transform: scale(1.05);
    outline: none;
}
html.lh-tv .nb-sched-row .nb-sched-meta {
    /* Old "Durasi N menit" — replaced by the rating row. Hide. */
    display: none;
}
/* Container width override for TV — full bleed, tight padding. */
/* Push content below the fixed top nav (54px tall + 28px top + 24px gap +
 * 12px scale-up headroom for hover-zoomed first-row cards). */
html.lh-tv .nb-page { padding: 118px 0 48px !important; max-width: none !important; }
html.lh-tv .nb-titlebar { margin-left: 64px; margin-right: 64px; }
html.lh-tv .nb-bottom-schedule { padding: 0; }
html.lh-tv .nb-titlebar h1 { font-size: 26px !important; }

/* TV mode is remote-only — strip non-essential clutter that requires
 * scrolling or precise cursor input. Users only need: play, see details,
 * watch trailer, browse schedule. Embeds, SEO, marquee, "Lewat?" CTA,
 * online viewer count, and the page heading paragraph all hidden. */
html.lh-tv .nb-marquee-wrap,
html.lh-tv .nb-embed-block,
html.lh-tv .nb-seo-block,
html.lh-tv .nb-vod-link,
html.lh-tv .nb-online,
html.lh-tv .nb-page > p,
html.lh-tv .nb-trailer-cta { display: none !important; }

/* Make .nb-titlebar a single tight line, no marquee. */
html.lh-tv .nb-titlebar { display: block; padding: 0; margin-bottom: 14px; }

@media (max-width: 900px) {
    html.lh-tv .nb-titlebar,
    html.lh-tv .nb-embed-block,
    html.lh-tv .nb-seo-block { margin-left: 12px; margin-right: 12px; }
    html.lh-tv .nb-bottom-schedule .nb-section-title { margin: 14px 12px 10px; font-size: 22px; }
    html.lh-tv .nb-schedule-list { padding: 4px 12px 24px !important; gap: 14px; }
    html.lh-tv .nb-sched-row { flex: 0 0 86vw; height: 230px; max-width: 540px; }
    html.lh-tv .nb-sched-row .nb-sched-poster-inset { width: 110px; height: 165px; top: 20px; left: 20px; }
    html.lh-tv .nb-sched-row .nb-sched-info { top: 20px; left: 150px; right: 16px; bottom: 12px; gap: 8px; }
    html.lh-tv .nb-sched-row .nb-sched-info h3 { font-size: 20px !important; }
    html.lh-tv .nb-sched-rating-row { font-size: 12px; gap: 6px; }
    html.lh-tv .nb-sched-rating-row > span { padding: 2px 7px; }
    html.lh-tv .nb-sched-row .nb-sched-time { font-size: 12px; padding: 6px 10px; top: 10px; right: 12px; }
    html.lh-tv .nb-sched-row .nb-sched-trailer { font-size: 13px; padding: 7px 16px; }
}


:root {
    --lh-fg: #f5f5f7;
    --lh-fg-dim: #94a3b8;
    --lh-bg: #0a0a0f;
    --lh-bg-card: #161620;
    --lh-bg-card-hover: #1a1a25;
    --lh-focus: #38bdf8;
    --lh-accent: #ec4899;
    --lh-premium: #f59e0b;
    --lh-card-w: 320px;
    --lh-card-h: 200px;
    --lh-card-gap: 18px;
    --lh-section-pad-x: 64px;
}

#livehub {
    background: var(--lh-bg);
    color: var(--lh-fg);
    font-size: 22px;
    line-height: 1.4;
    margin-top: 32px;
    border-top: 1px solid #1f2937;
    padding-top: 24px;
}

.lh-header {
    display: flex;
    align-items: baseline;
    gap: 16px;
    padding: 0 var(--lh-section-pad-x) 24px;
}

.lh-header h1 {
    font-size: 36px;
    font-weight: 800;
    margin: 0;
    background: linear-gradient(135deg, var(--lh-focus), var(--lh-accent));
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    letter-spacing: 0.5px;
}

.lh-header .lh-subtitle {
    color: var(--lh-fg-dim);
    font-size: 18px;
}

/* Tabs strip — D-pad LEFT/RIGHT navigates, ENTER selects */
.lh-tabs {
    display: flex;
    gap: 12px;
    padding: 0 var(--lh-section-pad-x) 8px;
    overflow-x: auto;
    scrollbar-width: none;
    flex-wrap: wrap;
}
.lh-tabs::-webkit-scrollbar { display: none; }
.lh-tab {
    background: rgba(22, 22, 32, 0.7);
    border: 2px solid #1f2937;
    color: var(--lh-fg-dim);
    padding: 12px 22px;
    border-radius: 999px;
    font-size: 18px;
    font-weight: 600;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 10px;
    transition: transform .12s, border-color .12s, background .12s, color .12s;
    line-height: 1;
    white-space: nowrap;
    outline: none;
}
.lh-tab .lh-count {
    background: rgba(56, 189, 248, 0.15);
    color: var(--lh-focus);
    font-size: 13px;
    font-weight: 700;
    padding: 3px 10px;
    border-radius: 999px;
    line-height: 1;
}
.lh-tab.lh-tab-premium .lh-count {
    background: rgba(245, 158, 11, 0.18);
    color: var(--lh-premium);
}
.lh-tab.is-active {
    background: linear-gradient(135deg, var(--lh-focus), var(--lh-accent));
    border-color: transparent;
    color: #0a0a0f;
}
.lh-tab.is-active .lh-count {
    background: rgba(0, 0, 0, 0.22);
    color: #0a0a0f;
}
.lh-tab.lh-tab-premium.is-active {
    background: linear-gradient(135deg, var(--lh-premium), #fb923c);
}
.lh-tab:focus,
.lh-tab:focus-visible {
    transform: scale(1.04);
    border-color: var(--lh-focus);
    box-shadow: 0 0 0 4px rgba(56, 189, 248, 0.25);
}
@media (pointer: fine) {
    .lh-tab:hover { border-color: var(--lh-focus); color: var(--lh-fg); }
}

.lh-section.is-hidden { display: none; }

/* ───── Page modes: top-nav clicks toggle body.lh-mode-<id>. ────────────
 * - lh-mode-nobar  : NoBar player + Schedule visible. Live Hub hidden.
 * - lh-mode-psports: ONLY Premium Sports cards (Netflix category page).
 *                    NoBar hero + schedule + other panes all hidden.
 *                    Card click → fullscreen shaka player overlay.
 * - lh-mode-ptv    : ONLY Premium TV cards.
 * - lh-mode-sports : ONLY Sports cards.
 * - lh-mode-tv     : ONLY TV cards. */
body.lh-mode-nobar #livehub,
body.lh-mode-nobar #livehub .lh-section { display: none !important; }
body.lh-mode-live .nb-hero,
body.lh-mode-psports .nb-hero,
body.lh-mode-ptv .nb-hero,
body.lh-mode-sports .nb-hero,
body.lh-mode-tv .nb-hero,
body.lh-mode-live .nb-bottom,
body.lh-mode-psports .nb-bottom,
body.lh-mode-ptv .nb-bottom,
body.lh-mode-sports .nb-bottom,
body.lh-mode-tv .nb-bottom,
body.lh-mode-live .nb-titlebar,
body.lh-mode-psports .nb-titlebar,
body.lh-mode-ptv .nb-titlebar,
body.lh-mode-sports .nb-titlebar,
body.lh-mode-tv .nb-titlebar,
body.lh-mode-live .nb-cinema-exit,
body.lh-mode-psports .nb-cinema-exit,
body.lh-mode-ptv .nb-cinema-exit,
body.lh-mode-sports .nb-cinema-exit,
body.lh-mode-tv .nb-cinema-exit { display: none !important; }
body.lh-mode-live #livehub .lh-section:not([data-pane-id="live"]),
body.lh-mode-psports #livehub .lh-section:not([data-pane-id="psports"]),
body.lh-mode-ptv #livehub .lh-section:not([data-pane-id="ptv"]),
body.lh-mode-sports #livehub .lh-section:not([data-pane-id="sports"]),
body.lh-mode-tv #livehub .lh-section:not([data-pane-id="tv"]) { display: none !important; }
/* Category pages: bigger card grid since whole viewport free. */
body.lh-mode-live #livehub .lh-row,
body.lh-mode-psports #livehub .lh-row,
body.lh-mode-ptv #livehub .lh-row,
body.lh-mode-sports #livehub .lh-row,
body.lh-mode-tv #livehub .lh-row {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(var(--lh-card-w), 1fr));
    overflow-x: visible;
    overflow-y: auto;
    scroll-snap-type: none;
    /* 24px top breathing room so hover-zoomed first-row cards aren't
     * clipped by the fixed top nav (sits at top:28px, ~54px tall). */
    padding: 24px var(--lh-section-pad-x) 32px;
    gap: 22px;
}

/* Channel grids (non-live-now): tighter card width so 4-5 columns fit on
 * standard desktops (1280-1600px). Live-now keeps the wider 320px min
 * because each card carries two team logos + VS + names + league meta —
 * needs room to breathe. */
body.lh-mode-psports #livehub .lh-row,
body.lh-mode-ptv #livehub .lh-row,
body.lh-mode-sports #livehub .lh-row,
body.lh-mode-tv #livehub .lh-row {
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
}
@media (min-width: 1600px) {
    body.lh-mode-psports #livehub .lh-row,
    body.lh-mode-ptv #livehub .lh-row,
    body.lh-mode-sports #livehub .lh-row,
    body.lh-mode-tv #livehub .lh-row {
        grid-template-columns: repeat(5, 1fr);
    }
}

/* Scroll into view leaves 110px clearance from top so the fixed nav (54px
 * tall + 28px from top + ~28px hover-grow margin) doesn't cover the
 * focused card. Same for D-pad keyboard-driven scroll-into-view. */
html.lh-tv { scroll-padding-top: 110px; }

/* Fullscreen modal for category-mode card clicks. */
#lh-fs-stage {
    position: fixed;
    inset: 0;
    background: #000;
    z-index: 9990;
    display: none;
    flex-direction: column;
}
#lh-fs-stage.is-open { display: flex; }
#lh-fs-stage .lh-fs-video-wrap {
    position: relative;
    flex: 1 1 auto;
    background: #000;
}
#lh-fs-stage video {
    width: 100%;
    height: 100%;
    object-fit: contain;
    background: #000;
}
#lh-fs-stage .lh-fs-bar {
    position: absolute;
    top: 0; left: 0; right: 0;
    padding: 16px 22px;
    display: flex;
    align-items: center;
    gap: 14px;
    background: linear-gradient(180deg, rgba(0,0,0,0.85) 0%, rgba(0,0,0,0.45) 60%, rgba(0,0,0,0) 100%);
    z-index: 20;
    color: #fff;
    pointer-events: none;
    opacity: 1;
    transform: translateY(0);
    transition: opacity .25s ease, transform .25s ease;
}
#lh-fs-stage .lh-fs-bar > * { pointer-events: auto; }
#lh-fs-stage.is-idle .lh-fs-bar {
    opacity: 0;
    transform: translateY(-12px);
    pointer-events: none;
}
#lh-fs-stage.is-idle { cursor: none; }
#lh-fs-stage .lh-fs-title {
    font-size: 22px;
    font-weight: 700;
    line-height: 1.2;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    /* Default (no marquee): grow to fill row. */
    flex: 1 1 auto;
    min-width: 0;
}
/* Pill sits between marquee and actions; nudge a touch tighter on the right. */
#lh-fs-stage .lh-fs-bar > .lh-online-pill { flex: 0 0 auto; margin-right: 4px; }
#lh-fs-stage .lh-fs-actions { flex: 0 0 auto; }

/* Marquee ad — sits between title and pill. Sized to remaining row space.
 * Track loops two copies of the ad HTML so the scroll feels seamless.
 * Empty / no-ad → element is `hidden` and the title/pill close up via flex. */
#lh-fs-stage .lh-fs-marquee {
    flex: 1 1 auto;
    min-width: 0;
    height: 36px;
    overflow: hidden;
    border-radius: 18px;
    background: rgba(255, 255, 255, 0.07);
    border: 1px solid rgba(255, 255, 255, 0.12);
    display: flex;
    align-items: center;
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
}
#lh-fs-stage .lh-fs-marquee[hidden] { display: none; }
#lh-fs-stage .lh-fs-marquee-track {
    display: inline-flex;
    align-items: center;
    gap: 60px;
    padding-left: 0;
    white-space: nowrap;
    color: #fff;
    font-size: 13.5px;
    font-weight: 500;
    line-height: 1;
    will-change: transform;
    animation: lh-marquee-scroll 22s linear infinite;
}
#lh-fs-stage .lh-fs-marquee-track:hover { animation-play-state: paused; }
#lh-fs-stage .lh-fs-marquee-item { display: inline-flex; align-items: center; gap: 8px; padding: 0 10px; }
#lh-fs-stage .lh-fs-marquee-item a { color: var(--lh-focus); text-decoration: none; }
#lh-fs-stage .lh-fs-marquee-item a:hover { text-decoration: underline; }
#lh-fs-stage .lh-fs-marquee-item img { max-height: 24px; vertical-align: middle; }

@keyframes lh-marquee-scroll {
    from { transform: translateX(0); }
    to   { transform: translateX(-50%); }
}

/* When marquee is present, title sizes to its own content (so "HBO" stays
 * "HBO" not "H…"), capped at min(280px, 30vw) for long names. Marquee
 * absorbs the remaining row space via flex: 1 1 200px. */
#lh-fs-stage .lh-fs-bar:has(.lh-fs-marquee:not([hidden])) .lh-fs-title {
    flex: 0 0 auto;
    width: max-content;
    max-width: min(280px, 30vw);
}
#lh-fs-stage .lh-fs-bar:has(.lh-fs-marquee:not([hidden])) .lh-fs-marquee {
    flex: 1 1 200px;
}

@media (max-width: 720px) {
    #lh-fs-stage .lh-fs-marquee { height: 30px; font-size: 12.5px; }
    #lh-fs-stage .lh-fs-bar:has(.lh-fs-marquee:not([hidden])) .lh-fs-title {
        max-width: min(180px, 38vw);
    }
}
@media (max-width: 480px) {
    /* Below ~480px, hide marquee — bar gets crowded with title + pill +
     * 5 buttons. User can still see the ad on full desktop. */
    #lh-fs-stage .lh-fs-marquee { display: none !important; }
}
#lh-fs-stage .lh-fs-actions {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    flex-wrap: nowrap;
    pointer-events: auto;
    z-index: 30;
}
#lh-fs-stage .lh-fs-btn {
    background: rgba(0,0,0,0.7);
    border: 1px solid rgba(255,255,255,0.18);
    color: #fff;
    height: 44px;
    padding: 0 14px;
    border-radius: 22px;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    font: inherit;
    transition: background .15s ease, border-color .15s ease, transform .15s ease;
}
#lh-fs-stage .lh-fs-btn:hover,
#lh-fs-stage .lh-fs-btn:focus {
    background: rgba(56, 189, 248, 0.3);
    border-color: var(--lh-focus);
    outline: none;
    transform: translateY(-1px);
}
#lh-fs-stage .lh-fs-icon {
    font-size: 18px;
    line-height: 1;
    display: inline-block;
}
#lh-fs-stage .lh-fs-btn-label {
    font-size: 13px;
    font-weight: 600;
    line-height: 1;
}
@media (max-width: 720px) {
    /* Compact: hide labels, keep icons. Title clips. */
    #lh-fs-stage .lh-fs-btn { padding: 0 11px; height: 40px; }
    #lh-fs-stage .lh-fs-btn-label { display: none; }
    #lh-fs-stage .lh-fs-icon { font-size: 17px; }
    #lh-fs-stage .lh-fs-actions { gap: 6px; }
}
#lh-fs-stage .lh-fs-close {
    background: rgba(0,0,0,0.7);
    border: 2px solid rgba(248, 113, 113, 0.55);
    color: #fff;
    width: 44px;
    height: 44px;
    border-radius: 50%;
    cursor: pointer;
    font-size: 22px;
    line-height: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    backdrop-filter: blur(8px);
}
#lh-fs-stage .lh-fs-close:hover,
#lh-fs-stage .lh-fs-close:focus {
    background: rgba(248, 113, 113, 0.45);
    border-color: rgba(248, 113, 113, 0.9);
    outline: none;
}
@media (max-width: 720px) {
    #lh-fs-stage .lh-fs-close { width: 40px; height: 40px; font-size: 20px; }
}

/* Top-nav active-state pill. */
.lh-tv-navitem.is-active {
    background: rgba(56, 189, 248, 0.25);
    border-color: var(--lh-focus);
    color: #fff;
}
.lh-tv-navitem-premium.is-active {
    background: rgba(245, 158, 11, 0.28);
    border-color: var(--lh-premium);
    color: #fff;
}

.lh-section {
    padding: 18px var(--lh-section-pad-x) 16px;
}

.lh-section-title {
    font-size: 28px;
    font-weight: 700;
    margin: 0 0 16px;
    display: flex;
    align-items: center;
    gap: 12px;
    color: var(--lh-fg);
}

.lh-section-title .lh-count {
    background: rgba(56, 189, 248, 0.15);
    color: var(--lh-focus);
    font-size: 16px;
    font-weight: 600;
    padding: 4px 12px;
    border-radius: 999px;
    line-height: 1;
}

.lh-section-title.lh-premium-section .lh-count {
    background: rgba(245, 158, 11, 0.18);
    color: var(--lh-premium);
}

/* Horizontal scroll row (Netflix-style) */
.lh-row {
    display: flex;
    gap: var(--lh-card-gap);
    overflow-x: auto;
    overflow-y: visible;
    scroll-snap-type: x mandatory;
    scroll-behavior: smooth;
    padding: 12px 0 32px;
    scrollbar-width: none;
    -ms-overflow-style: none;
}
.lh-row::-webkit-scrollbar { display: none; }

.lh-card {
    flex: 0 0 var(--lh-card-w);
    height: var(--lh-card-h);
    scroll-snap-align: start;
    background: var(--lh-bg-card);
    border-radius: 14px;
    outline: none;
    border: 2px solid transparent;
    cursor: pointer;
    transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    position: relative;
}

/* D-pad focus + mouse hover (desktop) — same visual treatment */
.lh-card:focus,
.lh-card:focus-visible,
.lh-card.is-focused {
    transform: scale(1.06);
    border-color: var(--lh-focus);
    box-shadow: 0 12px 40px rgba(56, 189, 248, 0.45), 0 0 0 4px rgba(56, 189, 248, 0.25);
    z-index: 2;
}

@media (pointer: fine) {
    .lh-card:hover {
        transform: scale(1.04);
        border-color: var(--lh-focus);
        box-shadow: 0 8px 24px rgba(56, 189, 248, 0.30);
    }
}

.lh-card.lh-is-premium {
    background: linear-gradient(160deg, var(--lh-bg-card) 60%, rgba(245, 158, 11, 0.08));
    border-color: rgba(245, 158, 11, 0.20);
}

/* Channel had at least one failed health probe in the current 30-min
 * window. Card stays clickable but gets a desaturated, slightly dimmed
 * look + amber 🟠 badge so the user can pick a sibling instead of
 * walking into the ~60s playback-then-stall path. */
.lh-card.lh-is-degraded {
    filter: saturate(0.55);
    opacity: 0.85;
}
.lh-card.lh-is-degraded .lh-card-thumb {
    box-shadow: inset 0 0 0 1px rgba(245, 158, 11, 0.30);
}
.lh-badge.lh-degraded {
    background: rgba(245, 158, 11, 0.18);
    color: #f59e0b;
    border: 1px solid rgba(245, 158, 11, 0.40);
    border-radius: 6px;
    padding: 0 6px;
    font-size: 14px;
    line-height: 1.6;
}

/* Live status warning — sits between is-loading (neutral) and is-error
 * (red). Used when server says the channel may be flaky but we tried
 * playback anyway. */
.lh-status-badge.is-warning {
    color: #f59e0b;
    background: rgba(245, 158, 11, 0.12);
    border: 1px solid rgba(245, 158, 11, 0.35);
}

.lh-card-thumb {
    flex: 1 1 auto;
    background: radial-gradient(ellipse at center, #1a1a25 0%, #0a0a0f 80%);
    display: flex;
    align-items: center;
    justify-content: center;
    position: relative;
    min-height: 0;
}

.lh-card-thumb img {
    max-width: 60%;
    max-height: 80%;
    object-fit: contain;
}

.lh-card-thumb .lh-emoji-big {
    font-size: 64px;
    line-height: 1;
    filter: drop-shadow(0 4px 12px rgba(0,0,0,0.5));
}

/* LK21-brand placeholder shown when channel has no logo. Mirrors the
 * homepage header logo: red "LK21" wordmark + weather icon + 2-letter
 * country code superscript. */
.lh-card-thumb .lh-brand-logo {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 10px 14px;
    border-radius: 12px;
    background: rgba(0, 0, 0, 0.55);
    border: 1px solid rgba(255, 255, 255, 0.08);
    line-height: 1;
}
.lh-card-thumb .lh-brand-name {
    font-size: 30px;
    font-weight: 900;
    color: #ec4899;
    letter-spacing: -0.5px;
    line-height: 1;
}
.lh-card-thumb .lh-brand-wx { font-size: 22px; line-height: 1; }
.lh-card-thumb .lh-brand-cc {
    font-size: 13px;
    font-weight: 800;
    color: #cbd5e1;
    background: rgba(255, 255, 255, 0.08);
    padding: 3px 7px;
    border-radius: 6px;
    letter-spacing: 0.4px;
    align-self: center;
}

.lh-card-vs {
    display: flex;
    align-items: center;
    justify-content: space-around;
    gap: 8px;
    /* Top padding clears the absolute .lh-card-overlay row (LIVE badge
     * top-left at top:10 + ~26px badge height = needs ~46px clearance).
     * Without this, team logos overlap the LIVE badge / kickoff time. */
    padding: 48px 12px 12px;
    width: 100%;
}

.lh-team {
    flex: 1 1 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    min-width: 0;
}

.lh-team-logo {
    width: 56px;
    height: 56px;
    border-radius: 50%;
    background: #0d0d12;
    border: 2px solid #1f2937;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    flex-shrink: 0;
}

.lh-team-logo img {
    width: 44px;
    height: 44px;
    object-fit: contain;
}

.lh-team-name {
    font-size: 17px;
    font-weight: 600;
    text-align: center;
    line-height: 1.2;
    color: var(--lh-fg);
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
}

.lh-vs-sep {
    font-size: 14px;
    font-weight: 700;
    color: var(--lh-fg-dim);
    letter-spacing: 1px;
    flex-shrink: 0;
    margin-top: 18px;
}

.lh-card-foot {
    background: #0a0a0f;
    border-top: 1px solid #1f2937;
    padding: 10px 14px;
    display: flex;
    flex-direction: column;
    gap: 4px;
    flex-shrink: 0;
}

.lh-card-name {
    font-size: 19px;
    font-weight: 600;
    color: var(--lh-fg);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.lh-card-meta {
    font-size: 14px;
    color: var(--lh-fg-dim);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Status overlay (LIVE / TIME / Premium star) */
.lh-card-overlay {
    position: absolute;
    top: 10px;
    left: 10px;
    right: 10px;
    display: flex;
    justify-content: space-between;
    pointer-events: none;
    z-index: 3;
}

.lh-card-overlay-l, .lh-card-overlay-r {
    display: flex;
    gap: 6px;
}

.lh-badge {
    background: rgba(0, 0, 0, 0.78);
    color: #fff;
    padding: 4px 10px;
    border-radius: 6px;
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.4px;
    backdrop-filter: blur(6px);
    line-height: 1;
}
.lh-badge.lh-live { background: #dc2626; }
.lh-badge.lh-live::before {
    content: '';
    display: inline-block;
    width: 8px;
    height: 8px;
    background: #fff;
    border-radius: 50%;
    margin-right: 6px;
    vertical-align: middle;
    animation: lh-pulse 1.4s infinite;
}
.lh-badge.lh-soon { background: #1d4ed8; }
.lh-badge.lh-time { background: rgba(0, 0, 0, 0.85); }
.lh-badge.lh-premium { background: linear-gradient(135deg, #f59e0b, #d97706); color: #000; }
.lh-badge.lh-drm { background: rgba(168, 85, 247, 0.85); }

/* Heart favorite button — overlay top-right, semi-transparent until
 * hover. Click toggles in lk21_fav_live store. */
.lh-heart-btn {
    background: rgba(0, 0, 0, 0.55);
    color: #fff;
    border: 1px solid rgba(255, 255, 255, 0.15);
    border-radius: 50%;
    width: 24px;
    height: 24px;
    padding: 0;
    cursor: pointer;
    font-size: 12px;
    line-height: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: transform .15s, background .15s, border-color .15s;
    pointer-events: auto;
    backdrop-filter: blur(4px);
}
.lh-heart-btn:hover,
.lh-heart-btn:focus {
    transform: scale(1.15);
    background: rgba(244, 63, 94, 0.4);
    border-color: rgba(244, 63, 94, 0.8);
    outline: none;
}
.lh-heart-btn.is-on {
    background: rgba(244, 63, 94, 0.5);
    border-color: rgba(244, 63, 94, 0.85);
}
.lh-card-overlay { pointer-events: none; }
.lh-card-overlay-l, .lh-card-overlay-r { pointer-events: auto; }

@keyframes lh-pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.4; }
}

.lh-empty {
    text-align: center;
    color: var(--lh-fg-dim);
    padding: 40px;
    font-size: 18px;
}

/* Live-now empty state: full-grid hero card centered in viewport. Lives
 * inside a grid container, so grid-column:1/-1 + place-self:center span
 * every column and re-center horizontally. */
.lh-empty-hero {
    grid-column: 1 / -1;
    place-self: center;
    width: min(560px, calc(100% - 32px));
    margin: 8vh auto 6vh;
    padding: 44px 32px 36px;
    text-align: center;
    background: radial-gradient(circle at 50% 0%, rgba(229,9,20,0.12) 0%, rgba(20,20,28,0.65) 55%, rgba(12,12,18,0.85) 100%);
    border: 1px solid rgba(255,255,255,0.08);
    border-radius: 22px;
    box-shadow: 0 24px 60px -20px rgba(0,0,0,0.6), inset 0 1px 0 rgba(255,255,255,0.04);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
}

.lh-empty-orb {
    position: relative;
    width: 96px;
    height: 96px;
    margin: 0 auto 22px;
    display: grid;
    place-items: center;
}
.lh-empty-orb-icon {
    position: relative;
    z-index: 2;
    font-size: 44px;
    line-height: 1;
    filter: drop-shadow(0 4px 14px rgba(229,9,20,0.45));
}
.lh-empty-pulse {
    position: absolute;
    inset: 0;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(229,9,20,0.55) 0%, rgba(229,9,20,0) 65%);
    animation: lh-empty-ping 2.4s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
.lh-empty-pulse--lag { animation-delay: 1.2s; }

@keyframes lh-empty-ping {
    0%   { transform: scale(0.6); opacity: 0.85; }
    80%  { transform: scale(1.5); opacity: 0; }
    100% { transform: scale(1.5); opacity: 0; }
}

.lh-empty-title {
    margin: 0 0 10px;
    font-size: 1.5rem;
    font-weight: 800;
    letter-spacing: -0.01em;
    color: #fff;
}

.lh-empty-sub {
    margin: 0 auto 26px;
    max-width: 420px;
    color: rgba(255,255,255,0.66);
    font-size: 0.96rem;
    line-height: 1.6;
}

.lh-empty-ctas {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 10px;
    margin-bottom: 22px;
}
.lh-empty-btn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 11px 18px;
    border-radius: 999px;
    background: rgba(255,255,255,0.06);
    border: 1px solid rgba(255,255,255,0.1);
    color: #fff;
    font-size: 0.92rem;
    font-weight: 600;
    text-decoration: none;
    transition: background 0.18s ease, border-color 0.18s ease, transform 0.18s ease;
}
.lh-empty-btn:hover {
    background: rgba(255,255,255,0.1);
    border-color: rgba(255,255,255,0.18);
    transform: translateY(-1px);
}
.lh-empty-btn--primary {
    background: linear-gradient(135deg, #e50914 0%, #b00610 100%);
    border-color: rgba(229,9,20,0.5);
    box-shadow: 0 8px 22px -8px rgba(229,9,20,0.6);
}
.lh-empty-btn--primary:hover {
    background: linear-gradient(135deg, #ff1722 0%, #c40712 100%);
    border-color: rgba(229,9,20,0.7);
}

.lh-empty-tip {
    margin: 0;
    color: rgba(255,255,255,0.42);
    font-size: 0.78rem;
    letter-spacing: 0.02em;
}

@media (max-width: 480px) {
    .lh-empty-hero {
        padding: 36px 22px 28px;
        margin: 6vh auto 4vh;
    }
    .lh-empty-title { font-size: 1.3rem; }
    .lh-empty-sub { font-size: 0.9rem; }
    .lh-empty-btn { padding: 10px 14px; font-size: 0.86rem; }
}

/* Inline live-mode overlays on the existing nb-player-wrap (NoBar stage).
 * The <video id="lh-video"> sits absolute inset:0 above the iframe; toggled
 * via display. The "Back to NoBar" + status badge sit on top of the video. */

#lh-video {
    width: 100%;
    height: 100%;
    background: #000;
    object-fit: contain;
}

/* shaka.ui.Overlay needs the video parent to have a relative position +
 * fill the wrap. It wraps the <video> with .shaka-video-container etc. */
.nb-player-wrap[data-shaka-player-container],
.lh-fs-video-wrap[data-shaka-player-container],
.shaka-video-container {
    position: relative;
    width: 100%;
    height: 100%;
    background: #000;
}
.shaka-controls-container { z-index: 11; }
.shaka-controls-container .shaka-play-button-container .shaka-play-button { color: #fff; }
.shaka-bottom-controls .shaka-controls-button-panel button { color: #fff; }
.shaka-spinner-container { z-index: 12; }

/* Kill the giant center play/pause overlay button — its white circle covers
 * the middle of the video on every hover/pause. Click on the video surface
 * still toggles play via shaka's video-element click handler. */
.shaka-play-button-container .shaka-play-button {
    background: transparent !important;
    border: none !important;
    box-shadow: none !important;
    opacity: 0 !important;
    pointer-events: none !important;
}

.lh-back-btn {
    position: absolute;
    top: 12px;
    left: 12px;
    z-index: 12;
    background: rgba(0, 0, 0, 0.85);
    color: #fff;
    border: 2px solid transparent;
    padding: 10px 18px;
    border-radius: 999px;
    font-size: 15px;
    font-weight: 600;
    cursor: pointer;
    backdrop-filter: blur(6px);
    line-height: 1;
    display: inline-flex;
    align-items: center;
    gap: 6px;
}
.lh-back-btn:focus,
.lh-back-btn:hover {
    border-color: var(--lh-focus);
    background: rgba(56, 189, 248, 0.25);
}

.lh-status-badge {
    position: absolute;
    top: 12px;
    right: 12px;
    z-index: 12;
    background: rgba(0, 0, 0, 0.85);
    color: #cbd5e1;
    padding: 8px 14px;
    border-radius: 8px;
    font-size: 13px;
    font-weight: 700;
    backdrop-filter: blur(6px);
    line-height: 1;
    letter-spacing: 0.4px;
}
.lh-status-badge.is-live { color: #ef4444; }
.lh-status-badge.is-loading { color: #38bdf8; }
.lh-status-badge.is-error { color: #fbbf24; }

/* In live mode, swap the NoBar progress bar for a pulsing live indicator.
 * NoBar progress shows movie elapsed/total which is meaningless for live. */
body.nb-live-mode .nb-meta-progress { display: none; }
body.nb-live-mode .nb-vod-link { display: none; }
body.nb-live-mode #nbDlBtn { display: none !important; }
body.nb-live-mode #nbBtnPopup { display: none !important; }

/* NoBar JS continues to poll /now-playing in the background even in live
 * mode — it might toggle off .hidden on the off-air overlay. Force-hide
 * any NoBar overlay/badge/next-hint while live channel is playing. */
body.nb-live-mode #nbOverlay,
body.nb-live-mode #nbLiveBadge,
body.nb-live-mode #nbNextHint { display: none !important; }

/* lh-video must paint above any NoBar overlay z-index (defensive). */
#lh-video { z-index: 8; }

/* On-pause sibling-channel picker — appears at bottom of player when
 * user pauses, listing other channels in the same mode. Click switches. */
.lh-pause-picker {
    position: absolute;
    left: 0; right: 0; bottom: 0;
    z-index: 13;
    background: linear-gradient(180deg, rgba(0,0,0,0) 0%, rgba(0,0,0,0.85) 30%, rgba(0,0,0,0.95) 100%);
    /* Extra top padding so the hover/focus scale-up doesn't clip card tops. */
    padding: 90px 24px 24px;
    pointer-events: auto;
}
.lh-pp-title {
    font-size: 14px;
    font-weight: 700;
    color: #cbd5e1;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    margin-bottom: 12px;
}
.lh-pp-row {
    display: flex;
    gap: 12px;
    overflow-x: auto;
    overflow-y: visible;
    scrollbar-width: none;
    padding: 8px 0 8px;
}
.lh-pp-row::-webkit-scrollbar { display: none; }
.lh-pp-card {
    flex: 0 0 140px;
    width: 140px;
    height: 90px;
    background: rgba(22, 22, 32, 0.85);
    border: 2px solid rgba(255, 255, 255, 0.08);
    border-radius: 10px;
    cursor: pointer;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 8px;
    transition: transform .15s, border-color .15s, background .15s;
    overflow: hidden;
}
.lh-pp-card:hover,
.lh-pp-card:focus,
.lh-pp-card:focus-visible {
    transform: scale(1.06);
    border-color: var(--lh-focus);
    background: rgba(56, 189, 248, 0.18);
    outline: none;
}
.lh-pp-logo {
    width: 50px;
    height: 30px;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    font-size: 18px;
}
.lh-pp-logo img { max-width: 100%; max-height: 100%; object-fit: contain; }
.lh-pp-name {
    font-size: 11px;
    color: #fff;
    font-weight: 600;
    text-align: center;
    line-height: 1.2;
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
}

/* Branded 3-2-1 countdown splash before live stream loads. */
.lh-countdown-splash {
    position: absolute;
    inset: 0;
    z-index: 14;
    background: radial-gradient(ellipse at center, #0f0f1a 0%, #050507 100%);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 28px;
    transition: opacity .22s ease;
    color: #fff;
}
.lh-countdown-splash.is-done { opacity: 0; pointer-events: none; }
.lh-cd-brand {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    padding: 12px 18px;
    background: rgba(0, 0, 0, 0.55);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 14px;
    line-height: 1;
}
.lh-cd-name {
    font-size: 36px;
    font-weight: 900;
    color: #ec4899;
    letter-spacing: -1px;
    line-height: 1;
}
.lh-cd-wx { font-size: 28px; line-height: 1; }
.lh-cd-cc {
    font-size: 16px;
    font-weight: 800;
    color: #cbd5e1;
    background: rgba(255, 255, 255, 0.08);
    padding: 4px 9px;
    border-radius: 7px;
    letter-spacing: 0.5px;
}
.lh-cd-num {
    font-size: 180px;
    font-weight: 900;
    line-height: 1;
    color: #38bdf8;       /* fallback solid color if gradient-text fails */
    background: linear-gradient(135deg, #38bdf8, #ec4899);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    filter: drop-shadow(0 0 24px rgba(56, 189, 248, 0.55));
    transition: transform .3s ease;
    text-align: center;
    min-width: 200px;
    min-height: 200px;
    display: flex;
    align-items: center;
    justify-content: center;
}
.lh-cd-num.is-pulse { animation: lh-cd-pulse .9s ease-out; }
.lh-cd-stop {
    position: absolute;
    bottom: 24px;
    right: 24px;
    background: rgba(0, 0, 0, 0.65);
    color: #fff;
    border: 2px solid rgba(255, 255, 255, 0.18);
    padding: 9px 18px;
    border-radius: 999px;
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
    line-height: 1;
    backdrop-filter: blur(6px);
    transition: background .15s, border-color .15s, transform .12s;
}
.lh-cd-stop:hover,
.lh-cd-stop:focus {
    background: rgba(244, 63, 94, 0.4);
    border-color: rgba(244, 63, 94, 0.85);
    outline: none;
}
.lh-cd-stop:active { transform: scale(0.95); }
@keyframes lh-cd-pulse {
    0%   { transform: scale(0.55); opacity: 0; }
    35%  { transform: scale(1.15); opacity: 1; }
    100% { transform: scale(1); opacity: 1; }
}

/* Pre-roll + mid-roll ad overlay — covers the player while ad runs. */
.lh-ad-pause-overlay {
    position: absolute;
    inset: 0;
    z-index: 15;
    background: #000;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
}
.lh-ad-pause-overlay .lh-ad-content {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
}
.lh-ad-pause-overlay .lh-ad-content video,
.lh-ad-pause-overlay .lh-ad-content iframe,
.lh-ad-pause-overlay .lh-ad-content img {
    max-width: 100%;
    max-height: 100%;
    display: block;
}
.lh-ad-skip {
    position: absolute;
    bottom: 16px;
    right: 16px;
    background: rgba(0, 0, 0, 0.85);
    color: #fff;
    border: 2px solid var(--lh-focus);
    padding: 10px 18px;
    border-radius: 999px;
    font-size: 15px;
    font-weight: 600;
    cursor: pointer;
    line-height: 1;
    transition: opacity .2s;
    z-index: 16;
}
.lh-ad-skip:disabled {
    opacity: 0.55;
    cursor: not-allowed;
    border-color: #555;
}
.lh-ad-skip:not(:disabled):hover,
.lh-ad-skip:not(:disabled):focus {
    background: var(--lh-focus);
    color: #000;
}

/* Tap-to-unmute floating button (autoplay-policy fallback). */
.lh-unmute-btn {
    position: absolute;
    bottom: 16px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 14;
    background: rgba(0, 0, 0, 0.85);
    color: #fff;
    border: 2px solid var(--lh-focus);
    padding: 12px 22px;
    border-radius: 999px;
    font-size: 16px;
    font-weight: 700;
    cursor: pointer;
    line-height: 1;
    backdrop-filter: blur(6px);
    box-shadow: 0 8px 24px rgba(56, 189, 248, 0.4);
    animation: lh-unmute-pulse 2s ease-in-out infinite;
}
.lh-unmute-btn:hover,
.lh-unmute-btn:focus {
    background: var(--lh-focus);
    color: #000;
    outline: none;
}
@keyframes lh-unmute-pulse {
    0%, 100% { box-shadow: 0 8px 24px rgba(56, 189, 248, 0.4); }
    50%      { box-shadow: 0 8px 32px rgba(56, 189, 248, 0.8); }
}

/* Floating overlay banner — non-blocking, sticks bottom corner. */
.lh-overlay-banner {
    position: absolute;
    bottom: 12px;
    left: 12px;
    z-index: 11;
    max-width: 360px;
    background: rgba(0, 0, 0, 0.75);
    border: 1px solid rgba(56, 189, 248, 0.4);
    border-radius: 10px;
    padding: 6px 30px 6px 8px;
    backdrop-filter: blur(6px);
    color: #fff;
    font-size: 13px;
    line-height: 1.3;
}
.lh-overlay-banner .lh-overlay-content { overflow: hidden; }
.lh-overlay-banner img,
.lh-overlay-banner video {
    max-width: 100%;
    max-height: 80px;
    display: block;
    border-radius: 6px;
}
.lh-overlay-close {
    position: absolute;
    top: 4px;
    right: 4px;
    background: transparent;
    border: 1px solid transparent;
    color: #fff;
    font-size: 16px;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    cursor: pointer;
    line-height: 1;
    padding: 0;
}
.lh-overlay-close:hover,
.lh-overlay-close:focus { border-color: var(--lh-focus); background: rgba(56, 189, 248, 0.18); }

/* Loading state */
.lh-loading {
    color: var(--lh-fg-dim);
    text-align: center;
    padding: 40px;
    font-size: 18px;
}

/* Responsive — fall back to phone layout */
@media (max-width: 768px) {
    :root {
        --lh-card-w: 200px;
        --lh-card-h: 160px;
        --lh-section-pad-x: 16px;
    }
    #livehub { font-size: 18px; }
    .lh-header h1 { font-size: 26px; }
    .lh-section-title { font-size: 22px; }
    .lh-card-name { font-size: 16px; }
    .lh-card-meta { font-size: 13px; }
    .lh-team-logo { width: 40px; height: 40px; }
    .lh-team-logo img { width: 32px; height: 32px; }
    .lh-team-name { font-size: 14px; }
    #lh-modal { padding: 8px; }
    #lh-modal-title { font-size: 18px; }
}

/* Infinite-scroll sentinel — sits below the .lh-row, IntersectionObserver
   triggers next-page fetch when this enters viewport. Visible only while
   loading/queued; hidden when exhausted. */
.lh-infinite {
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 32px 0 56px;
    min-height: 80px;
}
.lh-infinite[hidden] { display: none; }
.lh-spinner {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    border: 3px solid rgba(148, 163, 184, 0.22);
    border-top-color: var(--lh-focus, #38bdf8);
    animation: lh-spin 0.8s linear infinite;
}
@keyframes lh-spin {
    to { transform: rotate(360deg); }
}
.lh-infinite[data-state="error"] .lh-spinner {
    border-top-color: #ef4444;
    animation: none;
}

/* ============================================================
   /nonton-bareng/tv hub-grid (data-ssr-mode="tv-family")
   Three views toggled via [data-view] + hidden attr in JS.
   Tiles are smaller + squarer than channel cards (logo + count
   only) so ~80–150 fit on one screen comfortably. Android-TV
   focus ring stays the same blue as channel cards.
   ============================================================ */

/* Bump specificity to #livehub.lh-tv-family-page — the bare class selector
   loses to `#livehub { padding-top: 24px; margin-top: 32px }` defined
   earlier (ID > class), so the page header stayed under the floating nav
   even with `padding-top: 140px` on `.lh-tv-family-page` alone. */
#livehub.lh-tv-family-page {
    /* The fixed .lh-tv-topnav sits at top:28px and is ~52px tall; with its
       drop-shadow it visually claims ~110px of vertical space. Combined
       with the existing #livehub margin-top:32px, padding-top:120px on
       the page lands the header well below the nav. We also zero out the
       inherited margin-top + border-top so the page starts cleanly. */
    margin-top: 0;
    border-top: 0;
    padding: 120px clamp(16px, 4vw, 64px) 24px;
    max-width: 1920px;
    margin-left: auto;
    margin-right: auto;
}
@media (max-width: 720px) {
    #livehub.lh-tv-family-page { padding-top: 110px; }
}
.lh-tv-header {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 16px 24px;
    padding: 0 0 20px;
    border-bottom: 1px solid rgba(148, 163, 184, 0.12);
    margin-bottom: 24px;
}
.lh-tv-title {
    font-size: clamp(22px, 3vw, 34px);
    font-weight: 800;
    color: #f1f5f9;
    margin: 0;
    letter-spacing: -0.02em;
}
.lh-tv-meta {
    color: #94a3b8;
    font-size: 14px;
}
.lh-tv-search-wrap {
    margin-left: auto;
    position: relative;
    display: flex;
    align-items: center;
    min-width: clamp(220px, 30vw, 360px);
}
.lh-tv-search-input {
    width: 100%;
    padding: 10px 36px 10px 14px;
    border-radius: 10px;
    border: 1px solid rgba(148, 163, 184, 0.18);
    background: rgba(15, 23, 42, 0.6);
    color: #f1f5f9;
    font-size: 15px;
    outline: none;
    transition: border-color .15s, box-shadow .15s;
}
.lh-tv-search-input:focus {
    border-color: var(--lh-focus, #38bdf8);
    box-shadow: 0 0 0 3px rgba(56, 189, 248, 0.18);
}
.lh-tv-search-input::placeholder { color: #64748b; }
.lh-tv-search-clear {
    position: absolute; right: 8px;
    width: 24px; height: 24px;
    border: 0;
    background: rgba(148, 163, 184, 0.18);
    color: #f1f5f9;
    border-radius: 50%;
    font-size: 16px;
    cursor: pointer;
    line-height: 1;
}

.lh-family-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
    gap: 14px;
}
@media (min-width: 1280px) { .lh-family-grid { grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); } }
@media (max-width: 600px)  { .lh-family-grid { grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 10px; } }

/* Explicit [hidden] override: any CSS `display:` rule (display:grid above)
   takes precedence over the UA `[hidden] { display:none }`, so without
   these the JS `el.hidden = true` would set the attribute but the
   element would still render. Each of the three views needs its own
   guard since they all set `display:` explicitly. */
.lh-family-grid[hidden],
.lh-flat-results[hidden],
.lh-family-panel[hidden] { display: none !important; }

.lh-family-tile {
    display: flex;
    flex-direction: column;
    background: rgba(15, 23, 42, 0.4);
    border: 1px solid rgba(148, 163, 184, 0.10);
    border-radius: 14px;
    overflow: hidden;
    cursor: pointer;
    transition: transform .15s, border-color .15s, box-shadow .15s;
}
.lh-family-tile:focus,
.lh-family-tile:focus-visible {
    outline: none;
    border-color: var(--lh-focus, #38bdf8);
    box-shadow: 0 0 0 3px rgba(56, 189, 248, 0.35);
    transform: scale(1.04);
}
@media (hover: hover) {
    .lh-family-tile:hover {
        border-color: rgba(56, 189, 248, 0.35);
        transform: translateY(-2px);
    }
}
.lh-family-thumb {
    aspect-ratio: 1.2 / 1;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(0, 0, 0, 0.35);
    position: relative;
    padding: 12px;
}
.lh-family-thumb img {
    max-width: 80%;
    max-height: 80%;
    object-fit: contain;
}
.lh-family-fallback {
    font-size: clamp(28px, 5vw, 44px);
    font-weight: 800;
    color: #cbd5e1;
    letter-spacing: 0.02em;
}
.lh-family-flag {
    position: absolute;
    top: 8px; right: 8px;
    font-size: 18px;
    line-height: 1;
}
.lh-family-badge {
    position: absolute;
    top: 8px; left: 8px;
    padding: 3px 7px;
    border-radius: 999px;
    font-size: 10px;
    font-weight: 800;
    letter-spacing: 0.04em;
    line-height: 1;
    text-transform: uppercase;
}
.lh-family-badge-proxy {
    background: linear-gradient(135deg, #f59e0b, #ef4444);
    color: #0a0a0f;
    box-shadow: 0 2px 6px rgba(245, 158, 11, 0.4);
}
.lh-family-tile.lh-family-proxy {
    border-color: rgba(245, 158, 11, 0.25);
}
.lh-family-foot {
    padding: 10px 12px 12px;
    text-align: center;
}
.lh-family-name {
    font-size: 14px;
    font-weight: 700;
    color: #f1f5f9;
    line-height: 1.2;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.lh-family-count {
    margin-top: 4px;
    font-size: 12px;
    color: #94a3b8;
}
.lh-family-tile.lh-family-lainnya .lh-family-thumb {
    background: rgba(56, 189, 248, 0.08);
}
.lh-family-tile.lh-family-lainnya .lh-family-fallback {
    color: var(--lh-focus, #38bdf8);
}

/* Family detail panel — sits where the grid was. The grid itself
   is hidden via [hidden] attr while panel is open. */
.lh-family-panel {
    padding: 0;
}
.lh-family-panel[hidden] { display: none; }
.lh-family-panel-head {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 0 0 20px;
    border-bottom: 1px solid rgba(148, 163, 184, 0.12);
    margin-bottom: 24px;
}
.lh-family-back {
    background: rgba(15, 23, 42, 0.6);
    border: 1px solid rgba(148, 163, 184, 0.18);
    color: #f1f5f9;
    padding: 8px 14px;
    border-radius: 10px;
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
}
.lh-family-back:focus,
.lh-family-back:focus-visible {
    outline: none;
    border-color: var(--lh-focus, #38bdf8);
    box-shadow: 0 0 0 3px rgba(56, 189, 248, 0.25);
}
.lh-family-title {
    font-size: clamp(20px, 2.4vw, 28px);
    font-weight: 800;
    color: #f1f5f9;
    margin: 0;
    letter-spacing: -0.01em;
}
.lh-family-subcount {
    color: #94a3b8;
    font-size: 14px;
    margin-left: auto;
}
.lh-family-channels {
    display: grid !important;
    grid-template-columns: repeat(auto-fill, minmax(var(--lh-card-w, 320px), 1fr));
    gap: var(--lh-card-gap, 18px);
}
.lh-family-loading {
    color: #94a3b8;
    text-align: center;
    padding: 40px 0;
}

/* Flat search results — same grid as detail panel. */
.lh-flat-results { padding: 0; }
.lh-flat-results[hidden] { display: none; }
.lh-flat-results .lh-row {
    display: grid !important;
    grid-template-columns: repeat(auto-fill, minmax(var(--lh-card-w, 320px), 1fr));
    gap: var(--lh-card-gap, 18px);
}
.lh-flat-empty {
    color: #94a3b8;
    text-align: center;
    padding: 40px 0;
    font-size: 16px;
}

/* Flash highlight applied by livehub.js when a #family=K&fav=S deep-link
 * resolves to a card — pulses the outline so the user sees which card
 * matched their /koleksi favorite before the auto-play kicks in. */
@keyframes lh-card-flash-pulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(233,69,96,0.0); }
    25%, 75% { box-shadow: 0 0 0 4px rgba(233,69,96,0.55); }
}
.lh-card.lh-card-flash {
    animation: lh-card-flash-pulse 1.4s ease-in-out 1;
    border-radius: 12px;
}
