<?php

declare(strict_types=1);

 
 
 

 
$_cssVer = @filemtime(ThemeManager::themePath(ThemeManager::active()) . '/assets/css/style.css') ?: time();
$_jsVer  = @filemtime(ThemeManager::themePath(ThemeManager::active()) . '/assets/js/app.js') ?: time();
ThemeRenderer::enqueueCSS(ThemeManager::assetUrl('css/style.css') . '?v=' . $_cssVer, 1);
 
$_premiumVer = @filemtime(ThemeManager::themePath(ThemeManager::active()) . '/assets/css/premium.css') ?: time();
ThemeRenderer::enqueueCSS(ThemeManager::assetUrl('css/premium.css') . '?v=' . $_premiumVer, 5);
ThemeRenderer::enqueueJS(ThemeManager::assetUrl('js/app.js') . '?v=' . $_jsVer, 1);

 
require_once __DIR__ . '/admin/appearance-controller.php';
require_once __DIR__ . '/admin/seo-controller.php';
require_once __DIR__ . '/admin/branding.php';
require_once __DIR__ . '/admin/footer.php';
require_once __DIR__ . '/admin/cards.php';
require_once __DIR__ . '/admin/homepage.php';
require_once __DIR__ . '/admin/translation-modal.php';

 
Translator::registerKeys('Albums', [
    'page_title_albums' => 'Albums',
    'albums'            => 'Albums',
    'no_albums'         => 'No albums found.',
    'report_gallery'      => 'Report gallery',
    'report_gallery_desc' => 'Help us keep the site safe — tell us what\'s wrong with this gallery.',
    'sort_most_images'    => 'Most images',
    'album_display'    => 'Display',
    'album_view_mode'  => 'View',
    'album_grid'       => 'Grid',
    'album_masonry'    => 'Masonry',
    'album_navigation' => 'Navigation',
    'album_pages'      => 'Pages',
    'album_infinite'   => 'Infinite',
    'album_filters'    => 'Filters',
    'album_all'        => 'All',
    'like'             => 'Like',
    'dislike'          => 'Dislike',
    'search_albums'     => 'Search albums...',
    'related_albums'    => 'Related Albums',
    'no_images_album'   => 'No images in this album yet.',
    'images'            => 'images',
    'copy_link'         => 'Copy link',
    'favorite'          => 'Favorite',
    'previous'          => 'Previous',
    'next'              => 'Next',
    'sort_newest'       => 'Newest',
    'sort_most_viewed'  => 'Most viewed',
    'sort_most_images'  => 'Most images',
    'videos'                     => 'Videos',
    'discover_albums'            => 'Discover albums',
    'no_favorite_albums'         => 'No favorite albums yet',
    'no_favorite_albums_desc'    => 'Galleries you favorite will appear here.',
    'no_liked_albums'            => 'No liked albums yet',
    'no_liked_albums_desc'       => 'Galleries you like will appear here.',
    'albums_in_favorites'        => ':count gallery in your favorites',
    'albums_in_favorites_plural' => ':count galleries in your favorites',
    'liked_albums_count'         => ':count liked gallery',
    'liked_albums_count_plural'  => ':count liked galleries',
]);



function simplyProfileTypePills(string $tab, string $active, int $videoCount, int $albumCount): string
{
    $base = url('/profile') . '?tab=' . rawurlencode($tab) . '&type=';
    $vCls = $active === 'album' ? '' : ' active';
    $aCls = $active === 'album' ? ' active' : '';
    $h  = '<div class="profile-subnav">';
    $h .= '<a href="' . htmlspecialchars($base . 'video') . '" class="profile-subnav__pill' . $vCls . '"><i class="fa-solid fa-film"></i> ' . htmlspecialchars(__('videos')) . ' <span class="profile-subnav__count">' . Format::number($videoCount) . '</span></a>';
    $h .= '<a href="' . htmlspecialchars($base . 'album') . '" class="profile-subnav__pill' . $aCls . '"><i class="fa-solid fa-images"></i> ' . htmlspecialchars(__('albums')) . ' <span class="profile-subnav__count">' . Format::number($albumCount) . '</span></a>';
    $h .= '</div>';
    return $h;
}
Translator::registerKeys('Simply Theme', [
    'simply_section_trending'    => 'TRENDING',
    'simply_section_latest'      => 'LATEST VIDEOS',
    'simply_section_most_viewed' => 'MOST VIEWED',
    'simply_section_top_rated'   => 'TOP RATED',
    'simply_section_watch_again' => 'WATCH IT AGAIN',
    'simply_section_most_favorited' => 'MOST FAVORITED',
    'simply_mega_top_trending'      => 'Top Trending',
    'simply_mega_most_popular'      => 'Most Popular',
    'simply_mega_trending_popular'  => 'Top Trending & Most Popular',
    'simply_mega_see_more'          => 'See more',
    'simply_mega_see_more_aria'     => 'See more categories',
    'simply_menu'                   => 'Menu',
    'simply_account_menu'           => 'Account menu',
    'simply_close'                  => 'Close',
    'simply_toggle_dark_mode'       => 'Toggle dark mode',
    'simply_powered_by'             => 'Powered by',
    'simply_copy'                   => 'Copy',
    'simply_remove'                 => 'Remove',
    'simply_no_thumbnail'           => 'No thumbnail',
    'simply_topbar_announcement' => '',
    'simply_more'                => 'More',
    'simply_more_aria'           => 'More watch history',
    'vtype_straight'             => 'Straight',
    'vtype_gay'                  => 'Gay',
    'vtype_hentai'               => 'Hentai',
]);

 
function simplyVideoCard(array $video): string
{
    global $_cardShowDuration, $_cardShowTitle, $_cardMetaLeft, $_cardMetaRight,
           $_cardBorderRadius, $_cardTitleLines, $_videosPerRow;

     
     
     
     
    static $cardSeq = 0;
    $_isDetailPage = (bool) preg_match('#(^|/)(video|embed)/#', $_SERVER['REQUEST_URI'] ?? '');
    $eagerCount    = max(1, (int) ($_videosPerRow ?? 5));
    $imgEager      = (!$_isDetailPage && $cardSeq < $eagerCount);
    $imgPriority   = (!$_isDetailPage && $cardSeq === 0);
    $cardSeq++;

     
    HookSystem::doAction('video.card.before', $video);

     
    $card = HookSystem::applyFilter('video.card.html', '', $video);
    if ($card !== '') {
        return $card;
    }

     
    $thumbResolved = VideoAsset::thumbUrl($video, true);
    if ($thumbResolved !== '') {
        $thumb = htmlspecialchars($thumbResolved);
    } else {
         
        $thumb = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 320 180'%3E%3Crect fill='%230d1220' width='320' height='180'/%3E%3Cg transform='translate(160 90)' fill='none' stroke='%23475569' stroke-width='2'%3E%3Crect x='-13' y='-9' width='26' height='18' rx='3'/%3E%3Cpath d='M-4 -5 L7 0 L-4 5 Z' fill='%23475569' stroke='none'/%3E%3C/g%3E%3C/svg%3E";
    }

     
     
     
    $preview = '';
    $previewResolved = VideoAsset::previewUrl($video);
    if ($previewResolved !== '') {
        $preview = htmlspecialchars($previewResolved);
    }
    $timelineSprite = '';
    $timelineCount  = 0;

    $metaValues = [
        'views' => __('views_count', [':count' => Format::number((int)($video['views'] ?? 0))]),
        'likes' => __('likes_count', [':count' => Format::number((int)($video['likes'] ?? 0))]),
        'time'  => Format::timeAgo($video['published_at'] ?? $video['created_at'] ?? ''),
        'none'  => '',
    ];

    $timelineCount = $timelineSprite !== '' ? (int)Setting::get('transcode_timeline_count', '10') : 0;

    $data = [
        'videoId'      => (int)($video['id'] ?? 0),
        'thumb'        => $thumb,
        'imgEager'     => $imgEager,
        'imgPriority'  => $imgPriority,
        'preview'      => $preview,
        'timelineSprite' => $timelineSprite,
        'timelineCount'  => $timelineCount,
        'title'        => htmlspecialchars(mb_ucfirst($video['title'])),
        'slug'         => htmlspecialchars($video['slug']),
        'duration'     => Format::duration((int)($video['duration'] ?? 0)),
        'showDuration' => $_cardShowDuration ?? true,
        'showTitle'    => $_cardShowTitle ?? true,
        'titleClass'   => (($_cardTitleLines ?? 1) >= 2)
            ? 'video-card__title video-card__title--clamp2'
            : 'video-card__title',
        'left'         => $metaValues[$_cardMetaLeft ?? 'views'] ?? '',
        'right'        => $metaValues[$_cardMetaRight ?? 'time'] ?? '',
    ];

     
    $path = ThemeManager::templatePath('partials/video-card');
    if ($path === '') {
        return '';
    }
    extract($data, EXTR_SKIP);
    ob_start();
    require $path;
    return ob_get_clean();
}

 
function simplySortTabs(string $currentSort, string $baseUrl = ''): string
{
    $tabs = [
        'newest'    => __('newest'),
        'popular'   => __('most_viewed'),
        'top_rated' => __('top_rated'),
    ];
    $tabs = HookSystem::applyFilter('front.sort_tabs', $tabs);
    $html = '<div class="sort-tabs">';
    foreach ($tabs as $key => $label) {
        $active = ($currentSort === $key) ? ' class="active"' : '';
        $params = $_GET;
        $params['sort'] = $key;
        unset($params['page']);
        $url = $baseUrl ?: strtok($_SERVER['REQUEST_URI'], '?');
        $qs = http_build_query($params);
        $href = htmlspecialchars($url . ($qs ? '?' . $qs : ''));
        $html .= "<a href=\"{$href}\"{$active}>{$label}</a>";
    }
    $html .= '</div>';
    return $html;
}

 
function simplySortDropdown(string $currentSort, string $baseUrl = '', ?array $customTabs = null): string
{
    if ($customTabs !== null) {
        $tabs = $customTabs;
    } else {
        $tabs = [
            'newest'    => __('newest'),
            'popular'   => __('most_viewed'),
            'top_rated' => __('top_rated'),
        ];
        $tabs = HookSystem::applyFilter('front.sort_tabs', $tabs);
    }

    $currentLabel = $tabs[$currentSort] ?? reset($tabs);

     
    if (isset($tabs[$currentSort])) {
        $tabs = [$currentSort => $tabs[$currentSort]] + array_diff_key($tabs, [$currentSort => '']);
    }

    $html = '<div class="section-sort-dropdown">';
    $html .= '<button type="button" class="section-sort-dropdown__toggle">';
    $html .= '<span class="section-sort-dropdown__label">' . htmlspecialchars($currentLabel) . '</span>';
    $html .= '<svg class="section-sort-dropdown__arrow" width="12" height="12" viewBox="0 0 12 12" fill="none"><path d="M3 4.5L6 7.5L9 4.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>';
    $html .= '</button>';
    $html .= '<div class="section-sort-dropdown__menu">';

    $i = 0;
    $total = count($tabs);
    foreach ($tabs as $key => $label) {
        $params = $_GET;
        $params['sort'] = $key;
        unset($params['page']);
        $url = $baseUrl ?: strtok($_SERVER['REQUEST_URI'], '?');
        $qs = http_build_query($params);
        $href = htmlspecialchars($url . ($qs ? '?' . $qs : ''));
        $active = ($currentSort === $key) ? ' section-sort-dropdown__item--active' : '';
        $html .= "<a href=\"{$href}\" class=\"section-sort-dropdown__item{$active}\">{$label}</a>";
        $i++;
        if ($i < $total) {
            $html .= '<div class="section-sort-dropdown__divider"></div>';
        }
    }

    $html .= '</div></div>';
    return $html;
}

 
function simplyPagination(Pagination $pagination, string $baseUrl = ''): string
{
    if ($pagination->totalPages <= 1) {
        return '';
    }

    $html = '<nav class="pagination">';

    if ($pagination->hasPrev()) {
        $html .= '<a href="' . htmlspecialchars($pagination->prevUrl($baseUrl)) . '" class="pagination__link" rel="prev">&laquo;</a>';
    }

    foreach ($pagination->pages() as $page) {
        if ($page === '...') {
            $html .= '<span class="pagination__dots">&hellip;</span>';
        } elseif ($page === $pagination->page) {
            $html .= '<span class="pagination__link pagination__link--active">' . $page . '</span>';
        } else {
            $params = $_GET;
            $params['page'] = $page;
            $url = $baseUrl . '?' . http_build_query($params);
            $html .= '<a href="' . htmlspecialchars($url) . '" class="pagination__link">' . $page . '</a>';
        }
    }

    if ($pagination->hasNext()) {
        $html .= '<a href="' . htmlspecialchars($pagination->nextUrl($baseUrl)) . '" class="pagination__link" rel="next">&raquo;</a>';
    }

    $html .= '</nav>';
    return $html;
}

 
HookSystem::addFilter('theme.template_data', function (array $data, string $template): array {
     
    $data['_siteLogo'] = Setting::get('site_logo', '');
    $data['_siteLogoDark'] = Setting::get('site_logo_dark', '');
    $data['_siteFavicon'] = Setting::get('site_favicon', '');

     
    $data['_cardShowDuration']   = Setting::get('card_show_duration', '1') === '1';
    $data['_cardShowTitle']      = Setting::get('card_show_title', '1') === '1';
    $data['_cardMetaLeft']       = Setting::get('card_meta_left', 'views');
    $data['_cardMetaRight']      = Setting::get('card_meta_right', 'time');
    $data['_cardGridGap']        = (int) Setting::get('card_grid_gap', '4');
    $data['_cardBorderRadius']   = (int) Setting::get('card_border_radius', '8');
    $data['_cardThumbnailHover'] = Setting::get('card_show_thumbnail_hover', '1') === '1';
    $data['_cardTitleLines']     = (int) Setting::get('card_title_lines', '1');

     
    $footerConfig = FooterConfig::get();
    $data['_footerColumns'] = FooterConfig::resolveColumns($footerConfig);
    $data['_footerBottom'] = $footerConfig['bottom'] ?? [];
    $data['_footerSocial'] = $footerConfig['social'] ?? [];
    $socialLinks = [];
    foreach (($footerConfig['social'] ?? []) as $sk => $val) {
        if ($val !== '') { $socialLinks[$sk] = $val; }
    }
    $data['_socialLinks'] = $socialLinks;

     
    $data['_performersPerRow'] = (int) Setting::get('simply_performers_per_row', '5');
    $data['_channelsPerRow']    = (int) Setting::get('simply_channels_per_row', '5');
     
    $data['_albumsPerRow']       = (int) Setting::get('albums_per_row', '5');
    $data['_albumCardHover']      = Setting::get('album_card_show_thumbnail_hover', '1') === '1';
    $data['_albumCardTitleLines'] = (int) Setting::get('album_card_title_lines', '2');
    $data['_topbarEnabled']    = Setting::get('simply_topbar_enabled', '0') === '1';
    $data['_topbarText']       = __('simply_topbar_announcement');
    $data['_topbarLinks']      = json_decode(Setting::get('simply_topbar_links', '[]'), true) ?: [];
     
    $data['_navStyle'] = Setting::get('simply_nav_style', 'default');
     
    $data['_hpWatchedEnabled'] = Setting::get('simply_hp_watched_enabled', '1') === '1';
    $data['_hpTitleWatched']   = __('simply_section_watch_again');
     
    $data['_hpSortTitles'] = [
        'trending'  => __('simply_section_trending'),
        'newest'    => __('simply_section_latest'),
        'popular'   => __('simply_section_most_viewed'),
        'top_rated' => __('simply_section_top_rated'),
    ];
     
    $data['_darkModeEnabled']  = Setting::get('simply_dark_mode_enabled', '1') === '1';
    $data['_darkModeDefault']  = Setting::get('simply_dark_mode_default', 'light');
     
    $data['_topbarTextBold']     = Setting::get('simply_topbar_text_bold', '0') === '1';
    $data['_topbarTextItalic']   = Setting::get('simply_topbar_text_italic', '0') === '1';
    $data['_topbarLinkBold']     = Setting::get('simply_topbar_link_bold', '0') === '1';
    $data['_topbarLinkItalic']   = Setting::get('simply_topbar_link_italic', '0') === '1';
    $data['_topbarLinkUnderline'] = Setting::get('simply_topbar_link_underline', '0') === '1';
    $data['_topbarLinkHoverUnderline'] = Setting::get('simply_topbar_link_hover_underline', '1') === '1';
     
    $_colorMap = [
        'bg' => '_topbarBgColor', 'text' => '_topbarTextColor', 'hover_text' => '_topbarHoverTextColor',
        'dark_bg' => '_topbarDarkBgColor', 'dark_text' => '_topbarDarkTextColor', 'dark_hover_text' => '_topbarDarkHoverTextColor',
    ];
    foreach ($_colorMap as $_ck => $_var) {
        $_hex = Setting::get("simply_topbar_{$_ck}_color", '');
        $_op  = (int) Setting::get("simply_topbar_{$_ck}_opacity", '100');
        if ($_hex !== '') {
            $_h = ltrim($_hex, '#');
            if (strlen($_h) === 3) $_h = $_h[0].$_h[0].$_h[1].$_h[1].$_h[2].$_h[2];
            if ($_op < 100 && strlen($_h) === 6) {
                $_r = hexdec(substr($_h, 0, 2)); $_g = hexdec(substr($_h, 2, 2)); $_b = hexdec(substr($_h, 4, 2));
                $data[$_var] = "rgba($_r,$_g,$_b," . round($_op / 100, 2) . ")";
            } else {
                $data[$_var] = $_hex;
            }
        } else {
            $data[$_var] = '';
        }
    }

     
    $locale = Translator::locale();
    $defaultCode = Translator::getDefaultCode();
    if ($locale !== $defaultCode) {
         
        foreach ($data['_topbarLinks'] as &$_tl) {
            if (!empty($_tl['_translations']['text'][$locale])) {
                $_tl['text'] = $_tl['_translations']['text'][$locale];
            }
        }
        unset($_tl);
         
        foreach ($data['_footerColumns'] as &$_ftCol) {
            if (!empty($_ftCol['_translations']['title'][$locale])) {
                $_ftCol['title'] = $_ftCol['_translations']['title'][$locale];
            }
            if (!empty($_ftCol['links'])) {
                foreach ($_ftCol['links'] as &$_ftLink) {
                    if (!empty($_ftLink['_translations']['label'][$locale])) {
                        $_ftLink['label'] = $_ftLink['_translations']['label'][$locale];
                    }
                }
                unset($_ftLink);
            }
            if (!empty($_ftCol['badges'])) {
                foreach ($_ftCol['badges'] as &$_ftBadge) {
                    if (!empty($_ftBadge['_translations']['label'][$locale])) {
                        $_ftBadge['label'] = $_ftBadge['_translations']['label'][$locale];
                    }
                }
                unset($_ftBadge);
            }
        }
        unset($_ftCol);
         
        if (!empty($data['_footerBottom']['_translations']['copyright_text'][$locale])) {
            $data['_footerBottom']['copyright_text'] = $data['_footerBottom']['_translations']['copyright_text'][$locale];
        }
        if (!empty($data['_footerBottom']['_translations']['disclaimer_text'][$locale])) {
            $data['_footerBottom']['disclaimer_text'] = $data['_footerBottom']['_translations']['disclaimer_text'][$locale];
        }
    }

    return $data;
});

 
HookSystem::addAction('routes.registered', function (): void {
    Router::get('/watch-history', function () {
        ThemeRenderer::render('watch-history', [
            'pageTitle' => SEO::title(__('watch_history') ?: 'Watch History'),
        ]);
    });
});

 
HookSystem::addFilter('front.default_sort', function (string $default, string $context): string {
    if ($context === 'home') {
        $configured = Setting::get('simply_hp_default_sort', '');
        if ($configured !== '') {
            return $configured;
        }
    }
    return $default;
}, 20);

 
HookSystem::addFilter('head.css', function (string $html): string {
    $cardGap = (int) Setting::get('card_grid_gap', '4');
    $cardRadius = (int) Setting::get('card_border_radius', '8');
    $albGap = (int) Setting::get('album_card_grid_gap', '4');
    $albRadius = (int) Setting::get('album_card_border_radius', '8');
    $html .= '<style>:root{--card-gap:' . $cardGap . 'px;--card-radius:' . $cardRadius . 'px;--album-card-gap:' . $albGap . 'px;--album-card-radius:' . $albRadius . 'px}</style>' . "\n";
    return $html;
});

 
HookSystem::addAction('admin.menu_extra', function (array $settings): void {
    $current = Setting::get('simply_nav_style', 'default');
    ?>
    <div style="display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-bottom:16px;">
        <label style="display:flex;align-items:flex-start;gap:10px;padding:12px 14px;border-radius:10px;border:2px solid <?= $current === 'default' ? '#c7d2fe' : '#e5e7eb' ?>;background:<?= $current === 'default' ? '#eef2ff' : '#fff' ?>;cursor:pointer;transition:all .15s;"
               onclick="setTimeout(()=>{let r=this.querySelector('input');if(r.checked){this.style.borderColor='#c7d2fe';this.style.background='#eef2ff';this.nextElementSibling.style.borderColor='#e5e7eb';this.nextElementSibling.style.background='#fff';}},0)">
            <input type="radio" name="simply_nav_style" value="default" <?= $current === 'default' ? 'checked' : '' ?>
                   style="width:16px;height:16px;accent-color:#4f46e5;cursor:pointer;flex-shrink:0;margin-top:1px;">
            <div style="flex:1;min-width:0;">
                <div style="font-size:13px;font-weight:600;color:#374151;">Default</div>
                <div style="font-size:11px;color:#9ca3af;margin-top:1px;">Contained within content area</div>
                <div style="margin-top:8px;border:1px solid #e5e7eb;border-radius:6px;overflow:hidden;background:#f9fafb;">
                    <div style="height:5px;background:#fff;border-bottom:1px solid #e5e7eb;"></div>
                    <div style="display:flex;gap:3px;padding:4px 20px;border-bottom:1px solid #e5e7eb;background:#fff;">
                        <div style="width:18px;height:4px;background:#4f46e5;border-radius:2px;"></div>
                        <div style="width:18px;height:4px;background:#d1d5db;border-radius:2px;"></div>
                        <div style="width:18px;height:4px;background:#d1d5db;border-radius:2px;"></div>
                    </div>
                    <div style="height:16px;"></div>
                </div>
            </div>
        </label>
        <label style="display:flex;align-items:flex-start;gap:10px;padding:12px 14px;border-radius:10px;border:2px solid <?= $current === 'full' ? '#c7d2fe' : '#e5e7eb' ?>;background:<?= $current === 'full' ? '#eef2ff' : '#fff' ?>;cursor:pointer;transition:all .15s;"
               onclick="setTimeout(()=>{let r=this.querySelector('input');if(r.checked){this.style.borderColor='#c7d2fe';this.style.background='#eef2ff';this.previousElementSibling.style.borderColor='#e5e7eb';this.previousElementSibling.style.background='#fff';}},0)">
            <input type="radio" name="simply_nav_style" value="full" <?= $current === 'full' ? 'checked' : '' ?>
                   style="width:16px;height:16px;accent-color:#4f46e5;cursor:pointer;flex-shrink:0;margin-top:1px;">
            <div style="flex:1;min-width:0;">
                <div style="font-size:13px;font-weight:600;color:#374151;">Full Width</div>
                <div style="font-size:11px;color:#9ca3af;margin-top:1px;">Stretches across entire screen</div>
                <div style="margin-top:8px;border:1px solid #e5e7eb;border-radius:6px;overflow:hidden;background:#f9fafb;">
                    <div style="height:5px;background:#fff;border-bottom:1px solid #e5e7eb;"></div>
                    <div style="display:flex;gap:0;border-bottom:1px solid #e5e7eb;background:#fff;">
                        <div style="flex:1;display:flex;align-items:center;justify-content:center;padding:5px 0;"><div style="width:18px;height:5px;background:#4f46e5;border-radius:2px;"></div></div>
                        <div style="flex:1;display:flex;align-items:center;justify-content:center;padding:5px 0;"><div style="width:18px;height:5px;background:#d1d5db;border-radius:2px;"></div></div>
                        <div style="flex:1;display:flex;align-items:center;justify-content:center;padding:5px 0;"><div style="width:18px;height:5px;background:#d1d5db;border-radius:2px;"></div></div>
                    </div>
                    <div style="height:16px;"></div>
                </div>
            </div>
        </label>
    </div>
    <?php
});

 
HookSystem::addAction('admin.appearance_save.menu.after', function (): void {
    $style = $_POST['simply_nav_style'] ?? 'default';
    Setting::set('simply_nav_style', in_array($style, ['default', 'full'], true) ? $style : 'default');
});

 
HookSystem::addAction('admin.appearance_extra.performers', function (array $settings): void {
    $currentPerf = (int) Setting::get('simply_performers_per_row', '5');
    ?>
    <div>
        <label class="block text-sm font-medium text-gray-700 mb-2">Per row</label>
        <div class="flex gap-2">
            <?php foreach ([4, 5, 6, 7] as $n): ?>
                <label class="flex-1 cursor-pointer">
                    <input type="radio" name="simply_performers_per_row" value="<?= $n ?>" class="sr-only peer" <?= $currentPerf === $n ? 'checked' : '' ?>>
                    <div class="border-2 rounded-lg p-2 text-center transition-all peer-checked:border-primary-600 peer-checked:bg-primary-50 border-gray-200 hover:border-gray-300">
                        <div class="flex gap-0.5 justify-center mb-1">
                            <?php for ($i = 0; $i < $n; $i++): ?>
                                <div class="h-3 bg-gray-300 rounded-sm" style="width: <?= round(40 / $n) ?>px"></div>
                            <?php endfor; ?>
                        </div>
                        <span class="text-xs font-medium text-gray-600"><?= $n ?></span>
                    </div>
                </label>
            <?php endforeach; ?>
        </div>
    </div>
    <?php
});

 
HookSystem::addAction('admin.appearance_extra.channels', function (array $settings): void {
    $currentChannel = (int) Setting::get('simply_channels_per_row', '5');
    ?>
    <div>
        <label class="block text-sm font-medium text-gray-700 mb-2">Per row</label>
        <div class="flex gap-2">
            <?php foreach ([4, 5, 6, 7] as $n): ?>
                <label class="flex-1 cursor-pointer">
                    <input type="radio" name="simply_channels_per_row" value="<?= $n ?>" class="sr-only peer" <?= $currentChannel === $n ? 'checked' : '' ?>>
                    <div class="border-2 rounded-lg p-2 text-center transition-all peer-checked:border-primary-600 peer-checked:bg-primary-50 border-gray-200 hover:border-gray-300">
                        <div class="flex gap-0.5 justify-center mb-1">
                            <?php for ($i = 0; $i < $n; $i++): ?>
                                <div class="h-3 bg-gray-300 rounded-sm" style="width: <?= round(40 / $n) ?>px"></div>
                            <?php endfor; ?>
                        </div>
                        <span class="text-xs font-medium text-gray-600"><?= $n ?></span>
                    </div>
                </label>
            <?php endforeach; ?>
        </div>
    </div>
    <?php
});

 
HookSystem::addAction('admin.appearance_save.layout', function (): void {
    $perfRow = (int) ($_POST['simply_performers_per_row'] ?? 5);
    Setting::set('simply_performers_per_row', (string) max(4, min(7, $perfRow)));
    $channelRow = (int) ($_POST['simply_channels_per_row'] ?? 5);
    Setting::set('simply_channels_per_row', (string) max(4, min(7, $channelRow)));
});

 
HookSystem::addFilter('admin.subtabs.appearance', function (array $subs): array {
    $result = [];
     
    $result['branding'] = 'Branding';
    foreach ($subs as $k => $v) {
        $result[$k] = $v;
        if ($k === 'colors') {
            $result['homepage'] = 'Homepage';
        }
        if ($k === 'menu') {
            $result['header'] = 'Header';
            $result['footer'] = 'Footer';
        }
        if ($k === 'layout') {
            $result['cards'] = 'Cards';
        }
    }
    return $result;
});

 
HookSystem::addFilter('admin.appearance_settings_keys', function (array $keys): array {
    return array_merge($keys, [
        'albums_per_page','albums_per_row','albums_default_sort',
        'album_card_show_count','album_card_show_title','album_card_show_thumbnail_hover',
        'album_card_show_views','album_card_show_date','album_card_title_lines',
        'album_card_border_radius','album_card_grid_gap',
        'album_show_views','album_show_date','album_show_likes','album_show_favorites',
        'album_show_pornstars','album_show_channels','album_show_categories','album_show_tags',
        'album_allow_download','related_albums_count',
    ]);
});

 
HookSystem::addAction('admin.appearance_render.header', function (array $vars): void {
    $settings = $vars['settings'] ?? $vars;
    $darkModeEnabled = Setting::get('simply_dark_mode_enabled', '1') === '1';
    $darkModeDefault = Setting::get('simply_dark_mode_default', 'light');
     
    $enabled  = Setting::get('simply_topbar_enabled', '0') === '1';
    $text     = Setting::get('simply_topbar_text', '');
    $links    = json_decode(Setting::get('simply_topbar_links', '[]'), true) ?: [];
     
    $bgColor  = Setting::get('simply_topbar_bg_color', '');
    $bgOp     = (int) Setting::get('simply_topbar_bg_opacity', '100');
    $txtColor = Setting::get('simply_topbar_text_color', '');
    $txtOp    = (int) Setting::get('simply_topbar_text_opacity', '100');
    $hoverTxtColor = Setting::get('simply_topbar_hover_text_color', '');
    $hoverTxtOp    = (int) Setting::get('simply_topbar_hover_text_opacity', '100');
     
    $darkBgColor  = Setting::get('simply_topbar_dark_bg_color', '');
    $darkBgOp     = (int) Setting::get('simply_topbar_dark_bg_opacity', '100');
    $darkTxtColor = Setting::get('simply_topbar_dark_text_color', '');
    $darkTxtOp    = (int) Setting::get('simply_topbar_dark_text_opacity', '100');
    $darkHoverTxtColor = Setting::get('simply_topbar_dark_hover_text_color', '');
    $darkHoverTxtOp    = (int) Setting::get('simply_topbar_dark_hover_text_opacity', '100');
     
    $textBold     = Setting::get('simply_topbar_text_bold', '0') === '1';
    $textItalic   = Setting::get('simply_topbar_text_italic', '0') === '1';
    $linkBold     = Setting::get('simply_topbar_link_bold', '0') === '1';
    $linkItalic   = Setting::get('simply_topbar_link_italic', '0') === '1';
    $linkUnderline = Setting::get('simply_topbar_link_underline', '0') === '1';
    $linkHoverUnderline = Setting::get('simply_topbar_link_hover_underline', '1') === '1';
    ?>
    <style>
    .tb-link-row{display:flex;gap:8px;align-items:center;margin-bottom:6px}
    .tb-icon-btn{width:34px;height:34px;display:flex;align-items:center;justify-content:center;border-radius:7px;flex-shrink:0;cursor:pointer;border:1px dashed #d1d5db;background:#fff;color:#9ca3af;font-size:13px;transition:all .12s}
    .tb-icon-btn:hover{border-color:#818cf8;color:#6366f1;background:#eef2ff}
    .tb-icon-btn.has-icon{border-style:solid;background:#eef2ff;color:#4f46e5;border-color:#c7d2fe}
    .tb-color-block{margin-bottom:8px;position:relative}
    .tb-color-row{display:flex;align-items:center;gap:6px}
    .tb-color-label{font-size:11px;font-weight:600;color:#6b7280;width:72px;flex-shrink:0}
    .tb-fmt-bar{display:inline-flex;gap:2px;border:1px solid #e5e7eb;border-radius:6px;padding:2px;background:#f9fafb}
    .tb-fmt-btn{width:26px;height:24px;display:flex;align-items:center;justify-content:center;border:none;border-radius:4px;background:transparent;cursor:pointer;font-size:12px;color:#6b7280;transition:all .1s;font-family:Georgia,serif}
    .tb-fmt-btn:hover{background:#e5e7eb;color:#374151}
    .tb-fmt-btn.active{background:#4f46e5;color:#fff}
    .tb-color-swatch{width:34px;height:34px;border-radius:8px;border:2px solid #e5e7eb;cursor:pointer;flex-shrink:0;padding:0;position:relative;overflow:hidden;background:repeating-conic-gradient(#d1d5db 0% 25%,#fff 0% 50%) 0 0/14px 14px}
    .tb-color-swatch .tb-swatch-fill{position:absolute;inset:0;border-radius:6px;pointer-events:none}
    .tb-color-swatch:hover{border-color:#818cf8}
    .tb-hex-input{width:90px;padding:7px 10px;border:1px solid #d1d5db;border-radius:7px;font-size:13px;font-family:monospace;outline:none;transition:border-color .12s}
    .tb-hex-input:focus{border-color:#4f46e5;box-shadow:0 0 0 3px rgba(79,70,229,.08)}
    .tb-opacity-badge{padding:2px 8px;font-size:11px;font-weight:600;color:#6b7280;background:#f3f4f6;border-radius:10px;white-space:nowrap}
    .tb-reset-btn{padding:4px 10px;font-size:11px;color:#9ca3af;background:none;border:1px solid #e5e7eb;border-radius:6px;cursor:pointer;transition:all .12s;white-space:nowrap}
    .tb-reset-btn:hover{color:#dc2626;border-color:#fecaca;background:#fef2f2}
    .tb-picker{display:none;position:absolute;top:100%;left:0;z-index:100;width:260px;background:#fff;border:1px solid #e5e7eb;border-radius:12px;box-shadow:0 12px 40px rgba(0,0,0,.15);padding:14px;margin-top:6px}
    .tb-picker.open{display:block}
    .tb-picker__sv-wrap{position:relative;width:100%;height:150px;border-radius:8px;overflow:hidden;cursor:crosshair;margin-bottom:12px}
    .tb-picker__sv-wrap canvas{width:100%;height:100%;display:block}
    .tb-picker__sv-cursor{position:absolute;width:14px;height:14px;border:2px solid #fff;border-radius:50%;box-shadow:0 0 0 1px rgba(0,0,0,.3),inset 0 0 0 1px rgba(0,0,0,.15);pointer-events:none;transform:translate(-50%,-50%)}
    .tb-picker__row{display:flex;align-items:center;gap:8px;margin-bottom:8px}
    .tb-picker__label{font-size:10px;font-weight:600;color:#9ca3af;text-transform:uppercase;width:14px;flex-shrink:0}
    .tb-picker__hue{-webkit-appearance:none;appearance:none;flex:1;height:12px;border-radius:6px;outline:none;background:linear-gradient(to right,#f00 0%,#ff0 17%,#0f0 33%,#0ff 50%,#00f 67%,#f0f 83%,#f00 100%);cursor:pointer}
    .tb-picker__hue::-webkit-slider-thumb{-webkit-appearance:none;width:16px;height:16px;border-radius:50%;background:#fff;border:2px solid rgba(0,0,0,.2);box-shadow:0 1px 3px rgba(0,0,0,.2);cursor:pointer}
    .tb-picker__alpha-track{flex:1;height:12px;border-radius:6px;position:relative;overflow:hidden;background:repeating-conic-gradient(#d1d5db 0% 25%,#fff 0% 50%) 0 0/10px 10px}
    .tb-picker__alpha-fill{position:absolute;inset:0;border-radius:6px}
    .tb-picker__alpha{-webkit-appearance:none;appearance:none;position:absolute;inset:0;width:100%;height:100%;background:transparent;cursor:pointer;margin:0}
    .tb-picker__alpha::-webkit-slider-thumb{-webkit-appearance:none;width:16px;height:16px;border-radius:50%;background:#fff;border:2px solid rgba(0,0,0,.2);box-shadow:0 1px 3px rgba(0,0,0,.2);cursor:pointer}
    .tb-picker__alpha-val{font-size:11px;font-weight:600;color:#374151;min-width:30px;text-align:right}
    .tb-picker__hex-row{display:flex;align-items:center;gap:8px;margin-top:4px}
    .tb-picker__hex-input{flex:1;padding:6px 8px;border:1px solid #d1d5db;border-radius:6px;font-size:12px;font-family:monospace;outline:none}
    .tb-picker__hex-input:focus{border-color:#4f46e5;box-shadow:0 0 0 3px rgba(79,70,229,.08)}
    @media(max-width:479px){.tb-picker{width:calc(100vw - 48px);left:50%;transform:translateX(-50%)}}
    @media(max-width:479px){.tb-theme-tab{font-size:11px;padding:6px 0}}
    .tb-theme-tabs{display:flex;gap:0;margin-bottom:16px;border:1px solid #e5e7eb;border-radius:8px;overflow:hidden}
    .tb-theme-tab{flex:1;padding:8px 0;text-align:center;font-size:12px;font-weight:600;cursor:pointer;border:none;background:#f9fafb;color:#6b7280;transition:all .15s;display:flex;align-items:center;justify-content:center;gap:5px}
    .tb-theme-tab:not(:last-child){border-right:1px solid #e5e7eb}
    .tb-theme-tab.active{background:#fff;color:#4f46e5;box-shadow:inset 0 -2px 0 #4f46e5}
    .tb-theme-pane{display:none}
    .tb-theme-pane.active{display:block}
    .tb-theme-tab--disabled{opacity:.35;pointer-events:none;cursor:default}
    .dm-note{margin:0;padding:8px 20px;font-size:11px;color:#9ca3af;border-top:1px solid #f3f4f6;display:flex;align-items:center;gap:6px;flex-wrap:wrap}
    @media(max-width:639px){.tb-link-row{flex-wrap:wrap}.tb-link-row input[type="text"],.tb-link-row input[type="url"]{flex:1 1 120px;min-width:0}}
    .tb-preview{border-radius:8px;overflow:hidden;padding:10px 16px;font-size:12px;margin-top:8px;transition:all .3s;display:flex;align-items:center;justify-content:center;gap:12px}
    .tb-preview a{color:inherit;text-decoration:underline;opacity:.8}
    .ip-overlay{display:none;position:fixed;inset:0;z-index:9999;background:rgba(0,0,0,.5);backdrop-filter:blur(2px);align-items:center;justify-content:center}
    .ip-overlay.open{display:flex}
    .ip-modal{background:#fff;border-radius:14px;width:900px;max-width:95vw;max-height:85vh;display:flex;flex-direction:column;box-shadow:0 20px 60px rgba(0,0,0,.2);animation:ipIn .2s ease}
    @keyframes ipIn{from{opacity:0;transform:scale(.96) translateY(8px)}to{opacity:1;transform:none}}
    .ip-hd{display:flex;align-items:center;gap:10px;padding:16px 20px;border-bottom:1px solid #e5e7eb;flex-shrink:0}
    .ip-hd__title{font-size:15px;font-weight:600;color:#111827;flex:1}
    .ip-hd__close{width:30px;height:30px;display:flex;align-items:center;justify-content:center;border:none;background:#f3f4f6;border-radius:8px;cursor:pointer;color:#6b7280;font-size:14px}
    .ip-hd__close:hover{background:#e5e7eb;color:#111}
    .ip-toolbar{display:flex;align-items:center;gap:10px;padding:12px 20px;border-bottom:1px solid #f3f4f6;flex-shrink:0;flex-wrap:wrap}
    .ip-search-wrap{position:relative;flex:1;min-width:180px}
    .ip-search-wrap i{position:absolute;left:11px;top:50%;transform:translateY(-50%);color:#9ca3af;font-size:13px;pointer-events:none}
    .ip-search{width:100%;padding:8px 12px 8px 34px;border:1px solid #d1d5db;border-radius:8px;font-size:13px;outline:none;transition:border-color .12s}
    .ip-search:focus{border-color:#4f46e5;box-shadow:0 0 0 3px rgba(79,70,229,.08)}
    .ip-styles{display:flex;gap:4px;flex-shrink:0}
    .ip-style-btn{padding:5px 12px;border:1px solid #e5e7eb;border-radius:6px;font-size:12px;font-weight:600;cursor:pointer;background:#fff;color:#6b7280;transition:all .1s}
    .ip-style-btn:hover{border-color:#c7d2fe;color:#4f46e5}
    .ip-style-btn.active{background:#4f46e5;color:#fff;border-color:#4f46e5}
    .ip-count{font-size:11px;color:#9ca3af;flex-shrink:0;white-space:nowrap}
    .ip-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(58px,1fr));gap:4px;padding:14px 20px 20px;overflow-y:auto;flex:1}
    .ip-icon{display:flex;align-items:center;justify-content:center;aspect-ratio:1;border-radius:8px;cursor:pointer;color:#4b5563;font-size:20px;transition:all .1s;border:2px solid transparent}
    .ip-icon:hover{background:#eef2ff;color:#4f46e5;border-color:#c7d2fe}
    .ip-icon.selected{background:#4f46e5;color:#fff;border-color:#4f46e5}
    .ip-empty{grid-column:1/-1;text-align:center;padding:32px;color:#9ca3af;font-size:13px}
    .ip-footer{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:12px 20px;border-top:1px solid #e5e7eb;flex-shrink:0}
    .ip-footer__sel{font-size:13px;color:#6b7280;display:flex;align-items:center;gap:8px}
    .ip-footer__sel i{font-size:20px;color:#4f46e5}
    .ip-footer__actions{display:flex;gap:6px}
    .ip-btn{padding:7px 16px;border-radius:7px;font-size:12px;font-weight:600;cursor:pointer;border:none;transition:all .1s}
    .ip-btn--ghost{background:#f3f4f6;color:#6b7280}.ip-btn--ghost:hover{background:#e5e7eb}
    .ip-btn--primary{background:#4f46e5;color:#fff}.ip-btn--primary:hover{background:#4338ca}
    .ip-btn--danger{background:none;color:#dc2626;font-weight:500;padding:7px 10px}.ip-btn--danger:hover{background:#fef2f2}
    </style>

    <form method="POST" action="/admin/appearance">
        <?= Router::csrfField() ?>
        <input type="hidden" name="_tab" value="appearance">
        <input type="hidden" name="_sub" value="header">

        
        

        
        <div class="bg-white rounded-lg shadow-sm border border-gray-200">
            <div class="px-5 py-3.5 border-b border-gray-200 flex items-center justify-between">
                <div class="flex items-center gap-2.5">
                    <span class="text-gray-400"><i class="fa-solid fa-bars-staggered"></i></span>
                    <h3 class="text-sm font-semibold text-gray-900">Top Bar</h3>
                </div>
                <label class="flex items-center gap-2 cursor-pointer">
                    <input type="checkbox" name="simply_topbar_enabled" value="1" <?= $enabled ? 'checked' : '' ?>
                           class="w-4 h-4 rounded border-gray-300 text-primary-600 focus:ring-primary-500" id="tbEnable">
                    <span class="text-xs font-medium text-gray-600">Enabled</span>
                </label>
            </div>
            <div class="p-5">
                <div class="grid grid-cols-1 lg:grid-cols-2 gap-5">

                    
                    <div class="border border-gray-200 rounded-lg overflow-hidden">
                        <div class="px-4 py-2.5 bg-gray-50 border-b border-gray-200">
                            <div class="text-xs font-semibold text-gray-500 uppercase tracking-wider flex items-center gap-2">
                                <i class="fa-solid fa-align-left text-[10px] text-gray-400"></i> Content
                            </div>
                        </div>
                        <div class="p-4 space-y-4">
                            
                            <div>
                                <label class="text-sm font-medium text-gray-700">Announcement text</label>
                                <p class="text-xs text-gray-500 mt-1">
                                    <i class="fa-solid fa-language mr-1"></i>
                                    Edit the announcement text per language in <a href="/admin/languages" class="text-primary-600 hover:text-primary-700 font-medium">Languages</a> under the <strong>Simply Theme</strong> section (<code class="text-[11px] bg-gray-100 px-1 py-0.5 rounded">simply_topbar_announcement</code>).
                                </p>
                                <input type="hidden" name="simply_topbar_text_bold" id="simply_topbar_text_bold" value="<?= $textBold ? '1' : '0' ?>">
                                <input type="hidden" name="simply_topbar_text_italic" id="simply_topbar_text_italic" value="<?= $textItalic ? '1' : '0' ?>">
                                <div class="flex items-center gap-2 mt-2">
                                    <span class="text-xs text-gray-500">Formatting:</span>
                                    <div class="tb-fmt-bar">
                                        <button type="button" class="tb-fmt-btn <?= $textBold ? 'active' : '' ?>" onclick="tbFmtToggle(this,'simply_topbar_text_bold')" title="Bold"><b>B</b></button>
                                        <button type="button" class="tb-fmt-btn <?= $textItalic ? 'active' : '' ?>" onclick="tbFmtToggle(this,'simply_topbar_text_italic')" title="Italic"><i style="font-style:italic">I</i></button>
                                    </div>
                                </div>
                            </div>

                            
                            <div>
                                <input type="hidden" name="simply_topbar_link_bold" id="simply_topbar_link_bold" value="<?= $linkBold ? '1' : '0' ?>">
                                <input type="hidden" name="simply_topbar_link_italic" id="simply_topbar_link_italic" value="<?= $linkItalic ? '1' : '0' ?>">
                                <input type="hidden" name="simply_topbar_link_underline" id="simply_topbar_link_underline" value="<?= $linkUnderline ? '1' : '0' ?>">
                                <div class="flex items-center justify-between mb-2">
                                    <label class="text-sm font-medium text-gray-700">Links</label>
                                    <div class="flex items-center gap-2">
                                        <div class="tb-fmt-bar">
                                            <button type="button" class="tb-fmt-btn <?= $linkBold ? 'active' : '' ?>" onclick="tbFmtToggle(this,'simply_topbar_link_bold')" title="Bold"><b>B</b></button>
                                            <button type="button" class="tb-fmt-btn <?= $linkItalic ? 'active' : '' ?>" onclick="tbFmtToggle(this,'simply_topbar_link_italic')" title="Italic"><i style="font-style:italic">I</i></button>
                                            <button type="button" class="tb-fmt-btn <?= $linkUnderline ? 'active' : '' ?>" onclick="tbFmtToggle(this,'simply_topbar_link_underline')" title="Underline"><u>U</u></button>
                                        </div>
                                        <label class="flex items-center gap-1 text-[11px] text-gray-500 cursor-pointer" title="Underline links on hover">
                                            <input type="checkbox" name="simply_topbar_link_hover_underline" value="1" <?= $linkHoverUnderline ? 'checked' : '' ?>
                                                   class="w-3.5 h-3.5 rounded border-gray-300 text-primary-600 focus:ring-primary-500"> hover <u>U</u>
                                        </label>
                                    </div>
                                </div>
                                <div id="topbar-links">
                                    <?php foreach ($links as $i => $link): ?>
                                    <div class="tb-link-row" data-icon="<?= htmlspecialchars($link['icon'] ?? '') ?>">
                                        <button type="button" class="tb-icon-btn<?= !empty($link['icon']) ? ' has-icon' : '' ?>" onclick="openIconPicker(this.closest('.tb-link-row'))">
                                            <?php if (!empty($link['icon'])): ?>
                                                <i class="fa-solid fa-<?= htmlspecialchars($link['icon']) ?>"></i>
                                            <?php else: ?>
                                                <i class="fa-solid fa-circle-plus" style="font-size:15px;"></i>
                                            <?php endif; ?>
                                        </button>
                                        <input type="hidden" name="topbar_link_icon[]" class="tb-icon-val" value="<?= htmlspecialchars($link['icon'] ?? '') ?>">
                                        <input type="text" name="topbar_link_text[]" value="<?= htmlspecialchars($link['text'] ?? '') ?>"
                                               placeholder="Label" class="flex-1 px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-primary-500 focus:border-primary-500 outline-none">
                                        <?= simplyTranslateButton('topbar_link_' . $i, 'Link text', 'input', $link['_translations']['text'] ?? [], 'topbar_link_text_translations[' . $i . ']') ?>
                                        <input type="url" name="topbar_link_url[]" value="<?= htmlspecialchars($link['url'] ?? '') ?>"
                                               placeholder="https://..." class="flex-1 px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-primary-500 focus:border-primary-500 outline-none">
                                        <button type="button" onclick="this.closest('.tb-link-row').remove();tbUpdatePreview();"
                                                class="p-2 text-gray-400 hover:text-red-500 transition-colors flex-shrink-0" title="Remove">
                                            <i class="fa-solid fa-xmark"></i>
                                        </button>
                                    </div>
                                    <?php endforeach; ?>
                                </div>
                                <button type="button" id="topbar-add-link"
                                        class="mt-2 inline-flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium text-primary-600 bg-primary-50 rounded-lg hover:bg-primary-100 transition-colors">
                                    <i class="fa-solid fa-plus" style="font-size:10px;"></i> Add link
                                </button>
                            </div>
                        </div>
                    </div>

                    
                    <div class="border border-gray-200 rounded-lg overflow-hidden">
                        <div class="px-4 py-2.5 bg-gray-50 border-b border-gray-200">
                            <div class="text-xs font-semibold text-gray-500 uppercase tracking-wider flex items-center gap-2">
                                <i class="fa-solid fa-palette text-[10px] text-gray-400"></i> Appearance
                            </div>
                        </div>
                        <div class="p-4 space-y-4">
                            
                            <div class="tb-theme-tabs">
                                <button type="button" class="tb-theme-tab active" onclick="tbSwitchThemeMode('light')">
                                    <i class="fa-regular fa-sun" style="font-size:11px;"></i> Light mode
                                </button>
                                <button type="button" class="tb-theme-tab" onclick="tbSwitchThemeMode('dark')">
                                    <i class="fa-regular fa-moon" style="font-size:11px;"></i> Dark mode
                                </button>
                            </div>
                            <p id="dmNote" class="dm-note" style="display:none;padding:0 0 4px;border-top:none"><i class="fa-solid fa-circle-info" style="font-size:10px"></i> <span id="dmNoteText"></span></p>

                            <?php
                             
                            $colorRow = function(string $key, string $name, string $label, string $hex, int $op, string $placeholder) {
                                ?>
                                <div class="tb-color-block" id="tb_<?= $key ?>_block">
                                    <div class="tb-color-row">
                                        <span class="tb-color-label"><?= $label ?></span>
                                        <button type="button" class="tb-color-swatch" id="tb_<?= $key ?>_swatch" onclick="pkOpen('<?= $key ?>',this)">
                                            <span class="tb-swatch-fill"></span>
                                        </button>
                                        <input type="text" id="tb_<?= $key ?>_hex" name="<?= $name ?>"
                                               value="<?= htmlspecialchars($hex) ?>"
                                               class="tb-hex-input" placeholder="<?= $placeholder ?>"
                                               oninput="pkHexInput('<?= $key ?>')">
                                        <input type="hidden" id="tb_<?= $key ?>_opacity" name="<?= str_replace('_color', '_opacity', $name) ?>" value="<?= $op ?>">
                                        <span class="tb-opacity-badge" id="tb_<?= $key ?>_opacity_val"><?= $op ?>%</span>
                                        <button type="button" class="tb-reset-btn" onclick="pkReset('<?= $key ?>')">
                                            <i class="fa-solid fa-rotate-left" style="font-size:10px;"></i>
                                        </button>
                                    </div>
                                </div>
                                <?php
                            };
                            ?>

                            
                            <div class="tb-theme-pane active" id="tbThemeLight">
                                <?php $colorRow('bg', 'simply_topbar_bg_color', 'Background', $bgColor, $bgOp, '#1a1a2e'); ?>
                                <?php $colorRow('text', 'simply_topbar_text_color', 'Text', $txtColor, $txtOp, '#ffffff'); ?>
                                <?php $colorRow('hover_text', 'simply_topbar_hover_text_color', 'Hover', $hoverTxtColor, $hoverTxtOp, '#ffffff'); ?>
                            </div>

                            
                            <div class="tb-theme-pane" id="tbThemeDark">
                                <?php $colorRow('dark_bg', 'simply_topbar_dark_bg_color', 'Background', $darkBgColor, $darkBgOp, '#1e293b'); ?>
                                <?php $colorRow('dark_text', 'simply_topbar_dark_text_color', 'Text', $darkTxtColor, $darkTxtOp, '#e2e8f0'); ?>
                                <?php $colorRow('dark_hover_text', 'simply_topbar_dark_hover_text_color', 'Hover', $darkHoverTxtColor, $darkHoverTxtOp, '#818cf8'); ?>
                            </div>

                            
                            <div class="tb-picker" id="tbPicker">
                                <div class="tb-picker__sv-wrap" id="pkSvWrap">
                                    <canvas id="pkSvCanvas" width="232" height="150"></canvas>
                                    <div class="tb-picker__sv-cursor" id="pkSvCursor"></div>
                                </div>
                                <div class="tb-picker__row">
                                    <span class="tb-picker__label">H</span>
                                    <input type="range" class="tb-picker__hue" id="pkHue" min="0" max="360" step="1" value="0">
                                </div>
                                <div class="tb-picker__row">
                                    <span class="tb-picker__label">A</span>
                                    <div class="tb-picker__alpha-track">
                                        <div class="tb-picker__alpha-fill" id="pkAlphaFill"></div>
                                        <input type="range" class="tb-picker__alpha" id="pkAlpha" min="0" max="100" step="1" value="100">
                                    </div>
                                    <span class="tb-picker__alpha-val" id="pkAlphaVal">100%</span>
                                </div>
                                <div class="tb-picker__hex-row">
                                    <span class="tb-picker__label">#</span>
                                    <input type="text" class="tb-picker__hex-input" id="pkHexInput" maxlength="7" placeholder="#000000">
                                </div>
                            </div>

                            
                            <div style="margin-top:12px;">
                                <label class="block text-xs font-semibold text-gray-500 mb-2 uppercase tracking-wider">Preview</label>
                                <div class="tb-preview" id="tb-preview" style="background:#1a1a2e;color:#fff;"></div>
                                <div class="tb-preview" id="tb-preview-hover" style="background:#1a1a2e;color:#fff;margin-top:3px;"></div>
                            </div>
                        </div>
                    </div>

                </div>
            </div>
        </div>

        <div class="mt-5">
            <button type="submit" class="inline-flex items-center px-5 py-2 bg-primary-600 text-white text-sm font-medium rounded-lg hover:bg-primary-700 transition-colors shadow-sm">
                <i class="fa-solid fa-check" style="margin-right:6px;font-size:11px;"></i> Save changes
            </button>
        </div>
    </form>

    
    <div class="ip-overlay" id="iconPicker">
        <div class="ip-modal">
            <div class="ip-hd">
                <span class="ip-hd__title">Choose an icon</span>
                <button type="button" class="ip-hd__close" onclick="ipClose()"><i class="fa-solid fa-xmark"></i></button>
            </div>
            <div class="ip-toolbar">
                <div class="ip-search-wrap">
                    <i class="fa-solid fa-magnifying-glass"></i>
                    <input type="text" class="ip-search" id="ipSearch" placeholder="Search icons..." autocomplete="off">
                </div>
                <div class="ip-styles" id="ipStyles">
                    <button type="button" class="ip-style-btn active" data-style="solid">Solid</button>
                    <button type="button" class="ip-style-btn" data-style="regular">Regular</button>
                    <button type="button" class="ip-style-btn" data-style="light">Light</button>
                    <button type="button" class="ip-style-btn" data-style="thin">Thin</button>
                    <button type="button" class="ip-style-btn" data-style="brands">Brands</button>
                </div>
                <span class="ip-count" id="ipCount"></span>
            </div>
            <div class="ip-grid" id="ipGrid"></div>
            <div class="ip-footer">
                <div class="ip-footer__sel" id="ipSelected"><span>No icon selected</span></div>
                <div class="ip-footer__actions">
                    <button type="button" class="ip-btn ip-btn--danger" id="ipRemoveBtn" style="display:none;" onclick="ipRemove()">Remove icon</button>
                    <button type="button" class="ip-btn ip-btn--ghost" onclick="ipClose()">Cancel</button>
                    <button type="button" class="ip-btn ip-btn--primary" onclick="ipConfirm()">Select</button>
                </div>
            </div>
        </div>
    </div>

    <script>
    (function() {
        
        document.getElementById('topbar-add-link').addEventListener('click', function() {
            var row = document.createElement('div');
            row.className = 'tb-link-row';
            row.dataset.icon = '';
            row.innerHTML = '<button type="button" class="tb-icon-btn" onclick="openIconPicker(this.closest(\'.tb-link-row\'))"><i class="fa-solid fa-circle-plus" style="font-size:15px;"></i></button>'
                + '<input type="hidden" name="topbar_link_icon[]" class="tb-icon-val" value="">'
                + '<input type="text" name="topbar_link_text[]" placeholder="Label" class="flex-1 px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-primary-500 focus:border-primary-500 outline-none">'
                + '<input type="url" name="topbar_link_url[]" placeholder="https://..." class="flex-1 px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-primary-500 focus:border-primary-500 outline-none">'
                + '<button type="button" onclick="this.closest(\'.tb-link-row\').remove();tbUpdatePreview();" class="p-2 text-gray-400 hover:text-red-500 transition-colors flex-shrink-0" title="Remove"><i class="fa-solid fa-xmark"></i></button>';
            document.getElementById('topbar-links').appendChild(row);
        });

        
        function hexToRgb(hex) {
            var h = hex.replace('#','');
            if (h.length === 3) h = h[0]+h[0]+h[1]+h[1]+h[2]+h[2];
            return [parseInt(h.substr(0,2),16), parseInt(h.substr(2,2),16), parseInt(h.substr(4,2),16)];
        }
        function rgbToHex(r, g, b) {
            return '#' + ((1<<24)+(r<<16)+(g<<8)+b).toString(16).slice(1);
        }
        function hexToRgba(hex, alpha) {
            var c = hexToRgb(hex);
            return 'rgba('+c[0]+','+c[1]+','+c[2]+','+alpha+')';
        }
        function hsvToRgb(h, s, v) {
            var i = Math.floor(h/60)%6, f = h/60-Math.floor(h/60);
            var p = v*(1-s), q = v*(1-f*s), t = v*(1-(1-f)*s);
            var r, g, b;
            switch(i) {
                case 0: r=v;g=t;b=p;break; case 1: r=q;g=v;b=p;break;
                case 2: r=p;g=v;b=t;break; case 3: r=p;g=q;b=v;break;
                case 4: r=t;g=p;b=v;break; default: r=v;g=p;b=q;
            }
            return [Math.round(r*255), Math.round(g*255), Math.round(b*255)];
        }
        function rgbToHsv(r, g, b) {
            r/=255; g/=255; b/=255;
            var mx = Math.max(r,g,b), mn = Math.min(r,g,b), d = mx-mn;
            var h = 0, s = mx === 0 ? 0 : d/mx, v = mx;
            if (d !== 0) {
                if (mx === r) h = ((g-b)/d + 6) % 6;
                else if (mx === g) h = (b-r)/d + 2;
                else h = (r-g)/d + 4;
                h *= 60;
            }
            return [h, s, v];
        }

        
        var pk = { which: null, h: 0, s: 0, v: 1, alpha: 100, dragging: false };
        var pkEl = document.getElementById('tbPicker');
        var pkCanvas = document.getElementById('pkSvCanvas');
        var pkCtx = pkCanvas.getContext('2d');
        var pkCursor = document.getElementById('pkSvCursor');
        var pkHueSlider = document.getElementById('pkHue');
        var pkAlphaSlider = document.getElementById('pkAlpha');
        var pkAlphaFill = document.getElementById('pkAlphaFill');
        var pkAlphaVal = document.getElementById('pkAlphaVal');
        var pkHexIn = document.getElementById('pkHexInput');

        function pkDrawSV() {
            var w = pkCanvas.width, h = pkCanvas.height;
            var rgb = hsvToRgb(pk.h, 1, 1);
            var hueColor = 'rgb('+rgb[0]+','+rgb[1]+','+rgb[2]+')';
            pkCtx.fillStyle = hueColor;
            pkCtx.fillRect(0, 0, w, h);
            var wGrad = pkCtx.createLinearGradient(0, 0, w, 0);
            wGrad.addColorStop(0, 'rgba(255,255,255,1)');
            wGrad.addColorStop(1, 'rgba(255,255,255,0)');
            pkCtx.fillStyle = wGrad;
            pkCtx.fillRect(0, 0, w, h);
            var bGrad = pkCtx.createLinearGradient(0, 0, 0, h);
            bGrad.addColorStop(0, 'rgba(0,0,0,0)');
            bGrad.addColorStop(1, 'rgba(0,0,0,1)');
            pkCtx.fillStyle = bGrad;
            pkCtx.fillRect(0, 0, w, h);
        }

        function pkPositionCursor() {
            pkCursor.style.left = (pk.s * 100) + '%';
            pkCursor.style.top = ((1 - pk.v) * 100) + '%';
        }

        function pkSVPick(e) {
            var rect = pkCanvas.getBoundingClientRect();
            var clientX = e.touches ? e.touches[0].clientX : e.clientX;
            var clientY = e.touches ? e.touches[0].clientY : e.clientY;
            var x = Math.max(0, Math.min(1, (clientX - rect.left) / rect.width));
            var y = Math.max(0, Math.min(1, (clientY - rect.top) / rect.height));
            pk.s = x;
            pk.v = 1 - y;
            pkPositionCursor();
            pkSync();
        }

        function pkSync() {
            if (!pk.which) return;
            var rgb = hsvToRgb(pk.h, pk.s, pk.v);
            var hex = rgbToHex(rgb[0], rgb[1], rgb[2]);
            
            document.getElementById('tb_' + pk.which + '_hex').value = hex;
            document.getElementById('tb_' + pk.which + '_opacity').value = pk.alpha;
            
            pkHexIn.value = hex;
            pkAlphaSlider.value = pk.alpha;
            pkAlphaVal.textContent = pk.alpha + '%';
            
            pkAlphaFill.style.background = 'linear-gradient(to right, rgba('+rgb[0]+','+rgb[1]+','+rgb[2]+',0), rgb('+rgb[0]+','+rgb[1]+','+rgb[2]+'))';
            
            document.getElementById('tb_' + pk.which + '_opacity_val').textContent = pk.alpha + '%';
            
            pkUpdateSwatch(pk.which);
            tbUpdatePreview();
        }

        function pkUpdateSwatch(which) {
            var hex = document.getElementById('tb_' + which + '_hex').value;
            var op = document.getElementById('tb_' + which + '_opacity').value;
            var swatch = document.getElementById('tb_' + which + '_swatch');
            var fill = swatch.querySelector('.tb-swatch-fill');
            if (hex) {
                var c = hexToRgb(hex);
                fill.style.background = 'rgba('+c[0]+','+c[1]+','+c[2]+','+(op/100)+')';
            } else {
                var defaults = {bg:'#1a1a2e',text:'#ffffff',hover_text:'',dark_bg:'#1e293b',dark_text:'#e2e8f0',dark_hover_text:''};
                fill.style.background = defaults[which] || 'transparent';
            }
        }

        window.pkOpen = function(which, anchorEl) {
            
            if (pk.which === which && pkEl.classList.contains('open')) { pkClose(); return; }
            pk.which = which;
            
            var pkDefaults = { bg:'#1a1a2e', text:'#ffffff', hover_text:'#ffffff', dark_bg:'#1e293b', dark_text:'#e2e8f0', dark_hover_text:'#818cf8' };
            var hex = document.getElementById('tb_' + which + '_hex').value || pkDefaults[which] || '#ffffff';
            pk.alpha = parseInt(document.getElementById('tb_' + which + '_opacity').value) || 100;
            var rgb = hexToRgb(hex);
            var hsv = rgbToHsv(rgb[0], rgb[1], rgb[2]);
            pk.h = hsv[0]; pk.s = hsv[1]; pk.v = hsv[2];
            
            var block = document.getElementById('tb_' + which + '_block');
            if (pkEl.parentNode !== block) block.appendChild(pkEl);
            
            pkHueSlider.value = Math.round(pk.h);
            pkAlphaSlider.value = pk.alpha;
            pkAlphaVal.textContent = pk.alpha + '%';
            pkHexIn.value = hex;
            
            pkDrawSV();
            pkPositionCursor();
            var rgbCur = hsvToRgb(pk.h, pk.s, pk.v);
            pkAlphaFill.style.background = 'linear-gradient(to right, rgba('+rgbCur[0]+','+rgbCur[1]+','+rgbCur[2]+',0), rgb('+rgbCur[0]+','+rgbCur[1]+','+rgbCur[2]+'))';
            pkEl.classList.add('open');
        };

        function pkClose() {
            pkEl.classList.remove('open');
            pk.which = null;
        }

        
        pkCanvas.addEventListener('mousedown', function(e) { e.preventDefault(); pk.dragging = true; pkSVPick(e); });
        document.addEventListener('mousemove', function(e) { if (pk.dragging) pkSVPick(e); });
        document.addEventListener('mouseup', function() { pk.dragging = false; });
        pkCanvas.addEventListener('touchstart', function(e) { e.preventDefault(); pk.dragging = true; pkSVPick(e); }, {passive:false});
        document.addEventListener('touchmove', function(e) { if (pk.dragging) pkSVPick(e); });
        document.addEventListener('touchend', function() { pk.dragging = false; });

        
        pkHueSlider.addEventListener('input', function() {
            pk.h = parseInt(this.value);
            pkDrawSV();
            pkSync();
        });

        
        pkAlphaSlider.addEventListener('input', function() {
            pk.alpha = parseInt(this.value);
            pkSync();
        });

        
        pkHexIn.addEventListener('input', function() {
            var val = this.value.trim();
            if (!val.startsWith('#')) val = '#' + val;
            if (val.match(/^#[0-9a-fA-F]{6}$/)) {
                var rgb = hexToRgb(val);
                var hsv = rgbToHsv(rgb[0], rgb[1], rgb[2]);
                pk.h = hsv[0]; pk.s = hsv[1]; pk.v = hsv[2];
                pkHueSlider.value = Math.round(pk.h);
                pkDrawSV();
                pkPositionCursor();
                pkSync();
            }
        });

        
        document.addEventListener('mousedown', function(e) {
            if (!pkEl.classList.contains('open')) return;
            if (pkEl.contains(e.target)) return;
            
            if (e.target.closest('.tb-color-swatch')) return;
            pkClose();
        });
        document.addEventListener('keydown', function(e) {
            if (e.key === 'Escape' && pkEl.classList.contains('open')) pkClose();
        });

        
        window.pkReset = function(which) {
            document.getElementById('tb_' + which + '_hex').value = '';
            document.getElementById('tb_' + which + '_opacity').value = 100;
            document.getElementById('tb_' + which + '_opacity_val').textContent = '100%';
            pkUpdateSwatch(which);
            if (pk.which === which) pkClose();
            tbUpdatePreview();
        };

        window.pkHexInput = function(which) {
            var hex = document.getElementById('tb_' + which + '_hex').value;
            if (hex.match(/^#[0-9a-fA-F]{6}$/)) {
                pkUpdateSwatch(which);
                if (pk.which === which && pkEl.classList.contains('open')) {
                    var rgb = hexToRgb(hex);
                    var hsv = rgbToHsv(rgb[0], rgb[1], rgb[2]);
                    pk.h = hsv[0]; pk.s = hsv[1]; pk.v = hsv[2];
                    pkHueSlider.value = Math.round(pk.h);
                    pkHexIn.value = hex;
                    pkDrawSV();
                    pkPositionCursor();
                }
            }
            tbUpdatePreview();
        };

        
        var activeThemeMode = 'light';

        window.tbUpdatePreview = function() {
            var preview = document.getElementById('tb-preview');
            var previewHover = document.getElementById('tb-preview-hover');
            
            var pre = activeThemeMode === 'dark' ? 'dark_' : '';
            var defBg = activeThemeMode === 'dark' ? '#1e293b' : '#1a1a2e';
            var defTxt = activeThemeMode === 'dark' ? '#e2e8f0' : '#ffffff';
            var bgHex = document.getElementById('tb_' + pre + 'bg_hex').value || defBg;
            var bgOp = document.getElementById('tb_' + pre + 'bg_opacity').value / 100;
            var txtHex = document.getElementById('tb_' + pre + 'text_hex').value || defTxt;
            var txtOp = document.getElementById('tb_' + pre + 'text_opacity').value / 100;
            preview.style.background = hexToRgba(bgHex, bgOp);
            preview.style.color = hexToRgba(txtHex, txtOp);
            
            var txtBold = document.getElementById('simply_topbar_text_bold').value === '1';
            var txtItalic = document.getElementById('simply_topbar_text_italic').value === '1';
            var lnkBold = document.getElementById('simply_topbar_link_bold').value === '1';
            var lnkItalic = document.getElementById('simply_topbar_link_italic').value === '1';
            var lnkUnderline = document.getElementById('simply_topbar_link_underline').value === '1';
            var txtStyle = (txtBold ? 'font-weight:bold;' : '') + (txtItalic ? 'font-style:italic;' : '');
            var lnkStyle = 'color:inherit;opacity:.85;' + (lnkBold ? 'font-weight:bold;' : '') + (lnkItalic ? 'font-style:italic;' : '') + 'text-decoration:' + (lnkUnderline ? 'underline' : 'none') + ';';
            
            var parts = [];
            var tbTextEl = document.getElementById('simply_topbar_text');
            var tbText = tbTextEl ? tbTextEl.value.trim() : '';
            if (tbText) parts.push('<span style="' + txtStyle + '">' + tbText.replace(/</g,'&lt;') + '</span>');
            document.querySelectorAll('#topbar-links .tb-link-row').forEach(function(row) {
                var label = row.querySelector('input[name="topbar_link_text[]"]').value.trim();
                if (!label) return;
                var icon = row.dataset.icon || (row.querySelector('.tb-icon-val') ? row.querySelector('.tb-icon-val').value : '');
                var html = '';
                if (icon) html += '<i class="fa-solid fa-' + icon.replace(/</g,'&lt;') + '" style="font-size:11px;opacity:.85;"></i> ';
                html += label.replace(/</g,'&lt;');
                parts.push('<a href="#" onclick="return false" style="' + lnkStyle + '">' + html + '</a>');
            });
            var modeLabel = activeThemeMode === 'dark' ? 'Dark' : 'Light';
            preview.innerHTML = parts.length ? '<span style="font-size:10px;opacity:.5;margin-right:6px;">' + modeLabel + '</span>' + parts.join(' <span style="opacity:.4;margin:0 4px;">&middot;</span> ') : '<span style="opacity:.5;font-style:italic;">Configure text or links to see a preview</span>';
            
            var hTxtHex = document.getElementById('tb_' + pre + 'hover_text_hex').value || txtHex;
            var hTxtOp = document.getElementById('tb_' + pre + 'hover_text_opacity').value / 100;
            previewHover.style.background = hexToRgba(bgHex, bgOp);
            previewHover.style.color = hexToRgba(hTxtHex, hTxtOp);
            var hParts = [];
            if (tbText) hParts.push('<span style="' + txtStyle + '">' + tbText.replace(/</g,'&lt;') + '</span>');
            document.querySelectorAll('#topbar-links .tb-link-row').forEach(function(row) {
                var label = row.querySelector('input[name="topbar_link_text[]"]').value.trim();
                if (!label) return;
                var icon = row.dataset.icon || (row.querySelector('.tb-icon-val') ? row.querySelector('.tb-icon-val').value : '');
                var html = '';
                if (icon) html += '<i class="fa-solid fa-' + icon.replace(/</g,'&lt;') + '" style="font-size:11px;opacity:.85;"></i> ';
                html += label.replace(/</g,'&lt;');
                var hLnkStyle = 'color:inherit;' + (lnkBold ? 'font-weight:bold;' : '') + (lnkItalic ? 'font-style:italic;' : '') + 'text-decoration:' + (lnkUnderline ? 'underline' : 'none') + ';';
                hParts.push('<a href="#" onclick="return false" style="' + hLnkStyle + '">' + html + '</a>');
            });
            previewHover.innerHTML = '<span style="font-size:10px;opacity:.5;margin-right:6px;">' + modeLabel + ' hover</span>' + (hParts.length ? hParts.join(' <span style="opacity:.4;margin:0 4px;">&middot;</span> ') : '<span style="opacity:.5;font-style:italic;">…</span>');
        };

        
        window.tbFmtToggle = function(btn, inputName) {
            btn.classList.toggle('active');
            document.getElementById(inputName).value = btn.classList.contains('active') ? '1' : '0';
            tbUpdatePreview();
        };

        
        var tbTextInput = document.getElementById('simply_topbar_text');
        if (tbTextInput) tbTextInput.addEventListener('input', tbUpdatePreview);
        document.getElementById('topbar-links').addEventListener('input', tbUpdatePreview);

        
        window.tbSwitchThemeMode = function(mode) {
            var tabs = document.querySelectorAll('.tb-theme-tab');
            var targetTab = mode === 'dark' ? tabs[1] : tabs[0];
            if (targetTab && targetTab.classList.contains('tb-theme-tab--disabled')) return;
            activeThemeMode = mode;
            tabs.forEach(function(t) { t.classList.remove('active'); });
            document.querySelectorAll('.tb-theme-pane').forEach(function(p) { p.classList.remove('active'); });
            if (mode === 'dark') {
                tabs[1].classList.add('active');
                document.getElementById('tbThemeDark').classList.add('active');
            } else {
                tabs[0].classList.add('active');
                document.getElementById('tbThemeLight').classList.add('active');
            }
            
            if (pkEl.classList.contains('open')) pkClose();
            tbUpdatePreview();
        };

        
        ['bg','text','hover_text','dark_bg','dark_text','dark_hover_text'].forEach(function(w) { pkUpdateSwatch(w); });
        tbUpdatePreview();

        
        var ipOverlay = document.getElementById('iconPicker');
        var ipGrid = document.getElementById('ipGrid');
        var ipSearch = document.getElementById('ipSearch');
        var ipSelDisplay = document.getElementById('ipSelected');
        var ipRemoveBtn = document.getElementById('ipRemoveBtn');
        var ipCountEl = document.getElementById('ipCount');
        var ipAllIcons = [], ipStyle = 'solid', ipCurrentIcon = '', ipTarget = null, ipLoaded = false;

        function ipLoad(cb) {
            if (ipLoaded) return cb();
            fetch('/assets/fontawesomepro/icons.json').then(function(r) { return r.json(); }).then(function(data) {
                ipAllIcons = data; ipLoaded = true; cb();
            });
        }

        window.openIconPicker = function(rowEl) {
            ipTarget = rowEl;
            var val = rowEl.querySelector('.tb-icon-val');
            ipCurrentIcon = val ? val.value : '';
            ipLoad(function() {
                ipSearch.value = '';
                ipFilter();
                ipUpdateSel();
                ipOverlay.classList.add('open');
                setTimeout(function() { ipSearch.focus(); }, 100);
            });
        };

        window.ipClose = function() {
            ipOverlay.classList.remove('open');
            ipTarget = null;
        };

        window.ipConfirm = function() {
            if (ipTarget) {
                var val = ipTarget.querySelector('.tb-icon-val');
                var btn = ipTarget.querySelector('.tb-icon-btn');
                if (val) val.value = ipCurrentIcon;
                ipTarget.dataset.icon = ipCurrentIcon;
                if (btn) {
                    if (ipCurrentIcon) {
                        btn.className = 'tb-icon-btn has-icon';
                        btn.innerHTML = '<i class="fa-solid fa-' + ipCurrentIcon + '"></i>';
                    } else {
                        btn.className = 'tb-icon-btn';
                        btn.innerHTML = '<i class="fa-solid fa-circle-plus" style="font-size:15px;"></i>';
                    }
                }
                tbUpdatePreview();
            }
            ipClose();
        };

        window.ipRemove = function() {
            ipCurrentIcon = '';
            ipUpdateSel();
            ipGrid.querySelectorAll('.ip-icon.selected').forEach(function(x) { x.classList.remove('selected'); });
        };

        function ipUpdateSel() {
            if (ipCurrentIcon) {
                ipSelDisplay.innerHTML = '<i class="fa-solid fa-' + ipCurrentIcon + '"></i> <span>fa-' + ipCurrentIcon + '</span>';
                ipRemoveBtn.style.display = '';
            } else {
                ipSelDisplay.innerHTML = '<span style="color:#9ca3af;">No icon selected</span>';
                ipRemoveBtn.style.display = 'none';
            }
        }

        function ipFilter() {
            var q = ipSearch.value.trim().toLowerCase();
            var filtered = ipAllIcons.filter(function(ic) {
                if (ipStyle === 'brands') return ic.b && ic.n.indexOf(q) !== -1;
                if (ic.b) return false;
                return ic.n.indexOf(q) !== -1;
            });
            ipCountEl.textContent = filtered.length + ' icons';
            if (!filtered.length) {
                ipGrid.innerHTML = '<div class="ip-empty"><i class="fa-solid fa-face-meh" style="font-size:24px;opacity:.3;margin-bottom:8px;display:block;"></i>No icons found</div>';
                return;
            }
            var faPrefix = ipStyle === 'brands' ? 'fa-brands' : 'fa-' + ipStyle;
            var frag = document.createDocumentFragment();
            for (var i = 0; i < filtered.length; i++) {
                var n = filtered[i].n;
                var div = document.createElement('div');
                div.className = 'ip-icon' + (n === ipCurrentIcon ? ' selected' : '');
                div.dataset.name = n;
                div.title = n;
                var ic = document.createElement('i');
                ic.className = faPrefix + ' fa-' + n;
                div.appendChild(ic);
                frag.appendChild(div);
            }
            ipGrid.innerHTML = '';
            ipGrid.appendChild(frag);
            if (ipCurrentIcon) {
                var sel = ipGrid.querySelector('.ip-icon.selected');
                if (sel) setTimeout(function() { sel.scrollIntoView({ block: 'center', behavior: 'instant' }); }, 50);
            }
        }

        ipGrid.addEventListener('click', function(e) {
            var icon = e.target.closest('.ip-icon');
            if (!icon) return;
            ipGrid.querySelectorAll('.ip-icon.selected').forEach(function(x) { x.classList.remove('selected'); });
            icon.classList.add('selected');
            ipCurrentIcon = icon.dataset.name;
            ipUpdateSel();
        });

        ipSearch.addEventListener('input', function() { ipFilter(); });

        document.getElementById('ipStyles').addEventListener('click', function(e) {
            var btn = e.target.closest('.ip-style-btn');
            if (!btn) return;
            document.querySelectorAll('.ip-style-btn').forEach(function(b) { b.classList.remove('active'); });
            btn.classList.add('active');
            ipStyle = btn.dataset.style;
            ipFilter();
        });

        ipOverlay.addEventListener('click', function(e) { if (e.target === ipOverlay) ipClose(); });
        document.addEventListener('keydown', function(e) { if (e.key === 'Escape' && ipOverlay.classList.contains('open')) ipClose(); });

        
        
        var dmEnabled = <?= $darkModeEnabled ? 'true' : 'false' ?>;
        var dmServerDefault = <?= json_encode($darkModeDefault) ?>;
        var dmToggle = { checked: dmEnabled };
        var dmNote = document.getElementById('dmNote');
        var dmNoteText = document.getElementById('dmNoteText');
        var dmLabel = { textContent: '' };

        function dmUpdateState() {
            var enabled = dmToggle.checked;
            var defRadio = document.querySelector('input[name="simply_dark_mode_default"]:checked');
            var def = defRadio ? defRadio.value : dmServerDefault;
            var tabs = document.querySelectorAll('.tb-theme-tab');
            var lightTab = tabs[0];
            var darkTab = tabs[1];

            if (enabled) {
                dmNote.style.display = 'none';
                dmLabel.textContent = 'Default:';
                lightTab.classList.remove('tb-theme-tab--disabled');
                darkTab.classList.remove('tb-theme-tab--disabled');
            } else {
                var themeName = def === 'dark' ? 'Dark' : 'Light';
                var unusedName = def === 'dark' ? 'Light' : 'Dark';
                dmNoteText.textContent = 'User toggle is off \u2014 site will always use the ' + themeName + ' theme. ' + unusedName + ' topbar colors are disabled.';
                dmNote.style.display = '';
                dmLabel.textContent = 'Theme:';

                if (def === 'light') {
                    lightTab.classList.remove('tb-theme-tab--disabled');
                    darkTab.classList.add('tb-theme-tab--disabled');
                    if (activeThemeMode === 'dark') tbSwitchThemeMode('light');
                } else {
                    darkTab.classList.remove('tb-theme-tab--disabled');
                    lightTab.classList.add('tb-theme-tab--disabled');
                    if (activeThemeMode === 'light') tbSwitchThemeMode('dark');
                }
            }
        }

        dmUpdateState();
    })();
    </script>
    <?php
    simplyTranslateModalAssets();
});

 
HookSystem::addAction('admin.appearance_save.header', function (): void {
     
    Setting::set('simply_topbar_enabled', isset($_POST['simply_topbar_enabled']) ? '1' : '0');

    $texts = $_POST['topbar_link_text'] ?? [];
    $urls  = $_POST['topbar_link_url'] ?? [];
    $icons = $_POST['topbar_link_icon'] ?? [];
    $textTranslations = $_POST['topbar_link_text_translations'] ?? [];
    $links = [];
    foreach ($texts as $i => $t) {
        $t = trim($t);
        $u = trim($urls[$i] ?? '');
        if ($t !== '' && $u !== '') {
            $link = ['text' => $t, 'url' => $u, 'icon' => trim($icons[$i] ?? '')];
             
            $tl = array_filter(array_map('trim', $textTranslations[$i] ?? []), fn($v) => $v !== '');
            if (!empty($tl)) {
                $link['_translations'] = ['text' => $tl];
            }
            $links[] = $link;
        }
    }
    Setting::set('simply_topbar_links', json_encode($links));

     
    $colorKeys = [
        'simply_topbar_bg_color', 'simply_topbar_text_color', 'simply_topbar_hover_text_color',
        'simply_topbar_dark_bg_color', 'simply_topbar_dark_text_color', 'simply_topbar_dark_hover_text_color',
    ];
    foreach ($colorKeys as $ck) {
        $val = trim($_POST[$ck] ?? '');
        if ($val !== '' && !preg_match('/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/', $val)) {
            $val = '';
        }
        Setting::set($ck, $val);
    }
     
    $opacityKeys = [
        'simply_topbar_bg_opacity', 'simply_topbar_text_opacity', 'simply_topbar_hover_text_opacity',
        'simply_topbar_dark_bg_opacity', 'simply_topbar_dark_text_opacity', 'simply_topbar_dark_hover_text_opacity',
    ];
    foreach ($opacityKeys as $ok) {
        $val = (int) ($_POST[$ok] ?? 100);
        Setting::set($ok, (string) max(0, min(100, $val)));
    }
     
    foreach (['simply_topbar_text_bold', 'simply_topbar_text_italic', 'simply_topbar_link_bold', 'simply_topbar_link_italic', 'simply_topbar_link_underline'] as $fk) {
        Setting::set($fk, ($_POST[$fk] ?? '0') === '1' ? '1' : '0');
    }
    Setting::set('simply_topbar_link_hover_underline', isset($_POST['simply_topbar_link_hover_underline']) ? '1' : '0');
});

 

function simplyCategoryCard(array $cat): string
{
    $name = htmlspecialchars($cat['name']);
    $href = url('/category/' . htmlspecialchars($cat['slug']));
    $vc = (int)($cat['video_count'] ?? 0);
    $count = $vc !== 1 ? __('video_count_plural', [':count' => Format::number($vc)]) : __('video_count', [':count' => Format::number($vc)]);
    $dataName = htmlspecialchars(mb_strtolower($cat['name']));

    $catThumbUrl = '';
    if (!empty($cat['thumbnail'])) {
        $catThumbUrl = (str_starts_with($cat['thumbnail'], 'http') ? $cat['thumbnail'] : '/uploads/thumbnails/' . $cat['thumbnail']);
    } elseif (!empty($cat['best_video_folder'])) {
        $catThumbUrl = VideoAsset::thumbUrlFromFolder($cat['best_video_folder'], false, $cat['best_video_storage_id'] ?? null);
    }
    $initial = strtoupper(mb_substr($cat['name'], 0, 1));
    $imgHtml = $catThumbUrl !== ''
        ? '<img src="' . htmlspecialchars($catThumbUrl) . '" alt="' . $name . '" loading="lazy">'
        : '<div class="category-card__placeholder">' . $initial . '</div>';

    return '<a href="' . $href . '" class="category-card" data-name="' . $dataName . '">'
        . $imgHtml
        . '<span class="category-card__count">' . $count . '</span>'
        . '<span class="category-card__name">' . $name . '</span>'
        . '</a>';
}

function simplyAlbumCard(array $album): string
{
    $title = htmlspecialchars($album['title'] ?? '');
    $href = url('/album/' . htmlspecialchars($album['slug'] ?? ''));
    $count = (int)($album['image_count'] ?? 0);
    $dataName = htmlspecialchars(mb_strtolower($album['title'] ?? ''));
    $cover = AlbumAsset::coverUrl($album);
    $imgHtml = $cover !== ''
        ? '<img src="' . htmlspecialchars($cover) . '" alt="' . $title . '" loading="lazy" onerror="this.style.display=\'none\'">'
        : '<div class="album-card__placeholder"><i class="fa-light fa-images"></i></div>';

     
    static $albCardOpt = null;
    if ($albCardOpt === null) {
        $albCardOpt = [
            'count' => Setting::get('album_card_show_count', '1') === '1',
            'title' => Setting::get('album_card_show_title', '1') === '1',
            'views' => Setting::get('album_card_show_views', '0') === '1',
            'date'  => Setting::get('album_card_show_date', '0') === '1',
        ];
    }
    $countHtml = $albCardOpt['count']
        ? '<span class="album-card__count"><i class="fa-solid fa-images"></i> ' . Format::number($count) . '</span>'
        : '';
    $info = '';
    $showMeta = $albCardOpt['views'] || $albCardOpt['date'];
    if ($albCardOpt['title'] || $showMeta) {
        $info = '<div class="album-card__info">';
        if ($albCardOpt['title']) {
            $info .= '<h3 class="album-card__title">' . $title . '</h3>';
        }
        if ($showMeta) {
            $info .= '<div class="album-card__meta">';
            if ($albCardOpt['views']) {
                $info .= '<span class="album-card__meta-i"><i class="fa-light fa-eye"></i> ' . Format::number((int)($album['views'] ?? 0)) . '</span>';
            }
            if ($albCardOpt['date']) {
                $dt = $album['published_at'] ?? ($album['created_at'] ?? '');
                if ($dt) {
                    $info .= '<span class="album-card__meta-i">' . htmlspecialchars(Format::timeAgo($dt)) . '</span>';
                }
            }
            $info .= '</div>';
        }
        $info .= '</div>';
    }
    return '<a href="' . $href . '" class="album-card" data-album-id="' . (int) ($album['id'] ?? 0) . '" data-name="' . $dataName . '">'
        . '<div class="album-card__thumb">' . $imgHtml . $countHtml . '</div>'
        . $info
        . '</a>';
}

function simplyPerformerCard(array $perf): string
{
    $name = htmlspecialchars(mb_ucfirst($perf['name']));
    $href = url('/pornstar/' . htmlspecialchars($perf['slug']));
    $vc = (int)($perf['video_count'] ?? 0);
    $count = $vc !== 1 ? __('video_count_plural', [':count' => Format::number($vc)]) : __('video_count', [':count' => Format::number($vc)]);
    $views = Format::number((int)($perf['total_views'] ?? 0)) . ' ' . __('views');
    $dataName = htmlspecialchars(mb_strtolower($perf['name']));
    $initial = strtoupper(mb_substr($name, 0, 1));

    $perfThumbUrl = '';
    if (!empty($perf['photo'])) {
        $perfThumbUrl = (str_starts_with($perf['photo'], 'http') ? $perf['photo'] : '/uploads/performers/' . $perf['photo']);
    } elseif (!empty($perf['best_video_folder'])) {
        $perfThumbUrl = VideoAsset::thumbUrlFromFolder($perf['best_video_folder'], false, $perf['best_video_storage_id'] ?? null);
    }

    $imgHtml = $perfThumbUrl !== ''
        ? '<img src="' . htmlspecialchars($perfThumbUrl) . '" alt="' . $name . '" class="performer-card__photo" loading="lazy">'
        : '<div class="performer-card__photo--placeholder">' . $initial . '</div>';

    return '<a href="' . $href . '" class="performer-card" data-name="' . $dataName . '">'
        . $imgHtml
        . '<div class="performer-card__overlay"></div>'
        . '<div class="performer-card__info">'
        . '<span class="performer-card__name">' . $name . '</span>'
        . '<span class="performer-card__videos">' . $count . '</span>'
        . '<span class="performer-card__views">' . $views . '</span>'
        . '</div></a>';
}

function simplyChannelCard(array $channel): string
{
    $name = htmlspecialchars(mb_ucfirst($channel['name']));
    $href = url('/channel/' . htmlspecialchars($channel['slug']));
    $vc = (int)($channel['video_count'] ?? 0);
    $count = $vc !== 1 ? __('video_count_plural', [':count' => Format::number($vc)]) : __('video_count', [':count' => Format::number($vc)]);
    $views = Format::number((int)($channel['total_views'] ?? 0)) . ' ' . __('views');
    $dataName = htmlspecialchars(mb_strtolower($channel['name']));
    $initial = strtoupper(mb_substr($name, 0, 1));

    $channelThumbUrl = '';
    if (!empty($channel['logo'])) {
        $channelThumbUrl = (str_starts_with($channel['logo'], 'http') ? $channel['logo'] : '/uploads/channels/' . $channel['logo']);
    } elseif (!empty($channel['best_video_folder'])) {
        $channelThumbUrl = VideoAsset::thumbUrlFromFolder($channel['best_video_folder'], false, $channel['best_video_storage_id'] ?? null);
    }

    $imgHtml = $channelThumbUrl !== ''
        ? '<img src="' . htmlspecialchars($channelThumbUrl) . '" alt="' . $name . '" class="channel-card__photo" loading="lazy">'
        : '<div class="channel-card__photo--placeholder">' . $initial . '</div>';

    return '<a href="' . $href . '" class="channel-card" data-name="' . $dataName . '">'
        . $imgHtml
        . '<div class="channel-card__overlay"></div>'
        . '<div class="channel-card__info">'
        . '<span class="channel-card__name">' . $name . '</span>'
        . '<span class="channel-card__videos">' . $count . '</span>'
        . '<span class="channel-card__views">' . $views . '</span>'
        . '</div></a>';
}





function simplyAlbumGridClass(): string
{
    return Setting::get('albums_display_mode', 'grid') === 'masonry' ? ' is-masonry' : '';
}

function simplyAlbumSidebar(string $activeType = '', string $currentType = '', string $currentSlug = ''): string
{
    static $cache = [];
    if (!isset($cache[$activeType])) {
        $cache[$activeType] = [
            'categories' => AlbumCategory::all(14, 0, 'popularity', $activeType, true),
            'channels'   => AlbumChannel::all(10, 0, 'popularity', $activeType, true),
            'performers' => AlbumPerformer::all(10, 0, 'popularity', $activeType, true),
            'tags'       => AlbumTag::all(24, 0, 'popularity', $activeType, true),
        ];
    }
    $d = $cache[$activeType];
     
     
    foreach (['categories', 'channels', 'performers', 'tags'] as $__albSk) {
        if (Setting::get('albums_sidebar_' . $__albSk, '1') !== '1') { $d[$__albSk] = []; }
    }
    $albDefView = Setting::get('albums_display_mode', 'grid') === 'masonry' ? 'masonry' : 'grid';
    $albDefNav  = Setting::get('albums_nav_mode', 'pages') === 'infinite' ? 'infinite' : 'pages';
    $sections = [
        ['categories', __('categories'), 'fa-folder', '/album-category/'],
        ['channels',   __('channels'),   'fa-tv',     '/album-channel/'],
        ['performers', __('pornstars'),  'fa-star',   '/album-pornstar/'],
    ];
    ob_start(); ?>
<aside class="album-side album-side--listing">
    <div class="album-panel">
        <div class="album-panel__head"><i class="fa-solid fa-sliders"></i> <?php echo __('album_display'); ?></div>
        <div class="alb-disp">
            <div class="alb-disp__label"><?php echo __('album_view_mode'); ?></div>
            <div class="alb-toggle">
                <button type="button" class="alb-toggle__btn<?php echo $albDefView === 'grid' ? ' active' : ''; ?>" data-view="grid" onclick="albSetView('grid')"><i class="fa-solid fa-table-cells"></i> <?php echo __('album_grid'); ?></button>
                <button type="button" class="alb-toggle__btn<?php echo $albDefView === 'masonry' ? ' active' : ''; ?>" data-view="masonry" onclick="albSetView('masonry')"><i class="fa-solid fa-table-cells-large"></i> <?php echo __('album_masonry'); ?></button>
            </div>
            <div class="alb-disp__label"><?php echo __('album_navigation'); ?></div>
            <div class="alb-toggle">
                <button type="button" class="alb-toggle__btn<?php echo $albDefNav === 'pages' ? ' active' : ''; ?>" data-nav="pages" onclick="albSetNav('pages')"><i class="fa-solid fa-list-ol"></i> <?php echo __('album_pages'); ?></button>
                <button type="button" class="alb-toggle__btn<?php echo $albDefNav === 'infinite' ? ' active' : ''; ?>" data-nav="infinite" onclick="albSetNav('infinite')"><i class="fa-solid fa-infinity"></i> <?php echo __('album_infinite'); ?></button>
            </div>
        </div>
    </div>
    <?php foreach ($sections as $sec): list($rk, $label, $icon, $base) = $sec; if (empty($d[$rk])) continue; ?>
    <div class="album-panel">
        <div class="album-panel__head"><i class="fa-solid <?php echo $icon; ?>"></i> <?php echo $label; ?></div>
        <div class="album-panel__chips">
            <?php foreach ($d[$rk] as $it): $act = ($currentType === $rk && $currentSlug === ($it['slug'] ?? '')); ?>
            <a href="<?php echo url($base . htmlspecialchars((string) $it['slug'])); ?>" class="tag-link<?php echo $act ? ' tag-link--active' : ''; ?>"><?php echo htmlspecialchars((string) $it['name']); ?></a>
            <?php endforeach; ?>
        </div>
    </div>
    <?php endforeach; ?>
    <?php if (!empty($d['tags'])): ?>
    <div class="album-panel">
        <div class="album-panel__head"><i class="fa-solid fa-hashtag"></i> <?php echo __('tags'); ?></div>
        <div class="album-panel__chips">
            <?php foreach ($d['tags'] as $t): $act = ($currentType === 'tags' && $currentSlug === ($t['slug'] ?? '')); ?>
            <a href="<?php echo url('/album-tag/' . htmlspecialchars((string) $t['slug'])); ?>" class="tag-link<?php echo $act ? ' tag-link--active' : ''; ?>">#<?php echo htmlspecialchars((string) $t['name']); ?></a>
            <?php endforeach; ?>
        </div>
    </div>
    <?php endif; ?>
</aside>
<script>
(function(){
    if(window.__albDisp)return; window.__albDisp=true;
    function init(){
    var grid=document.querySelector('.album-grid'); if(!grid)return;
    function applyView(v){ grid.classList.toggle('is-masonry', v==='masonry'); document.querySelectorAll('.alb-toggle__btn[data-view]').forEach(function(b){ b.classList.toggle('active', b.dataset.view===v); }); }
    window.albSetView=function(v){ try{localStorage.setItem('albView',v);}catch(e){} applyView(v); };
    var sv='<?php echo $albDefView; ?>'; try{ var _sv=localStorage.getItem('albView'); if(_sv)sv=_sv; }catch(e){} applyView(sv);
    var navMode='pages', loading=false, ended=false, observer=null, sentinel=null, loaderEl=null;
    function ensureSentinel(){
        if(sentinel)return;
        loaderEl=document.createElement('div'); loaderEl.className='alb-loader'; loaderEl.innerHTML='<i class="fa-solid fa-spinner fa-spin"></i>';
        sentinel=document.createElement('div'); sentinel.className='alb-sentinel';
        grid.parentNode.insertBefore(loaderEl, grid.nextSibling);
        grid.parentNode.insertBefore(sentinel, loaderEl.nextSibling);
        observer=new IntersectionObserver(function(es){ es.forEach(function(e){ if(e.isIntersecting) loadNext(); }); },{rootMargin:'700px'});
        observer.observe(sentinel);
    }
    function teardown(){ if(observer){observer.disconnect();observer=null;} if(sentinel){sentinel.remove();sentinel=null;} if(loaderEl){loaderEl.remove();loaderEl=null;} }
    function loadNext(){
        if(loading||ended||navMode!=='infinite')return;
        var next=document.querySelector('.pagination a[rel="next"]'); if(!next){ended=true;return;}
        loading=true; if(loaderEl)loaderEl.classList.add('show');
        fetch(next.href).then(function(r){return r.text();}).then(function(html){
            var doc=new DOMParser().parseFromString(html,'text/html');
            var ng=doc.querySelector('.album-grid');
            if(ng){ while(ng.firstElementChild){ grid.appendChild(ng.firstElementChild); } }
            var np=doc.querySelector('.pagination'), cp=document.querySelector('.pagination');
            if(cp){ if(np){ cp.replaceWith(np); } else { cp.remove(); } }
            var cp2=document.querySelector('.pagination'); if(cp2 && navMode==='infinite') cp2.style.display='none';
            if(!document.querySelector('.pagination a[rel="next"]')) ended=true;
            loading=false; if(loaderEl)loaderEl.classList.remove('show');
        }).catch(function(){ loading=false; if(loaderEl)loaderEl.classList.remove('show'); });
    }
    function applyNav(n){
        navMode=n;
        document.querySelectorAll('.alb-toggle__btn[data-nav]').forEach(function(b){ b.classList.toggle('active', b.dataset.nav===n); });
        var p=document.querySelector('.pagination');
        if(n==='infinite'){ if(p)p.style.display='none'; ended=false; ensureSentinel(); }
        else { if(p)p.style.display=''; teardown(); }
    }
    window.albSetNav=function(n){ try{localStorage.setItem('albNav',n);}catch(e){} applyNav(n); };
    var sn='<?php echo $albDefNav; ?>'; try{ var _sn=localStorage.getItem('albNav'); if(_sn)sn=_sn; }catch(e){} applyNav(sn);
    
    var aside=document.querySelector('.album-side--listing');
    if(aside){
        var fab=document.createElement('button'); fab.type='button'; fab.className='alb-filters-btn'; fab.setAttribute('aria-label','Filters');
        fab.innerHTML='<i class="fa-solid fa-sliders"></i> <?php echo __('album_filters'); ?>';
        var bd=document.createElement('div'); bd.className='alb-filters-backdrop';
        var _main=document.querySelector('.album-main');
        if(_main){ _main.insertBefore(fab, _main.firstChild); } else { document.body.appendChild(fab); }
        document.body.appendChild(bd);
        function _openF(){ aside.classList.add('is-open'); bd.classList.add('is-open'); document.body.style.overflow='hidden'; }
        function _closeF(){ aside.classList.remove('is-open'); bd.classList.remove('is-open'); document.body.style.overflow=''; }
        fab.addEventListener('click', _openF);
        bd.addEventListener('click', _closeF);
        aside.addEventListener('click', function(e){ if(e.target.closest('a')) _closeF(); });
    }
    }
    if(document.readyState==='loading'){ document.addEventListener('DOMContentLoaded', init); } else { init(); }
})();
</script>
<?php
    return ob_get_clean();
}



function simplyAlbumBrowseBar(string $activeType = ''): string
{
    static $cache = [];
    if (!isset($cache[$activeType])) {
        $cache[$activeType] = [
            ['key' => 'categories', 'label' => __('categories'), 'icon' => 'fa-folder',  'base' => '/album-category/', 'items' => AlbumCategory::all(0, 0, 'alphabetical', $activeType, true)],
            ['key' => 'tags',       'label' => __('tags'),       'icon' => 'fa-hashtag', 'base' => '/album-tag/',      'items' => AlbumTag::all(0, 0, 'alphabetical', $activeType, true)],
            ['key' => 'performers', 'label' => __('pornstars'),  'icon' => 'fa-star',    'base' => '/album-pornstar/', 'items' => AlbumPerformer::all(0, 0, 'alphabetical', $activeType, true)],
            ['key' => 'channels',   'label' => __('channels'),   'icon' => 'fa-tv',      'base' => '/album-channel/',  'items' => AlbumChannel::all(0, 0, 'alphabetical', $activeType, true)],
        ];
    }
    $groups = $cache[$activeType];
    $groups = array_values(array_filter($groups, static function (array $g): bool {
        return Setting::get('albums_sidebar_' . $g['key'], '1') === '1';
    }));
    $any = false;
    foreach ($groups as $g) { if (!empty($g['items'])) { $any = true; break; } }
    if (!$any) return '';
    ob_start(); ?>
<div class="alb-browse">
    <?php foreach ($groups as $g): if (empty($g['items'])) continue; ?>
    <button type="button" class="alb-browse__btn" onclick="albBrowseOpen('<?php echo $g['key']; ?>')" title="<?php echo __('album_all') . ' ' . $g['label']; ?>"><i class="fa-solid <?php echo $g['icon']; ?>"></i> <span class="alb-browse__lbl"><?php echo __('album_all') . ' ' . $g['label']; ?></span> <span class="alb-browse__n"><?php echo count($g['items']); ?></span></button>
    <?php endforeach; ?>
</div>
<?php foreach ($groups as $g): if (empty($g['items'])) continue; ?>
<div class="alb-browse-modal" id="albBrowse-<?php echo $g['key']; ?>" aria-hidden="true">
    <div class="alb-browse-modal__box">
        <div class="alb-browse-modal__head">
            <h3><i class="fa-solid <?php echo $g['icon']; ?>"></i> <?php echo __('album_all') . ' ' . $g['label']; ?></h3>
            <button type="button" onclick="albBrowseClose()" aria-label="Close"><i class="fa-solid fa-xmark"></i></button>
        </div>
        <input type="text" class="alb-browse-modal__search" placeholder="<?php echo __('search'); ?>" oninput="albBrowseFilter(this)">
        <div class="alb-browse-modal__list">
            <?php
            $byL = [];
            foreach ($g['items'] as $it) { $n = (string) ($it['name'] ?? ''); $L = strtoupper(mb_substr($n, 0, 1)); if (!preg_match('/[A-Z]/', $L)) $L = '#'; $byL[$L][] = $it; }
            ksort($byL);
            foreach ($byL as $L => $items): ?>
            <div class="alb-browse-grp"><span class="alb-browse-grp__l"><?php echo $L; ?></span>
                <div class="alb-browse-grp__items"><?php foreach ($items as $it): ?><a href="<?php echo url($g['base'] . htmlspecialchars((string) $it['slug'])); ?>" class="alb-browse-item" data-n="<?php echo htmlspecialchars(mb_strtolower((string) ($it['name'] ?? ''))); ?>"><?php echo htmlspecialchars((string) ($it['name'] ?? '')); ?> <span><?php echo (int) ($it['album_count'] ?? 0); ?></span></a><?php endforeach; ?></div>
            </div>
            <?php endforeach; ?>
        </div>
    </div>
</div>
<?php endforeach; ?>
<script>
(function(){
    if(window.__albBrowse)return; window.__albBrowse=true;
    window.albBrowseOpen=function(k){ var m=document.getElementById('albBrowse-'+k); if(!m)return; m.classList.add('open'); document.body.style.overflow='hidden'; var s=m.querySelector('.alb-browse-modal__search'); if(s){ s.value=''; albBrowseFilter(s); s.focus(); } };
    window.albBrowseClose=function(){ document.querySelectorAll('.alb-browse-modal.open').forEach(function(m){ m.classList.remove('open'); }); document.body.style.overflow=''; };
    window.albBrowseFilter=function(inp){ var q=inp.value.toLowerCase().trim(); var box=inp.closest('.alb-browse-modal__box'); box.querySelectorAll('.alb-browse-item').forEach(function(a){ a.style.display=(!q||a.dataset.n.indexOf(q)>=0)?'':'none'; }); box.querySelectorAll('.alb-browse-grp').forEach(function(gp){ var vis=Array.prototype.some.call(gp.querySelectorAll('.alb-browse-item'),function(a){return a.style.display!=='none';}); gp.style.display=vis?'':'none'; }); };
    document.querySelectorAll('.alb-browse-modal').forEach(function(m){ m.addEventListener('click',function(e){ if(e.target===m) albBrowseClose(); }); });
    document.addEventListener('keydown',function(e){ if(e.key==='Escape') albBrowseClose(); });
})();
</script>
<?php
    return ob_get_clean();
}
