<!DOCTYPE html>
<html lang="en" data-theme="dark">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="referrer" content="no-referrer">

<!-- ═══════════════════════════════════════════════
     PRIMARY SEO META TAGS
     ═══════════════════════════════════════════════ -->
<title>Ghostddit — Reddit Hidden Profile Viewer | Posts &amp; Comments Finder</title>
<meta name="description" content="Ghostddit finds hidden Reddit posts AND comments. Search any Reddit username to see their hidden posts and full comment history — even if their profile is completely hidden. Free, no login required.">
<meta name="keywords" content=" Ghostddit, Reddit hidden profile finder, Reddit hidden account posts, Reddit hidden comments, see hidden Reddit posts, find Reddit comments by user, Reddit profile hidden posts, Reddit hidden user posts, find hidden Reddit posts, Reddit post finder, hidden Reddit account, view hidden Reddit profile, Reddit deleted posts finder, Reddit post search by user, Reddit hidden profile viewer, Reddit account post lookup, find Reddit posts by user, Reddit search hidden posts, Reddit comment history finder, view Reddit comment history">
<meta name="author" content="u/Aryan_Raj_7167">
<meta name="robots" content="index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1">
<meta name="googlebot" content="index, follow">
<meta name="theme-color" content="#ff4500">
<meta name="application-name" content="Ghostddit">
<meta name="generator" content="Ghostddit">
<link rel="canonical" href="https://ghostddit.pages.dev/">

<!-- ═══════════════════════════════════════════════
     OPEN GRAPH (Facebook, LinkedIn, Discord, etc.)
     ═══════════════════════════════════════════════ -->
<meta property="og:type" content="website">
<meta property="og:site_name" content="Ghostddit">
<meta property="og:title" content="Ghostddit — Reddit Hidden Profile, Posts &amp; Comments Finder">
<meta property="og:description" content="Find posts AND comments from hidden Reddit profiles. Search any Reddit username to uncover their complete post and comment history — even if their profile is set to hidden. Free, instant, no login.">
<meta property="og:url" content="https://ghostddit.pages.dev/">
<meta property="og:image" content="https://ghostddit.pages.dev/og-image.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta property="og:image:alt" content="Ghostddit — Reddit Hidden Profile, Posts & Comments Finder">
<meta property="og:locale" content="en_US">

<!-- ═══════════════════════════════════════════════
     TWITTER / X CARD
     ═══════════════════════════════════════════════ -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="@Ghostddit">
<meta name="twitter:creator" content="@Aryan_Raj_7167">
<meta name="twitter:title" content="Ghostddit — Reddit Hidden Profile, Posts & Comments Finder">
<meta name="twitter:description" content="Find posts AND comments from hidden Reddit profiles. Search any username to see their full Reddit activity — free, no login needed.">
<meta name="twitter:image" content="https://ghostddit.pages.dev/og-image.png">
<meta name="twitter:image:alt" content="Ghostddit — Reddit Hidden Profile, Posts & Comments Finder">

<!-- ═══════════════════════════════════════════════
     STRUCTURED DATA — WebApplication (JSON-LD)
     ═══════════════════════════════════════════════ -->
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "WebApplication",
  "name": "Ghostddit",
  "alternateName": ["Reddit Hidden Profile Finder", "Reddit Hidden Post Finder", "Reddit Comment History Finder"],
  "url": "https://ghostddit.pages.dev/",
  "description": "Ghostddit uncovers posts and comments from hidden Reddit profiles. When a Reddit user hides their profile, their activity vanishes from their page but remains indexed. Enter any username to find their hidden posts and full comment history instantly.",
  "applicationCategory": "UtilitiesApplication",
  "operatingSystem": "Any",
  "browserRequirements": "Requires JavaScript. Works in all modern browsers.",
  "offers": {
    "@type": "Offer",
    "price": "0",
    "priceCurrency": "USD"
  },
  "author": {
    "@type": "Person",
    "name": "u/Aryan_Raj_7167",
    "url": "https://www.reddit.com/user/Aryan_Raj_7167/"
  },
  "featureList": [
    "Find posts from hidden Reddit profiles",
    "Find comments from hidden Reddit profiles",
    "View Reddit hidden account posts and comment history",
    "Sort posts and comments by new, old, top, or hot",
    "Filter posts and comments by subreddit",
    "Search text and phrases within posts and comments",
    "View Reddit user karma and account info",
    "Detect if a Reddit profile is hidden",
    "See pinned posts from hidden profiles",
    "Deep link to specific user, tab, and sort via URL params"
  ],
  "keywords": "Ghostddit, Reddit hidden profile, Reddit hidden posts, Reddit hidden comments, hidden Reddit account, Reddit post finder, Reddit comment history"
}
</script>

<!-- ═══════════════════════════════════════════════
     STRUCTURED DATA — Support Me page (JSON-LD)
     ═══════════════════════════════════════════════ -->
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "WebPage",
  "name": "Support Ghostddit",
  "url": "https://ghostddit.pages.dev/support-me/",
  "description": "Support Ghostddit — a free Reddit hidden profile viewer. Tip the developer via UPI (India) or crypto (worldwide) to keep the project alive.",
  "isPartOf": {
    "@type": "WebSite",
    "name": "Ghostddit",
    "url": "https://ghostddit.pages.dev/"
  },
  "author": {
    "@type": "Person",
    "name": "u/Aryan_Raj_7167",
    "url": "https://www.reddit.com/user/Aryan_Raj_7167/"
  },
  "potentialAction": {
    "@type": "DonateAction",
    "name": "Support Ghostddit",
    "description": "Tip the developer via UPI or crypto",
    "target": "https://ghostddit.pages.dev/support-me/"
  }
}
</script>

<!-- ═══════════════════════════════════════════════
     STRUCTURED DATA — FAQPage (JSON-LD)
     ═══════════════════════════════════════════════ -->
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    {
      "@type": "Question",
      "name": "What is Ghostddit?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Ghostddit is a free tool that finds posts and comments from hidden Reddit profiles. When a Reddit user hides their profile, their activity disappears from their profile page but remains indexed by Reddit's search engine. Ghostddit uses Reddit's public API to surface both hidden posts and the full comment history for any username you search — no login required."
      }
    },
    {
      "@type": "Question",
      "name": "How do I find posts from a hidden Reddit account?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Enter the Reddit username into Ghostddit and click Search. The tool queries Reddit's search index for all posts by that author and displays them instantly — even if their profile is set to hidden. You can then sort by new, top, hot, or old, and filter by subreddit."
      }
    },
    {
      "@type": "Question",
      "name": "Can I see all posts and comments from a hidden Reddit profile?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Ghostddit retrieves every post that Reddit has indexed in its search engine, and fetches comment history through multiple sources including Reddit's API and archive services. Most activity is covered, but some very old or removed content may be missing. The tool automatically paginates through all available results for maximum coverage."
      }
    },
    {
      "@type": "Question",
      "name": "What is a hidden Reddit profile?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "A hidden Reddit profile is when a Reddit user enables the 'hide my profile' option in their account settings. This makes their profile page appear empty — their posts and comments disappear from their profile page. However, their content still exists in Reddit's search index, which is how Ghostddit is able to find and display it."
      }
    },
    {
      "@type": "Question",
      "name": "Does Ghostddit work on mobile?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Yes, Ghostddit is fully mobile-friendly and works in any modern browser on Android, iPhone, or tablet. No app download is required — just visit ghostddit.pages.dev from your mobile browser."
      }
    },
    {
      "@type": "Question",
      "name": "Is Ghostddit safe to use?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Yes. Ghostddit only uses Reddit's own public API and publicly indexed data — the same data anyone can access through Reddit's search. No passwords, no logins, and no personal data is collected or stored. Ghostddit does not scrape private content."
      }
    },
    {
      "@type": "Question",
      "name": "Is Ghostddit free to use?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Yes, Ghostddit is completely free. No Reddit account, no login, and no signup required. Just enter a username and search. Ghostddit is supported by optional tips from users who find it useful."
      }
    },
    {
      "@type": "Question",
      "name": "Can I share a direct link to a user's posts or comments on Ghostddit?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Yes. Ghostddit supports deep links via clean URLs. Use ghostddit.pages.dev/user/USERNAME for posts or ghostddit.pages.dev/user/USERNAME/?type=comment for comments. Add ?sort=new, ?sort=top, or ?sort=old to pre-select the sort order. Posts and comments have independent sort params (?sort for posts, ?csort for comments)."
      }
    },
    {
      "@type": "Question",
      "name": "How often is Reddit data updated on Ghostddit?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Ghostddit fetches data live from Reddit's API on every search — there is no cached or stale data. Each time you search a username, you get the most up-to-date posts and comments available in Reddit's index at that moment."
      }
    },
    {
      "@type": "Question",
      "name": "Can I request account removal from Ghostddit?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Ghostddit only displays publicly indexed Reddit data. If you want your Reddit activity removed, the most effective method is to delete your Reddit posts and comments directly through Reddit. For additional requests, contact u/Aryan_Raj_7167 on Reddit."
      }
    }
  ]
}
</script>

<!-- ═══════════════════════════════════════════════
     STRUCTURED DATA — BreadcrumbList (JSON-LD)
     ═══════════════════════════════════════════════ -->
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "BreadcrumbList",
  "itemListElement": [
    {
      "@type": "ListItem",
      "position": 1,
      "name": "Home",
      "item": "https://ghostddit.pages.dev/"
    }
  ]
}
</script>

<!-- ═══════════════════════════════════════════════
     PERFORMANCE & PRELOADING
     ═══════════════════════════════════════════════ -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="dns-prefetch" href="https://www.reddit.com">
<link rel="dns-prefetch" href="https://api.reddit.com">
<link href="https://fonts.googleapis.com/css2?family=Sora:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">

<!-- ═══════════════════════════════════════════════
     FAVICON / PWA ICONS
     ═══════════════════════════════════════════════ -->
<link rel="icon" type="image/svg+xml" href="/favicon.ico">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<link rel="icon" type="image/png" sizes="192x192" href="/android-chrome-192x192.png">
<link rel="icon" type="image/png" sizes="512x512" href="/android-chrome-512x512.png">
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<link rel="manifest" href="/site.webmanifest">

<!-- ═══════════════════════════════════════════════
     ADDITIONAL SEO SIGNALS
     ═══════════════════════════════════════════════ -->
<meta name="rating" content="general">
<meta name="revisit-after" content="7 days">
<meta name="language" content="English">
<meta name="category" content="utilities, reddit tools, social media">
<meta name="classification" content="Web Tool">
<meta name="coverage" content="Worldwide">
<meta name="distribution" content="Global">
<meta name="target" content="all">
<meta name="HandheldFriendly" content="True">
<meta name="MobileOptimized" content="320">
<!-- Sitemap: https://ghostddit.pages.dev/sitemap.xml -->
<!-- Robots: https://ghostddit.pages.dev/robots.txt -->
<style>
    :root {
        --bg:#0d0d0d;--bg2:#161616;--bg3:#1e1e1e;--border:#2a2a2a;
        --text:#f0f0f0;--text2:#888;--text3:#555;
        --accent:#ff4500;--accent2:#ff6534;--accent-dim:rgba(255,69,0,0.12);
        --radius:12px;--shadow:0 4px 24px rgba(0,0,0,0.4);
    }
    [data-theme="light"]{
        --bg:#f5f5f5;--bg2:#fff;--bg3:#efefef;--border:#e0e0e0;
        --text:#111;--text2:#555;--text3:#aaa;
        --accent-dim:rgba(255,69,0,0.08);--shadow:0 4px 24px rgba(0,0,0,0.08);
    }
    *,*::before,*::after{box-sizing:border-box;margin:0;padding:0;}
    body{font-family:'Sora',sans-serif;background:var(--bg);color:var(--text);min-height:100vh;-webkit-font-smoothing:antialiased;}

    /* TOPBAR */
    .topbar{position:sticky;top:0;z-index:100;display:flex;align-items:center;justify-content:space-between;padding:14px 20px;background:var(--bg);border-bottom:1px solid var(--border);}
    .logo{display:flex;align-items:center;gap:8px;font-size:1.05rem;font-weight:700;letter-spacing:-0.02em;}
    .logo-dot{width:10px;height:10px;border-radius:50%;background:var(--accent);box-shadow:0 0 10px var(--accent);flex-shrink:0;}
    .theme-btn{background:var(--bg3);border:1px solid var(--border);color:var(--text2);border-radius:8px;padding:6px 12px;font-size:0.78rem;font-family:inherit;cursor:pointer;transition:all .2s;}
    .theme-btn:hover{border-color:var(--accent);color:var(--accent);}
    .topbar-right{display:flex;align-items:center;gap:8px;}
    
    /* MAIN */
    main{max-width:680px;margin:0 auto;padding:28px 16px 80px;}
    
    /* HERO SECTION */
    .hero-section { margin-bottom: 16px; }
    
    .hero-title {
        font-size: clamp(1.4rem, 5vw, 2rem);
        font-weight: 700;
        letter-spacing: -.03em;
        line-height: 1.2;
        margin-bottom: 10px;
        color: var(--text);
    }
    .hero-sub {
        font-size: .92rem;
        color: var(--text2);
        line-height: 1.55;
        margin-bottom: 20px;
        max-width: 560px;
    }
    .hero-sub strong { color: var(--text); }
    
    .search-wrap { margin-bottom: 0; }

    /* SEARCH */
    .search-label{font-size:0.7rem;font-weight:600;letter-spacing:.1em;color:var(--text3);text-transform:uppercase;margin-bottom:8px;}
    .input-row{display:flex;gap:10px;align-items:stretch;}
    .input-wrap{flex:1;display:flex;align-items:center;background:var(--bg2);border:1px solid var(--border);border-radius:var(--radius);overflow:hidden;transition:border-color .2s;}
    .input-wrap:focus-within{border-color:var(--accent);}
    .input-prefix{padding:0 6px 0 14px;font-family:'JetBrains Mono',monospace;font-size:0.95rem;color:var(--accent);font-weight:500;user-select:none;white-space:nowrap;}
    .username-input{flex:1;border:none;outline:none;background:transparent;color:var(--text);font-size:0.95rem;font-family:'JetBrains Mono',monospace;padding:14px 14px 14px 0;}
    .username-input::placeholder{color:var(--text3);}
    .search-btn{background:var(--accent);color:#fff;border:none;border-radius:var(--radius);padding:0 22px;font-family:inherit;font-size:0.9rem;font-weight:600;cursor:pointer;white-space:nowrap;transition:background .2s,transform .1s;min-height:50px;}
    .search-btn:hover{background:var(--accent2);}
    .search-btn:active{transform:scale(0.97);}
    .search-btn:disabled{opacity:.5;cursor:not-allowed;transform:none;}

    /* SORT */
    .sort-row{display:flex;gap:6px;flex-wrap:wrap;margin-top:12px;}
    .sort-chip{background:var(--bg2);border:1px solid var(--border);color:var(--text2);border-radius:20px;padding:5px 14px;font-size:0.78rem;font-family:inherit;font-weight:500;cursor:pointer;transition:all .15s;}
    .sort-chip:hover{border-color:var(--accent);color:var(--accent);}
    .sort-chip.active{background:var(--accent-dim);border-color:var(--accent);color:var(--accent);}

    /* STATUS / ALERT / ANNOUNCEMENT */
    .status{display:none;align-items:center;gap:10px;padding:12px 16px;margin:16px 0;background:var(--bg2);border:1px solid var(--border);border-radius:var(--radius);font-size:.85rem;color:var(--text2);}
    .status.on{display:flex;}
    .spin{width:14px;height:14px;border-radius:50%;border:2px solid var(--border);border-top-color:var(--accent);animation:spin .7s linear infinite;flex-shrink:0;}
    @keyframes spin{to{transform:rotate(360deg);}}
    .alert{display:none;padding:12px 16px;border-radius:var(--radius);font-size:.85rem;margin:16px 0;}
    .alert.on{display:block;}
    .alert.error{background:rgba(239,68,68,.1);border:1px solid rgba(239,68,68,.3);color:#f87171;}
    .alert.info{background:rgba(59,130,246,.1);border:1px solid rgba(59,130,246,.3);color:#93c5fd;}
    .alert.warn{background:rgba(234,179,8,.07);border:1px solid rgba(234,179,8,.3);color:#fbbf24;font-size:.8rem;}
    .announcement{display:block;padding:12px 16px;border-radius:var(--radius);font-size:.85rem;margin:16px 0;}
    .announcement.error{background:rgba(239,68,68,.1);border:1px solid rgba(239,68,68,.3);color:#f87171;}
    .announcement.info{background:rgba(59,130,246,.1);border:1px solid rgba(59,130,246,.3);color:#93c5fd;}
    .announcement.warn{background:rgba(234,179,8,.07);border:1px solid rgba(234,179,8,.3);color:#fbbf24;font-size:.8rem;}
    .announcement.warn a{display:inline-block;color:#fbbf24;}
    .announcement.warn ul li{margin:10px 0;text-align:center;list-style: none}

    /* PROFILE */
    .profile-bar{display:none;background:var(--bg2);border:1px solid var(--border);border-radius:var(--radius);padding:16px 20px;margin-top:12px;margin-bottom:16px;align-items:center;justify-content:space-between;gap:12px;}
    .profile-bar.on{display:flex;}
    .profile-left{display:flex;align-items:center;gap:10px;flex-wrap:wrap;}
    .profile-name{font-weight:700;font-size:1rem;font-family:'JetBrains Mono',monospace;}
    .hidden-badge{display:inline-flex;align-items:center;gap:4px;background:var(--accent-dim);border:1px solid var(--accent);color:var(--accent);font-size:.72rem;font-weight:600;padding:3px 9px;border-radius:20px;}
    .stat-block{text-align:right;flex-shrink:0;}
    .stat-val{font-size:1.4rem;font-weight:700;font-family:'JetBrains Mono',monospace;color:var(--accent);}
    .stat-lbl{font-size:.72rem;color:var(--text3);display:block;margin-top:-2px;}

    /* REDDIT-STYLE PROFILE CARD */
    .rprofile{display:none;background:var(--bg2);border:1px solid var(--border);border-radius:var(--radius);margin-bottom:0;}
    .rprofile.on{display:block;}
    .rprofile-banner{height:90px;background:linear-gradient(135deg,#ff4500 0%,#ff6534 50%,#ff8c69 100%);border-radius:var(--radius) var(--radius) 0 0;overflow:hidden;}
    .rprofile-avatar-row{display:flex;align-items:flex-end;justify-content:space-between;padding:0 16px;margin-top:-44px;margin-bottom:0;}
    .rprofile-avatar-wrap{width:88px;height:88px;border-radius:50%;border:4px solid var(--bg2);overflow:hidden;background:var(--bg3);flex-shrink:0;}
    .rprofile-avatar{width:100%;height:100%;object-fit:cover;display:block;}
    .rprofile-body{padding:8px 16px 16px;}
    .rprofile-name-row{display:flex;align-items:center;gap:8px;margin-bottom:2px;flex-wrap:wrap;}
    .rprofile-name{font-size:1.15rem;font-weight:700;letter-spacing:-.02em;line-height:1.2;}
    .rprofile-username{font-family:'JetBrains Mono',monospace;font-size:.82rem;color:var(--text3);margin-bottom:6px;}
    .rprofile-about{font-size:.83rem;color:var(--text2);line-height:1.5;margin-bottom:12px;white-space:pre-wrap;word-break:break-word;}
    .rprofile-stats{display:flex;align-items:center;gap:0;flex-wrap:wrap;margin-bottom:10px;background:var(--bg3);border-radius:10px;padding:10px 14px;gap:8px;}
    .rprofile-stat{display:flex;flex-direction:column;align-items:center;flex:1;min-width:60px;}
    .rprofile-stat-val{font-size:1rem;font-weight:700;font-family:'JetBrains Mono',monospace;color:var(--accent);}
    .rprofile-stat-lbl{font-size:.65rem;color:var(--text3);text-transform:uppercase;letter-spacing:.05em;margin-top:2px;text-align:center;}
    .rprofile-stat-sep{width:1px;height:28px;background:var(--border);flex-shrink:0;}
    .account-status{display:inline-flex;align-items:center;gap:4px;font-size:.75rem;font-weight:600;padding:6px 16px;border-radius:20px;}
    .rprofile-body .account-status{display:block;text-align:center;width:fit-content;margin:0 auto;}
    .rprofile-badges{display:flex;align-items:center;justify-content:center;gap:8px;flex-wrap:wrap;}
    .nsfw-badge{display:inline-flex;align-items:center;font-size:.65rem;font-weight:700;padding:2px 7px;border-radius:8px;background:rgba(239,68,68,.15);border:1px solid rgba(239,68,68,.5);color:#f87171;letter-spacing:.03em;flex-shrink:0;}
    .account-status.hidden{background:var(--accent-dim);border:1px solid var(--accent);color:var(--accent);}
    .account-status.visible{background:rgba(34,197,94,.1);border:1px solid rgba(34,197,94,.3);color:#4ade80;}
    .account-status.archived{background:rgba(234,179,8,.1);border:1px solid rgba(234,179,8,.3);color:#fbbf24;}
    
    /* CARDS */
    .post-list{display:flex;flex-direction:column;gap:12px;}
    .card{background:var(--bg2);border:1px solid var(--border);border-radius:var(--radius);padding:16px;transition:border-color .2s,box-shadow .2s;animation:fadeUp .25s ease both;}
    .card:hover{border-color:var(--accent);box-shadow:var(--shadow);}

    @keyframes fadeUp{from{opacity:0;transform:translateY(8px);}to{opacity:1;transform:translateY(0);}}
    .card-title{font-size:.95rem;font-weight:600;line-height:1.4;margin-bottom:8px;}
    .card-title a{color:var(--text);text-decoration:none;}
    .card-title a:hover{color:var(--accent);}
    .card-sub{display:inline-block;background:var(--accent-dim);color:var(--accent);font-size:.72rem;font-weight:600;padding:3px 9px;border-radius:20px;margin-bottom:10px;}
    .sub-nsfw{display:inline-block;font-size:.62rem;font-weight:700;padding:1px 5px;border-radius:6px;background:rgba(239,68,68,.15);border:1px solid rgba(239,68,68,.4);color:#f87171;vertical-align:middle;margin-left:4px;line-height:1.4;}
    .card-media-wrap{margin:10px 0;border-radius:8px;overflow:hidden;}
    .card-media{width:100%;max-height:340px;object-fit:cover;display:block;border-radius:8px;background:var(--bg3);}
    video.card-media{max-height:340px;background:#000;}
    .card-body{font-size:.85rem;color:var(--text2);line-height:1.6;margin-bottom:10px;word-break:break-word;}
    .card-foot{display:flex;align-items:center;gap:12px;margin-top:10px;padding-top:10px;border-top:1px solid var(--border);font-size:.8rem;color:var(--text3);}
    .card-score{display:flex;align-items:center;gap:4px;}
    .card-comments{display:flex;align-items:center;gap:4px;}
    .arrow{color:var(--accent);font-size:.7rem;}
    .card-time{flex:1;}
    .card-open{display:inline-flex;align-items:center;gap:4px;color:var(--accent);font-weight:600;font-size:.8rem;text-decoration:none;padding:5px 12px;border:1px solid var(--accent);border-radius:8px;transition:background .15s;white-space:nowrap;}
    .card-open:hover{background:var(--accent-dim);}
    .post-type{display:inline-flex;align-items:center;gap:4px;font-size:.68rem;font-weight:600;padding:2px 8px;border-radius:20px;margin-left:6px;vertical-align:middle;}
    .post-type.text{background:rgba(99,102,241,.12);border:1px solid rgba(99,102,241,.3);color:#a5b4fc;}
    .post-type.image{background:rgba(34,197,94,.1);border:1px solid rgba(34,197,94,.25);color:#86efac;}
    .post-type.video{background:rgba(239,68,68,.1);border:1px solid rgba(239,68,68,.25);color:#fca5a5;}
    .post-type.gallery{background:rgba(168,85,247,.1);border:1px solid rgba(168,85,247,.25);color:#d8b4fe;}
    .post-type.link{background:rgba(234,179,8,.1);border:1px solid rgba(234,179,8,.25);color:#fde68a;}
    .empty{text-align:center;color:var(--text3);padding:40px 20px;font-size:.9rem;}

    /* ── TEXT SEARCH BAR ── */
    .text-search-row {
        display: none;
        align-items: center;
        gap: 8px;
        padding: 8px 0 6px;
        border-bottom: 1px solid var(--border);
        position: sticky;
        top: 149px;
        z-index: 88;
        background: var(--bg);
    }
    .text-search-row.visible { display: flex; }
    .text-search-wrap {
        flex: 1;
        display: flex;
        align-items: center;
        background: var(--bg2);
        border: 1px solid var(--border);
        border-radius: 20px;
        overflow: hidden;
        transition: border-color .2s;
        min-width: 0;
    }
    .text-search-wrap:focus-within { border-color: var(--accent); }
    .text-search-icon {
        padding: 0 8px 0 12px;
        color: var(--text3);
        display: flex;
        align-items: center;
        flex-shrink: 0;
        transition: color .2s;
    }
    .text-search-wrap:focus-within .text-search-icon { color: var(--accent); }
    .text-search-input {
        flex: 1;
        border: none;
        outline: none;
        background: transparent;
        color: var(--text);
        font-size: 0.85rem;
        font-family: inherit;
        padding: 8px 4px 8px 0;
        min-width: 0;
    }
    .text-search-input::placeholder { color: var(--text3); }
    .text-search-clear {
        background: none;
        border: none;
        color: var(--text3);
        cursor: pointer;
        padding: 0 10px;
        display: none;
        align-items: center;
        font-size: 1rem;
        line-height: 1;
        transition: color .15s;
    }
    .text-search-clear:hover { color: var(--accent); }
    .text-search-clear.visible { display: flex; }
    .text-search-count {
        font-size: .75rem;
        font-weight: 600;
        color: var(--text3);
        white-space: nowrap;
        flex-shrink: 0;
        font-family: 'JetBrains Mono', monospace;
        min-width: 28px;
        text-align: right;
    }
    .text-search-count.has-results { color: var(--accent); }
    mark.rg-highlight {
        background: rgba(255, 69, 0, 0.25);
        color: inherit;
        border-radius: 2px;
        padding: 0 1px;
    }

    /* CONTENT TABS */
    .content-tabs{display:flex;gap:0;border-bottom:1px solid var(--border);margin:0;position:sticky;top:57px;z-index:90;background:var(--bg);box-shadow:0 2px 8px rgba(0,0,0,.25);}
    .tab-btn{background:none;border:none;color:var(--text3);font-family:inherit;font-size:1rem;font-weight:700;padding:12px 22px;cursor:pointer;position:relative;transition:color .18s;letter-spacing:-.01em;}
    .tab-btn:hover{color:var(--text2);}
    .tab-btn.active{color:var(--text);}
    .tab-btn.active::after{content:'';position:absolute;bottom:-1px;left:50%;transform:translateX(-50%);width:60%;height:2px;background:var(--text);border-radius:2px;}

    /* FEED CONTROLS ROW */
    .feed-controls-row{display:flex;align-items:center;gap:8px;margin:0;flex-wrap:wrap;position:sticky;top:103px;z-index:89;background:var(--bg);padding:8px 0 6px;border-bottom:1px solid var(--border);}
    .feed-options-wrap{position:relative;}
    .sub-filter-wrap{position:relative;}
    .feed-options-btn{display:inline-flex;align-items:center;gap:7px;background:var(--bg2);border:1px solid var(--border);color:var(--text2);border-radius:20px;padding:7px 16px;font-size:0.82rem;font-family:inherit;font-weight:600;cursor:pointer;transition:all .15s;white-space:nowrap;}
    .feed-options-btn:hover{border-color:var(--text3);color:var(--text);}
    .feed-options-btn.active-filter{border-color:var(--accent);color:var(--accent);background:var(--accent-dim);}

    /* FEED DROPDOWN */
    .feed-dropdown{display:none;position:absolute;top:calc(100% + 6px);left:0;background:var(--bg2);border:1px solid var(--border);border-radius:12px;min-width:200px;z-index:200;overflow:hidden;box-shadow:0 8px 32px rgba(0,0,0,.35);animation:dropIn .15s ease;}
    .feed-dropdown.open{display:block;}
    @keyframes dropIn{from{opacity:0;transform:translateY(-6px);}to{opacity:1;transform:translateY(0);}}
    .feed-dropdown-item{display:flex;align-items:center;gap:10px;padding:12px 16px;cursor:pointer;font-size:.88rem;color:var(--text2);transition:background .12s,color .12s;font-family:inherit;}
    .feed-dropdown-item:hover{background:var(--bg3);color:var(--text);}
    .feed-dropdown-item.selected{color:var(--text);font-weight:600;}
    .feed-dropdown-item.selected::after{content:'✓';margin-left:auto;color:var(--text);font-size:.85rem;}
    .feed-dropdown-item svg{flex-shrink:0;opacity:.7;}
    .feed-dropdown-item.selected svg{opacity:1;}
    .feed-dropdown-item.hidden-item{display:none;}

    /* SUBREDDIT DROPDOWN */
    .sub-dropdown{display:none;position:absolute;top:calc(100% + 6px);left:0;background:var(--bg2);border:1px solid var(--border);border-radius:12px;min-width:220px;z-index:200;overflow:hidden;box-shadow:0 8px 32px rgba(0,0,0,.35);animation:dropIn .15s ease;}
    .sub-dropdown.open{display:block;}
    .sub-dropdown-search{display:flex;align-items:center;gap:8px;padding:10px 14px;border-bottom:1px solid var(--border);}
    .sub-dropdown-search svg{flex-shrink:0;color:var(--text3);}
    .sub-search-input{flex:1;background:none;border:none;outline:none;color:var(--text);font-size:.85rem;font-family:inherit;}
    .sub-search-input::placeholder{color:var(--text3);}
    .sub-dropdown-list{max-height:240px;overflow-y:auto;padding:4px 0;}
    .sub-dropdown-list::-webkit-scrollbar{width:4px;}
    .sub-dropdown-list::-webkit-scrollbar-track{background:transparent;}
    .sub-dropdown-list::-webkit-scrollbar-thumb{background:var(--border);border-radius:2px;}
    .sub-dropdown-item{display:flex;align-items:center;gap:6px;padding:10px 16px;cursor:pointer;font-size:.85rem;color:var(--text2);transition:background .12s,color .12s;font-family:'JetBrains Mono',monospace;}
    .sub-dropdown-item .sub-label{flex:1;display:flex;align-items:center;gap:5px;min-width:0;}
    .sub-dropdown-item:hover{background:var(--bg3);color:var(--text);}
    .sub-dropdown-item.selected{color:var(--accent);}
    .sub-dropdown-item.selected::after{content:'✓';color:var(--accent);font-size:.85rem;font-family:inherit;}
    .sub-dropdown-item.profile-sub{border-bottom:1px solid var(--border);margin-bottom:4px;padding-bottom:12px;}
    .sub-count{font-size:.72rem;opacity:.5;margin-left:6px;}

    /* ACTIVITY TAB */
    .activity-controls{display:flex;align-items:center;gap:8px;margin-bottom:12px;flex-wrap:wrap;}
    .activity-sort-wrap{position:relative;}
    .activity-sort-btn{display:inline-flex;align-items:center;gap:7px;background:var(--bg2);border:1px solid var(--border);color:var(--text2);border-radius:20px;padding:7px 16px;font-size:0.82rem;font-family:inherit;font-weight:600;cursor:pointer;transition:all .15s;white-space:nowrap;}
    .activity-sort-btn:hover{border-color:var(--text3);color:var(--text);}
    .activity-sort-dropdown{display:none;position:absolute;top:calc(100% + 6px);left:0;background:var(--bg2);border:1px solid var(--border);border-radius:12px;min-width:210px;z-index:200;overflow:hidden;box-shadow:0 8px 32px rgba(0,0,0,.35);animation:dropIn .15s ease;}
    .activity-sort-dropdown.open{display:block;}
    .activity-sort-group{padding:6px 0;border-bottom:1px solid var(--border);}
    .activity-sort-group:last-child{border-bottom:none;}
    .activity-sort-group-label{font-size:.68rem;font-weight:700;color:var(--text3);letter-spacing:.08em;text-transform:uppercase;padding:6px 16px 4px;}
    .activity-sort-item{display:flex;align-items:center;gap:10px;padding:10px 16px;cursor:pointer;font-size:.88rem;color:var(--text2);transition:background .12s,color .12s;font-family:inherit;}
    .activity-sort-item:hover{background:var(--bg3);color:var(--text);}
    .activity-sort-item.selected{color:var(--text);font-weight:600;}
    .activity-sort-item.selected::after{content:'✓';margin-left:auto;color:var(--text);font-size:.85rem;}
    .activity-header{display:flex;align-items:center;justify-content:space-between;padding:4px 0 12px;font-size:.75rem;color:var(--text3);font-weight:600;letter-spacing:.06em;text-transform:uppercase;}
    .activity-card{background:var(--bg2);border:1px solid var(--border);border-radius:var(--radius);padding:14px 16px;display:flex;align-items:center;gap:14px;transition:border-color .2s,box-shadow .2s;animation:fadeUp .22s ease both;}
    .activity-card:hover{border-color:var(--accent);box-shadow:var(--shadow);}
    .activity-rank{font-size:.8rem;font-weight:700;color:var(--text3);width:20px;text-align:center;flex-shrink:0;}
    .activity-sub{flex:1;min-width:0;}
    .activity-sub-name{display:flex;align-items:center;gap:5px;font-family:'JetBrains Mono',monospace;font-size:.9rem;font-weight:600;color:var(--text);}
    .activity-sub-name a{color:var(--text);text-decoration:none;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;}
    .activity-sub-name a:hover{color:var(--accent);}
    .activity-sub-name .sub-nsfw{flex-shrink:0;}
    .activity-badges{display:flex;gap:6px;margin-top:5px;flex-wrap:wrap;}
    .activity-badge{font-size:.7rem;font-weight:600;padding:2px 8px;border-radius:12px;white-space:nowrap;}
    .activity-badge.posts{background:rgba(99,102,241,.12);border:1px solid rgba(99,102,241,.3);color:#a5b4fc;}
    .activity-badge.comments{background:rgba(34,197,94,.1);border:1px solid rgba(34,197,94,.25);color:#86efac;}
    .activity-badge.karma{background:rgba(234,179,8,.1);border:1px solid rgba(234,179,8,.25);color:#fde68a;}
    .activity-bar-wrap{display:flex;align-items:center;gap:8px;flex-shrink:0;}
    .activity-bar-bg{width:48px;height:4px;background:var(--bg3);border-radius:2px;overflow:hidden;}
    .activity-bar-fill{height:100%;background:var(--accent);border-radius:2px;}
    .activity-total{font-size:.88rem;font-weight:700;font-family:'JetBrains Mono',monospace;color:var(--accent);min-width:28px;text-align:right;}

    /* COMMENT CARDS */
    .comment-card{background:var(--bg2);border:1px solid var(--border);border-radius:var(--radius);padding:16px;transition:border-color .2s,box-shadow .2s;animation:fadeUp .25s ease both;}
    .comment-card:hover{border-color:var(--accent);box-shadow:var(--shadow);}
    .comment-thread-ctx{font-size:.75rem;color:var(--text3);margin-bottom:8px;display:flex;align-items:center;gap:6px;flex-wrap:wrap;}
    .comment-thread-ctx a{color:var(--text3);text-decoration:none;}
    .comment-thread-ctx a:hover{color:var(--accent);}
    .comment-body{font-size:.9rem;color:var(--text);line-height:1.65;margin-bottom:6px;word-break:break-word;}
    .comment-body-preview{max-height:6.6em;overflow:hidden;position:relative;}
    .comment-body-preview::after{content:'';position:absolute;bottom:0;left:0;right:0;height:2em;background:linear-gradient(transparent,var(--bg2));}
    .comment-body-full{overflow:visible;max-height:none;}
    .comment-expand-btn{display:inline-flex;align-items:center;gap:4px;background:none;border:none;color:var(--accent);font-size:.78rem;font-weight:600;font-family:inherit;cursor:pointer;padding:2px 0 8px;opacity:.85;}
    .comment-expand-btn:hover{opacity:1;}
    .comment-foot{display:flex;align-items:center;gap:12px;margin-top:10px;padding-top:10px;border-top:1px solid var(--border);font-size:.8rem;color:var(--text3);}
    
    /* Support Me */
    .support-btn {
        display: inline-flex;
        align-items: center;
        gap: 5px;
        background: var(--accent-dim);
        border: 1px solid var(--accent);
        color: var(--accent);
        border-radius: 8px;
        padding: 6px 14px;
        font-family: inherit;
        font-size: 0.78rem;
        font-weight: 600;
        cursor: pointer;
        text-decoration: none;
        transition: all .2s;
        white-space: nowrap;
    }
    .support-btn:hover {
        background: var(--accent);
        color: #fff;
    }
    
    /* SUPPORT BANNER */
    @keyframes banner-shimmer {
        0%   { background-position: -200% center; }
        100% { background-position:  200% center; }
    }
    .support-banner {
        position: relative;
        display: flex;
        align-items: center;
        gap: 12px;
        padding: 13px 16px;
        margin: 16px 0;
        border-radius: var(--radius);
        text-decoration: none;
        overflow: hidden;
        cursor: pointer;
        transition: transform .18s, box-shadow .18s;
        background: linear-gradient(135deg,
            rgba(255,69,0,0.18) 0%,
            rgba(255,101,52,0.10) 50%,
            rgba(255,69,0,0.18) 100%
        );
        border: 1px solid rgba(255,69,0,0.35);
        box-shadow: 0 0 0 0 rgba(255,69,0,0);
    }
    .support-banner::before {
        content: '';
        position: absolute;
        inset: 0;
        background: linear-gradient(105deg,
            transparent 35%,
            rgba(255,255,255,0.06) 50%,
            transparent 65%
        );
        background-size: 200% 100%;
        animation: banner-shimmer 3.5s linear infinite;
        pointer-events: none;
    }
    .support-banner::after {
        content: '';
        position: absolute;
        left: 0; top: 0; bottom: 0;
        width: 3px;
        background: linear-gradient(to bottom, var(--accent), var(--accent2));
        border-radius: var(--radius) 0 0 var(--radius);
    }
    .support-banner:hover {
        transform: translateY(-1px);
        border-color: rgba(255,69,0,0.65);
        box-shadow: 0 4px 20px rgba(255,69,0,0.18);
    }
    .support-banner-icon {
        font-size: 1.4rem;
        line-height: 1;
        flex-shrink: 0;
        filter: drop-shadow(0 0 6px rgba(255,140,0,0.5));
    }
    .support-banner-text {
        display: flex;
        flex-direction: column;
        gap: 2px;
        flex: 1;
        min-width: 0;
    }
    .support-banner-title {
        font-size: .85rem;
        font-weight: 700;
        color: var(--text);
        letter-spacing: -.01em;
        line-height: 1.2;
    }
    .support-banner-sub {
        font-size: .75rem;
        color: var(--text2);
        line-height: 1.2;
    }
    .support-banner-cta {
        flex-shrink: 0;
        background: var(--accent);
        color: #fff;
        font-size: .75rem;
        font-weight: 700;
        padding: 5px 12px;
        border-radius: 20px;
        letter-spacing: .01em;
        transition: background .18s, transform .18s;
        white-space: nowrap;
    }
    .support-banner:hover .support-banner-cta {
        background: var(--accent2);
        transform: translateX(2px);
    }
    
    /* SEO SECTION */
    .seo-section {
        margin-top: 40px;
        padding-top: 28px;
        border-top: 1px solid var(--border);
    }
    .seo-heading {
        font-size: 1.15rem;
        font-weight: 700;
        letter-spacing: -.02em;
        margin-bottom: 12px;
        color: var(--text);
        line-height: 1.3;
    }
    .seo-subheading {
        font-size: .95rem;
        font-weight: 700;
        letter-spacing: -.01em;
        margin: 20px 0 8px;
        color: var(--text);
    }
    .seo-intro {
        font-size: .87rem;
        color: var(--text2);
        line-height: 1.6;
        margin-bottom: 14px;
    }
    .seo-body {
        font-size: .85rem;
        color: var(--text2);
        line-height: 1.65;
        margin-bottom: 8px;
    }
    .seo-link {
        color: var(--accent);
        text-decoration: none;
    }
    .seo-link:hover { text-decoration: underline; }
    
    /* FEATURE PILLS */
    .feature-pills {
        display: flex;
        flex-wrap: wrap;
        gap: 7px;
        margin-bottom: 20px;
    }
    .feature-pill {
        background: var(--bg2);
        border: 1px solid var(--border);
        color: var(--text2);
        font-size: .73rem;
        font-weight: 600;
        padding: 4px 11px;
        border-radius: 20px;
        letter-spacing: .01em;
    }
    
    /* FAQ ACCORDION */
    .faq-list {
        display: flex;
        flex-direction: column;
        gap: 8px;
        margin-top: 12px;
    }
    .faq-item {
        background: var(--bg2);
        border: 1px solid var(--border);
        border-radius: var(--radius);
        overflow: hidden;
        transition: border-color .2s;
    }
    .faq-item[open] {
        border-color: rgba(255,69,0,0.3);
    }
    .faq-q {
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding: 14px 16px;
        font-size: .88rem;
        font-weight: 600;
        color: var(--text);
        cursor: pointer;
        list-style: none;
        gap: 12px;
        user-select: none;
        line-height: 1.3;
    }
    .faq-q::-webkit-details-marker { display: none; }
    .faq-q::after {
        content: '▾';
        color: var(--accent);
        flex-shrink: 0;
        font-size: .8rem;
        transition: transform .2s;
    }
    .faq-item[open] .faq-q::after {
        transform: rotate(180deg);
    }
    .faq-a {
        padding: 0 16px 14px;
        font-size: .83rem;
        color: var(--text2);
        line-height: 1.65;
        border-top: 1px solid var(--border);
        padding-top: 12px;
    }
    .faq-a p { margin: 0; }
    .faq-a code {
        font-family: 'JetBrains Mono', monospace;
        font-size: .78rem;
        background: var(--bg3);
        border: 1px solid var(--border);
        padding: 1px 5px;
        border-radius: 4px;
        color: var(--accent);
    }
    
    @media(max-width:480px){
        .input-row{flex-direction:column;}
        .search-btn{min-height:46px;}
        .profile-bar{flex-direction:column;align-items:flex-start;}
        .stat-block{text-align:left;}
    }
</style>
</head>
<body>

<noscript>
  <div style="text-align:center;padding:40px;font-family:sans-serif;background:#0d0d0d;color:#f0f0f0;">
    <h1>Ghostddit — Reddit Hidden Profile &amp; Post Finder</h1>
    <p>Ghostddit requires JavaScript to search for hidden Reddit posts. Please enable JavaScript in your browser to use this tool.</p>
    <p>Ghostddit lets you find posts from hidden Reddit profiles, view Reddit hidden account posts, and search any Reddit username's post history — even if their profile is hidden.</p>
  </div>
</noscript>

<header class="topbar">
    <div class="logo"><div class="logo-dot"></div>Ghostddit</div>
    <div class="topbar-right">
        <a href="/support-me/" class="support-btn">☕ Support</a>
        <button class="theme-btn" id="themeBtn" onclick="cycleTheme()">🖥️ System</button>
    </div>
</header>

<main>

    <!-- HERO -->
    <div style="margin-bottom:24px;padding:20px 0 4px;">
        <h1 style="font-size:1.6rem;font-weight:700;letter-spacing:-0.03em;margin-bottom:8px;">Ghostddit 👻 — Reddit Hidden Posts &amp; Comments Finder</h1>
        <p style="font-size:0.88rem;color:var(--text2);line-height:1.6;margin-bottom:20px;">Find posts and comments from any <strong style="color:var(--text)">hidden Reddit profile</strong> — instantly. Free, no login required.</p>
    </div>

    <!-- SEARCH -->
    <div style="margin-bottom:24px;">
        <div class="search-label">Reddit Username</div>
        <div class="input-row">
            <div class="input-wrap">
                <span class="input-prefix">u/</span>
                <input class="username-input" id="usernameInput" type="text"
                    placeholder="username" autocomplete="off" autocorrect="off"
                    autocapitalize="none" spellcheck="false">
            </div>
            <button class="search-btn" id="searchBtn" onclick="startSearch()">Search</button>
        </div>
    </div>

    <!-- SUPPORT BANNER -->
    <a href="/support-me/" class="support-banner">
        <span class="support-banner-icon">☕</span>
        <span class="support-banner-text">
            <span class="support-banner-title">Ghostddit is free</span>
            <span class="support-banner-sub">Support the dev with a small tip</span>
        </span>
        <span class="support-banner-cta">Support →</span>
    </a>

    <!-- STATUS / ALERTS -->
    <div class="status" id="statusBar"><div class="spin"></div><span id="statusText"></span></div>
    <div class="alert" id="alertBox"></div>
    <div class="alert warn" id="fetchNotice" style="display:none">⚠️ Reddit's search index may not return every post — some older or less indexed posts might be missing from these results.</div>

    <!-- REDDIT-STYLE PROFILE CARD -->
    <div class="rprofile" id="accountInfo">
        <div class="rprofile-banner" id="accountBanner"></div>
        <div class="rprofile-avatar-row">
            <div class="rprofile-avatar-wrap">
                <img class="rprofile-avatar" id="accountPfp" src="" alt="Profile picture">
            </div>
        </div>
        <div class="rprofile-body">
            <div class="rprofile-name-row">
                <div class="rprofile-name" id="accountName"></div>
                <span class="nsfw-badge" id="nsfwBadge" style="display:none">18+</span>
            </div>
            <div class="rprofile-username" id="accountUsername"></div>
            <div class="rprofile-about" id="accountAbout"></div>
            <div class="rprofile-stats">
                <div class="rprofile-stat">
                    <span class="rprofile-stat-val" id="totalKarma">0</span>
                    <span class="rprofile-stat-lbl">Karma</span>
                </div>
                <div class="rprofile-stat-sep"></div>
                <div class="rprofile-stat">
                    <span class="rprofile-stat-val" id="postKarma">0</span>
                    <span class="rprofile-stat-lbl">Post karma</span>
                </div>
                <div class="rprofile-stat-sep"></div>
                <div class="rprofile-stat">
                    <span class="rprofile-stat-val" id="commentKarma">0</span>
                    <span class="rprofile-stat-lbl">Comment karma</span>
                </div>
                <div class="rprofile-stat-sep"></div>
                <div class="rprofile-stat">
                    <span class="rprofile-stat-val" id="accountAge"></span>
                    <span class="rprofile-stat-lbl">Account age</span>
                </div>
            </div>
            <div class="rprofile-badges">
                <span class="account-status" id="accountStatus" style="display:none"></span>
            </div>
        </div>
    </div>

    <!-- TABS -->
    <div class="content-tabs" id="contentTabs" style="display:none">
        <button class="tab-btn active" id="tabPosts" onclick="switchTab('posts')">Posts</button>
        <button class="tab-btn" id="tabComments" onclick="switchTab('comments')">Comments</button>
        <button class="tab-btn" id="tabActivity" onclick="switchTab('activity')">Activity</button>
    </div>

    <!-- FEED CONTROLS ROW -->
    <div class="feed-controls-row" id="feedControlsRow" style="display:none">
        <div class="feed-options-wrap">
            <button class="feed-options-btn" id="feedOptionsBtn" onclick="toggleFeedOptions()">
                <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><circle cx="9" cy="5" r="1.5"/><circle cx="9" cy="12" r="1.5"/><circle cx="9" cy="19" r="1.5"/><line x1="9" y1="5" x2="20" y2="5"/><line x1="9" y1="12" x2="20" y2="12"/><line x1="9" y1="19" x2="20" y2="19"/><line x1="4" y1="5" x2="7.5" y2="5"/><line x1="4" y1="12" x2="7.5" y2="12"/><line x1="4" y1="19" x2="7.5" y2="19"/></svg>
                Feed Options
            </button>
            <div class="feed-dropdown" id="feedDropdown">
                <div class="feed-dropdown-item selected" data-sort="new" onclick="selectSort('new')">
                    <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
                    <span>New</span>
                </div>
                <div class="feed-dropdown-item" data-sort="hot" onclick="selectSort('hot')">
                    <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M8.5 14.5A2.5 2.5 0 0011 12c0-1.38-.5-2-1-3-1.072-2.143-.224-4.054 2-6 .5 2.5 2 4.9 4 6.5 2 1.6 3 3.5 3 5.5a7 7 0 11-14 0c0-1.153.433-2.294 1-3a2.5 2.5 0 002.5 3z"/></svg>
                    <span>Hot</span>
                </div>
                <div class="feed-dropdown-item" data-sort="old" onclick="selectSort('old')">
                    <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 8 14"/></svg>
                    <span>Old</span>
                </div>
                <div class="feed-dropdown-item" data-sort="top" onclick="selectSort('top')">
                    <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="17 11 12 6 7 11"/><polyline points="17 18 12 13 7 18"/></svg>
                    <span>Top</span>
                </div>
                <div class="feed-dropdown-item posts-only" data-sort="comments" onclick="selectSort('comments')">
                    <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2z"/></svg>
                    <span>Most Commented</span>
                </div>
            </div>
        </div>
        <!-- SUBREDDIT FILTER -->
        <div class="sub-filter-wrap" id="subFilterWrap" style="display:none">
            <button class="feed-options-btn" id="subFilterBtn" onclick="toggleSubDropdown()">
                <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 6h18M7 12h10M11 18h2"/></svg>
                <span id="subFilterLabel">Subreddit</span>
            </button>
            <div class="sub-dropdown" id="subDropdown">
                <div class="sub-dropdown-search">
                    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
                    <input type="text" class="sub-search-input" id="subSearchInput" placeholder="Search subreddits…" oninput="filterSubList()" autocomplete="off">
                </div>
                <div class="sub-dropdown-list" id="subDropdownList"></div>
            </div>
        </div>
    </div>

    <!-- ACTIVITY SORT CONTROLS -->
    <div class="feed-controls-row" id="activityControlsRow" style="display:none">
        <div class="activity-sort-wrap">
            <button class="activity-sort-btn" id="activitySortBtn" onclick="toggleActivitySortDropdown()">
                <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 6h18M7 12h10M11 18h2"/></svg>
                <span id="activitySortLabel">Activity (High → Low)</span>
            </button>
            <div class="activity-sort-dropdown" id="activitySortDropdown">
                <div class="activity-sort-group">
                    <div class="activity-sort-group-label">By Count</div>
                    <div class="activity-sort-item selected" data-asort="activity-desc" onclick="selectActivitySort('activity-desc')">
                        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="17 11 12 6 7 11"/><line x1="12" y1="6" x2="12" y2="18"/></svg>
                        Activity (High → Low)
                    </div>
                    <div class="activity-sort-item" data-asort="activity-asc" onclick="selectActivitySort('activity-asc')">
                        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="17 13 12 18 7 13"/><line x1="12" y1="18" x2="12" y2="6"/></svg>
                        Activity (Low → High)
                    </div>
                    <div class="activity-sort-item" data-asort="posts-desc" onclick="selectActivitySort('posts-desc')">
                        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/><polyline points="14 2 14 8 20 8"/></svg>
                        Posts (High → Low)
                    </div>
                    <div class="activity-sort-item" data-asort="posts-asc" onclick="selectActivitySort('posts-asc')">
                        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/><polyline points="14 2 14 8 20 8"/></svg>
                        Posts (Low → High)
                    </div>
                    <div class="activity-sort-item" data-asort="comments-desc" onclick="selectActivitySort('comments-desc')">
                        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2z"/></svg>
                        Comments (High → Low)
                    </div>
                    <div class="activity-sort-item" data-asort="comments-asc" onclick="selectActivitySort('comments-asc')">
                        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2z"/></svg>
                        Comments (Low → High)
                    </div>
                </div>
                <div class="activity-sort-group">
                    <div class="activity-sort-group-label">By Karma</div>
                    <div class="activity-sort-item" data-asort="karma-desc" onclick="selectActivitySort('karma-desc')">
                        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg>
                        Karma (High → Low)
                    </div>
                    <div class="activity-sort-item" data-asort="karma-asc" onclick="selectActivitySort('karma-asc')">
                        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg>
                        Karma (Low → High)
                    </div>
                </div>
            </div>
        </div>
    </div>

    <!-- ── TEXT SEARCH BAR ── -->
    <div class="text-search-row" id="textSearchRow">
        <div class="text-search-wrap">
            <span class="text-search-icon">
                <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
            </span>
            <input
                type="text"
                class="text-search-input"
                id="textSearchInput"
                placeholder="Search in results…"
                autocomplete="off"
                autocorrect="off"
                autocapitalize="none"
                spellcheck="false"
                oninput="onTextSearch()"
            >
            <button class="text-search-clear" id="textSearchClear" onclick="clearTextSearch()" title="Clear search">✕</button>
        </div>
        <span class="text-search-count" id="textSearchCount"></span>
    </div>

    <!-- STATS BAR -->
    <div class="profile-bar" id="profileCard">
        <div class="profile-left">
            <span class="profile-name" id="profileName"></span>
        </div>
        <div class="stat-block" id="statBlock">
            <span class="stat-val" id="statPosts">0</span>
            <span class="stat-lbl" id="statLabel">Posts found</span>
        </div>
    </div>

    <!-- RESULTS LIST -->
    <div class="post-list" id="postsList"></div>

    <!-- ══ SEO SECTION ══ -->
    <section aria-label="About Ghostddit" style="margin-top:48px;padding:24px 0;border-top:1px solid var(--border);">

        <h2 style="font-size:1.05rem;font-weight:700;letter-spacing:-0.02em;margin-bottom:10px;color:var(--text);">About Ghostddit — Reddit Hidden Posts &amp; Comments Finder</h2>
        <p style="font-size:.85rem;color:var(--text2);line-height:1.6;margin-bottom:14px;"><strong>Ghostddit</strong> is the fastest free tool to <a href="/" style="color:var(--accent);text-decoration:none;">view hidden Reddit profiles</a>, find hidden Reddit posts, and browse the full comment history of any Reddit user — even when their profile is completely hidden.</p>

        <div style="display:flex;flex-wrap:wrap;gap:7px;margin-bottom:20px;">
            <span style="background:var(--bg2);border:1px solid var(--border);color:var(--text2);font-size:.73rem;font-weight:600;padding:4px 11px;border-radius:20px;">Hidden posts</span>
            <span style="background:var(--bg2);border:1px solid var(--border);color:var(--text2);font-size:.73rem;font-weight:600;padding:4px 11px;border-radius:20px;">Full comment history</span>
            <span style="background:var(--bg2);border:1px solid var(--border);color:var(--text2);font-size:.73rem;font-weight:600;padding:4px 11px;border-radius:20px;">Sort &amp; filter</span>
            <span style="background:var(--bg2);border:1px solid var(--border);color:var(--text2);font-size:.73rem;font-weight:600;padding:4px 11px;border-radius:20px;">Text search</span>
            <span style="background:var(--bg2);border:1px solid var(--border);color:var(--text2);font-size:.73rem;font-weight:600;padding:4px 11px;border-radius:20px;">No login</span>
            <span style="background:var(--bg2);border:1px solid var(--border);color:var(--text2);font-size:.73rem;font-weight:600;padding:4px 11px;border-radius:20px;">Mobile friendly</span>
            <span style="background:var(--bg2);border:1px solid var(--border);color:var(--text2);font-size:.73rem;font-weight:600;padding:4px 11px;border-radius:20px;">Always free</span>
        </div>

        <h3 style="font-size:.95rem;font-weight:700;margin:0 0 8px;color:var(--text);">How Ghostddit Works</h3>
        <p style="font-size:.85rem;color:var(--text2);line-height:1.65;margin-bottom:24px;">When a Reddit user hides their profile, their posts and comments vanish from their profile page — but they remain indexed in Reddit's own search engine. Ghostddit queries Reddit's public API and search index to surface this hidden activity, displaying every <strong>hidden Reddit post</strong> and comment it can find for any username you search.</p>

        <h2 style="font-size:1.05rem;font-weight:700;letter-spacing:-0.02em;margin-bottom:14px;color:var(--text);" id="faq">Frequently Asked Questions</h2>

        <details style="margin-bottom:10px;background:var(--bg2);border:1px solid var(--border);border-radius:10px;overflow:hidden;">
            <summary style="padding:14px 16px;cursor:pointer;font-size:.88rem;font-weight:600;color:var(--text);list-style:none;display:flex;justify-content:space-between;align-items:center;">What is Ghostddit?<span style="color:var(--accent);font-size:.8rem;flex-shrink:0;margin-left:8px;">▾</span></summary>
            <div style="padding:12px 16px 14px;font-size:.83rem;color:var(--text2);line-height:1.65;border-top:1px solid var(--border);">
                <strong>Ghostddit</strong> is a free <strong>Reddit hidden profile viewer</strong> that finds posts and comments from hidden Reddit accounts. When a Reddit user hides their profile, their activity disappears from their profile page — but remains indexed. Ghostddit uses Reddit's public API to surface both <a href="/" style="color:var(--accent);text-decoration:none;">hidden Reddit posts</a> and full comment history for any username you search.
            </div>
        </details>

        <details style="margin-bottom:10px;background:var(--bg2);border:1px solid var(--border);border-radius:10px;overflow:hidden;">
            <summary style="padding:14px 16px;cursor:pointer;font-size:.88rem;font-weight:600;color:var(--text);list-style:none;display:flex;justify-content:space-between;align-items:center;">What is a hidden Reddit profile?<span style="color:var(--accent);font-size:.8rem;flex-shrink:0;margin-left:8px;">▾</span></summary>
            <div style="padding:12px 16px 14px;font-size:.83rem;color:var(--text2);line-height:1.65;border-top:1px solid var(--border);">
                A hidden Reddit profile is when a user enables "hide my profile" in Reddit settings. Their profile page appears empty, but their posts and comments still exist in Reddit's search index. Ghostddit finds and displays this content.
            </div>
        </details>

        <details style="margin-bottom:10px;background:var(--bg2);border:1px solid var(--border);border-radius:10px;overflow:hidden;">
            <summary style="padding:14px 16px;cursor:pointer;font-size:.88rem;font-weight:600;color:var(--text);list-style:none;display:flex;justify-content:space-between;align-items:center;">How do I find posts from a hidden Reddit account?<span style="color:var(--accent);font-size:.8rem;flex-shrink:0;margin-left:8px;">▾</span></summary>
            <div style="padding:12px 16px 14px;font-size:.83rem;color:var(--text2);line-height:1.65;border-top:1px solid var(--border);">
                Enter the Reddit username above and click <strong>Search</strong>. Ghostddit queries Reddit's search index and displays all posts instantly — even if their profile is hidden. Sort by new, top, hot, or old, and filter by subreddit.
            </div>
        </details>

        <details style="margin-bottom:10px;background:var(--bg2);border:1px solid var(--border);border-radius:10px;overflow:hidden;">
            <summary style="padding:14px 16px;cursor:pointer;font-size:.88rem;font-weight:600;color:var(--text);list-style:none;display:flex;justify-content:space-between;align-items:center;">Can I see all posts and comments from a hidden Reddit profile?<span style="color:var(--accent);font-size:.8rem;flex-shrink:0;margin-left:8px;">▾</span></summary>
            <div style="padding:12px 16px 14px;font-size:.83rem;color:var(--text2);line-height:1.65;border-top:1px solid var(--border);">
                Ghostddit retrieves every post Reddit has indexed and fetches comment history through multiple sources. Most activity is covered — some very old or deleted content may be missing. The tool automatically paginates through all available results.
            </div>
        </details>

        <details style="margin-bottom:10px;background:var(--bg2);border:1px solid var(--border);border-radius:10px;overflow:hidden;">
            <summary style="padding:14px 16px;cursor:pointer;font-size:.88rem;font-weight:600;color:var(--text);list-style:none;display:flex;justify-content:space-between;align-items:center;">Does Ghostddit work on mobile?<span style="color:var(--accent);font-size:.8rem;flex-shrink:0;margin-left:8px;">▾</span></summary>
            <div style="padding:12px 16px 14px;font-size:.83rem;color:var(--text2);line-height:1.65;border-top:1px solid var(--border);">
                Yes. Ghostddit is fully mobile-friendly and works in any modern browser on Android, iPhone, or tablet. No app download required — just visit <a href="https://ghostddit.pages.dev/" style="color:var(--accent);text-decoration:none;">ghostddit.pages.dev</a>.
            </div>
        </details>

        <details style="margin-bottom:10px;background:var(--bg2);border:1px solid var(--border);border-radius:10px;overflow:hidden;">
            <summary style="padding:14px 16px;cursor:pointer;font-size:.88rem;font-weight:600;color:var(--text);list-style:none;display:flex;justify-content:space-between;align-items:center;">Is Ghostddit safe to use?<span style="color:var(--accent);font-size:.8rem;flex-shrink:0;margin-left:8px;">▾</span></summary>
            <div style="padding:12px 16px 14px;font-size:.83rem;color:var(--text2);line-height:1.65;border-top:1px solid var(--border);">
                Yes. Ghostddit only uses Reddit's own public API and publicly indexed data — the same data anyone can access through Reddit's search. No passwords, no logins, and no personal data is collected or stored.
            </div>
        </details>

        <details style="margin-bottom:10px;background:var(--bg2);border:1px solid var(--border);border-radius:10px;overflow:hidden;">
            <summary style="padding:14px 16px;cursor:pointer;font-size:.88rem;font-weight:600;color:var(--text);list-style:none;display:flex;justify-content:space-between;align-items:center;">Is Ghostddit free? Do I need to log in?<span style="color:var(--accent);font-size:.8rem;flex-shrink:0;margin-left:8px;">▾</span></summary>
            <div style="padding:12px 16px 14px;font-size:.83rem;color:var(--text2);line-height:1.65;border-top:1px solid var(--border);">
                Yes — completely free. No Reddit account, no login, no signup required. It's supported by optional tips from users who find it useful. <a href="/support-me/" style="color:var(--accent);text-decoration:none;">Support the developer here</a> if you'd like.
            </div>
        </details>

        <details style="margin-bottom:10px;background:var(--bg2);border:1px solid var(--border);border-radius:10px;overflow:hidden;">
            <summary style="padding:14px 16px;cursor:pointer;font-size:.88rem;font-weight:600;color:var(--text);list-style:none;display:flex;justify-content:space-between;align-items:center;">How often is Reddit data updated?<span style="color:var(--accent);font-size:.8rem;flex-shrink:0;margin-left:8px;">▾</span></summary>
            <div style="padding:12px 16px 14px;font-size:.83rem;color:var(--text2);line-height:1.65;border-top:1px solid var(--border);">
                Ghostddit fetches data live from Reddit's API on every search — no cached or stale data. Each search returns the most up-to-date posts and comments available in Reddit's index at that moment.
            </div>
        </details>

        <details style="margin-bottom:10px;background:var(--bg2);border:1px solid var(--border);border-radius:10px;overflow:hidden;">
            <summary style="padding:14px 16px;cursor:pointer;font-size:.88rem;font-weight:600;color:var(--text);list-style:none;display:flex;justify-content:space-between;align-items:center;">Can I share a direct link to a user's results?<span style="color:var(--accent);font-size:.8rem;flex-shrink:0;margin-left:8px;">▾</span></summary>
            <div style="padding:12px 16px 14px;font-size:.83rem;color:var(--text2);line-height:1.65;border-top:1px solid var(--border);">
                Yes. Use <code style="background:var(--bg3);padding:2px 6px;border-radius:4px;font-size:.85em;color:var(--accent)">ghostddit.pages.dev/user/USERNAME</code> for posts or add <code style="background:var(--bg3);padding:2px 6px;border-radius:4px;font-size:.85em;color:var(--accent)">?type=comment</code> for comments. Add <code style="background:var(--bg3);padding:2px 6px;border-radius:4px;font-size:.85em;color:var(--accent)">?sort=top</code> to pre-set sort order.
            </div>
        </details>

        <details style="margin-bottom:10px;background:var(--bg2);border:1px solid var(--border);border-radius:10px;overflow:hidden;">
            <summary style="padding:14px 16px;cursor:pointer;font-size:.88rem;font-weight:600;color:var(--text);list-style:none;display:flex;justify-content:space-between;align-items:center;">Can I request removal of my data?<span style="color:var(--accent);font-size:.8rem;flex-shrink:0;margin-left:8px;">▾</span></summary>
            <div style="padding:12px 16px 14px;font-size:.83rem;color:var(--text2);line-height:1.65;border-top:1px solid var(--border);">
                Ghostddit only displays publicly indexed Reddit data. To remove your activity, delete your posts and comments directly through Reddit. For additional requests, contact <a href="https://www.reddit.com/user/Aryan_Raj_7167/" style="color:var(--accent);text-decoration:none;" target="_blank" rel="noopener">u/Aryan_Raj_7167</a>.
            </div>
        </details>

    </section>

    <!-- KEYWORD CLOUD -->
    <div style="margin-top:24px;padding:16px;background:var(--bg2);border:1px solid var(--border);border-radius:10px;">
        <p style="font-size:0.75rem;color:var(--text3);line-height:1.8;text-align:center;">
            Reddit Hidden Profile Finder · Reddit Hidden Account Posts · Reddit Hidden Comments · Find Hidden Reddit Posts · Find Reddit Comments · Ghostddit · View Hidden Reddit Profile · Reddit Post Search by User · Reddit Comment History Finder · Reddit Hidden User Posts · Reddit Profile Viewer · Hidden Reddit Account Lookup · View Reddit Comment History
        </p>
    </div>

    <!-- FOOTER -->
    <footer style="margin-top:32px;padding:20px;text-align:center;font-size:0.8rem;color:var(--text3);border-top:1px solid var(--border);">
        <p style="margin-bottom:8px;">
            Created by <a href="https://www.reddit.com/user/Aryan_Raj_7167/" target="_blank" rel="noopener" style="color:var(--accent);text-decoration:none;">u/Aryan_Raj_7167</a>
        </p>
        <p style="font-size:0.75rem;margin-bottom:6px;">
            Using <a href="https://www.reddit.com/dev/api/" target="_blank" rel="noopener" style="color:var(--text3);text-decoration:underline;">Reddit's Public API</a> · No login required · Free forever
        </p>
        <p style="font-size:0.72rem;color:var(--text3);margin-top:8px;">
            Ghostddit is not affiliated with or endorsed by Reddit, Inc.
        </p>
    </footer>

</main>

<script>
    let currentUser = '';
    let currentSort = 'new';
    let currentCommentSort = 'new';
    let currentActivitySort = 'activity-desc';
    let currentTab = 'posts'; // 'posts' | 'comments' | 'activity'
    let nsfwSubs = new Set(); // subreddit names (lowercase) known to be over18
    let afterToken  = null;
    let allPosts    = [];
    let allComments = [];
    let seenIds     = new Set();
    let seenCommentIds = new Set();
    let currentTheme = 'system';
    let selectedSubreddits = new Set();
    let selectedCommentSubs = new Set();
    let commentsFetched = false;

    // ── TEXT SEARCH STATE ─────────────────────────────────────────────────────
    let textSearchQuery = '';
    let textSearchTimer = null;

    function getSystemTheme() {
        return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
    }

    function applyTheme(theme) {
        const html = document.documentElement;
        if (theme === 'system') {
            const systemTheme = getSystemTheme();
            html.setAttribute('data-theme', systemTheme);
        } else {
            html.setAttribute('data-theme', theme);
        }
    }

    function updateThemeButton() {
        const btn = document.getElementById('themeBtn');
        switch(currentTheme) {
            case 'system': btn.textContent = '🖥️ System'; break;
            case 'light':  btn.textContent = '☀️ Light'; break;
            case 'dark':   btn.textContent = '🌙 Dark'; break;
        }
    }

    function cycleTheme() {
        const themes = ['system', 'light', 'dark'];
        const idx = themes.indexOf(currentTheme);
        currentTheme = themes[(idx + 1) % themes.length];
        localStorage.setItem('theme', currentTheme);
        applyTheme(currentTheme);
        updateThemeButton();
    }

    function initTheme() {
        const saved = localStorage.getItem('theme');
        currentTheme = saved || 'system';
        applyTheme(currentTheme);
        updateThemeButton();

        window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {
            if (currentTheme === 'system') {
                applyTheme('system');
            }
        });
    }

    // ── TEXT SEARCH HELPERS ───────────────────────────────────────────────────

    function updateTextSearchVisibility() {
        const row = $('textSearchRow');
        const shouldShow = currentTab !== 'activity' && currentUser && (
            (currentTab === 'posts' && allPosts.length > 0) ||
            (currentTab === 'comments' && allComments.length > 0)
        );
        row.classList.toggle('visible', !!shouldShow);
        if (!shouldShow) {
            clearTextSearch(true);
        }
    }

    function onTextSearch() {
        clearTimeout(textSearchTimer);
        textSearchTimer = setTimeout(() => {
            textSearchQuery = $('textSearchInput').value.trim().toLowerCase();
            const clearBtn = $('textSearchClear');
            clearBtn.classList.toggle('visible', textSearchQuery.length > 0);
            if (currentTab === 'posts') {
                applySortToAllPosts(currentSort);
            } else if (currentTab === 'comments') {
                applySortToAllComments(currentCommentSort);
            }
        }, 150);
    }

    function clearTextSearch(silent) {
        textSearchQuery = '';
        const inp = $('textSearchInput');
        if (inp) inp.value = '';
        const clearBtn = $('textSearchClear');
        if (clearBtn) clearBtn.classList.remove('visible');
        const countEl = $('textSearchCount');
        if (countEl) { countEl.textContent = ''; countEl.className = 'text-search-count'; }
        if (!silent) {
            if (currentTab === 'posts') applySortToAllPosts(currentSort);
            else if (currentTab === 'comments') applySortToAllComments(currentCommentSort);
        }
    }

    function updateTextSearchCount(matched, total) {
        const el = $('textSearchCount');
        if (!textSearchQuery) {
            el.textContent = '';
            el.className = 'text-search-count';
            return;
        }
        el.textContent = matched + '/' + total;
        el.className = 'text-search-count' + (matched > 0 ? ' has-results' : '');
    }

    function filterPostsByText(posts) {
        if (!textSearchQuery) return posts;
        return posts.filter(p => {
            const d = p.data;
            return (
                (d.title || '').toLowerCase().includes(textSearchQuery) ||
                (d.selftext || '').toLowerCase().includes(textSearchQuery) ||
                (d.subreddit || '').toLowerCase().includes(textSearchQuery)
            );
        });
    }

    function filterCommentsByText(comments) {
        if (!textSearchQuery) return comments;
        return comments.filter(c =>
            (c.body || '').toLowerCase().includes(textSearchQuery) ||
            (c.subreddit || '').toLowerCase().includes(textSearchQuery)
        );
    }

    function escapeRegex(s) {
        return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
    }

    function highlightText(html) {
        if (!textSearchQuery) return html;
        const re = new RegExp('(' + escapeRegex(textSearchQuery) + ')', 'gi');
        return html.replace(/>([^<]*)</g, (m, text) => {
            if (!text) return m;
            const highlighted = text.replace(re, '<mark class="rg-highlight">$1</mark>');
            return '>' + highlighted + '<';
        });
    }

    // ── SORT / FILTER ─────────────────────────────────────────────────────────

    function applySortToAllPosts(sort) {
        let posts = selectedSubreddits.size > 0
            ? allPosts.filter(p => selectedSubreddits.has(p.data.subreddit.toLowerCase()))
            : allPosts.slice();

        if (sort === 'new') {
            posts.sort((a, b) => b.data.created_utc - a.data.created_utc);
        } else if (sort === 'old') {
            posts.sort((a, b) => a.data.created_utc - b.data.created_utc);
        } else if (sort === 'top') {
            posts.sort((a, b) => b.data.score - a.data.score);
        } else if (sort === 'hot') {
            posts.sort((a, b) => b.data.upvote_ratio - a.data.upvote_ratio || b.data.score - a.data.score);
        } else if (sort === 'comments') {
            posts.sort((a, b) => b.data.num_comments - a.data.num_comments);
        }

        const totalBeforeText = posts.length;
        const filtered = filterPostsByText(posts);
        updateTextSearchCount(filtered.length, totalBeforeText);

        renderPosts(filtered);
    }

    function applySortToAllComments(sort) {
        let comments = selectedCommentSubs.size > 0
            ? allComments.filter(c => selectedCommentSubs.has(c.subreddit.toLowerCase()))
            : allComments.slice();

        if (sort === 'new') {
            comments.sort((a, b) => b.created_utc - a.created_utc);
        } else if (sort === 'old') {
            comments.sort((a, b) => a.created_utc - b.created_utc);
        } else if (sort === 'top') {
            comments.sort((a, b) => b.score - a.score);
        } else if (sort === 'hot') {
            comments.sort((a, b) => b.score - a.score);
        }

        const totalBeforeText = comments.length;
        const filtered = filterCommentsByText(comments);
        updateTextSearchCount(filtered.length, totalBeforeText);

        if (currentTab === 'comments') {
            renderComments(filtered);
        }
    }

    function selectSort(sort) {
        if (currentTab === 'posts') {
            currentSort = sort;
        } else {
            currentCommentSort = sort;
        }
        document.querySelectorAll('.feed-dropdown-item').forEach(el => {
            el.classList.toggle('selected', el.dataset.sort === sort);
        });
        updateFeedOptionsBtnLabel(sort);
        closeFeedDropdown();

        if (currentUser && $('profileCard').classList.contains('on')) {
            pushParams(currentUser, currentSort, currentCommentSort, currentTab === 'posts' ? 'post' : 'comment');
            if (currentTab === 'posts') {
                applySortToAllPosts(currentSort);
            } else {
                applySortToAllComments(currentCommentSort);
            }
        }
    }

    function updateFeedOptionsBtnLabel(sort) {
        const labels = {hot:'Hot',new:'New',old:'Old',top:'Top',comments:'Most Commented'};
        const svgIcon = `<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><circle cx="9" cy="5" r="1.5"/><circle cx="9" cy="12" r="1.5"/><circle cx="9" cy="19" r="1.5"/><line x1="9" y1="5" x2="20" y2="5"/><line x1="9" y1="12" x2="20" y2="12"/><line x1="9" y1="19" x2="20" y2="19"/><line x1="4" y1="5" x2="7.5" y2="5"/><line x1="4" y1="12" x2="7.5" y2="12"/><line x1="4" y1="19" x2="7.5" y2="19"/></svg>`;
        $('feedOptionsBtn').innerHTML = svgIcon + (labels[sort] || sort);
    }

    function setSort(sort) { selectSort(sort); }

    function toggleFeedOptions() {
        const dd = $('feedDropdown');
        dd.classList.toggle('open');
        $('subDropdown') && $('subDropdown').classList.remove('open');
    }

    function closeFeedDropdown() {
        $('feedDropdown').classList.remove('open');
    }

    function toggleSubDropdown() {
        const dd = $('subDropdown');
        dd.classList.toggle('open');
        if (dd.classList.contains('open')) {
            $('subSearchInput').value = '';
            filterSubList();
            setTimeout(() => $('subSearchInput').focus(), 50);
        }
        $('feedDropdown').classList.remove('open');
    }

    function closeSubDropdown() {
        $('subDropdown') && $('subDropdown').classList.remove('open');
    }

    document.addEventListener('click', function(e) {
        if (!e.target.closest('.feed-options-wrap')) closeFeedDropdown();
        if (!e.target.closest('.sub-filter-wrap')) closeSubDropdown();
    });

    function switchTab(tab, skipPush) {
        currentTab = tab;
        $('tabPosts').classList.toggle('active', tab === 'posts');
        $('tabComments').classList.toggle('active', tab === 'comments');
        $('tabActivity').classList.toggle('active', tab === 'activity');

        $('feedControlsRow').style.display = tab === 'activity' ? 'none' : '';
        $('activityControlsRow').style.display = tab === 'activity' ? '' : 'none';

        document.querySelectorAll('.posts-only').forEach(el => {
            el.classList.toggle('hidden-item', tab !== 'posts');
        });

        if (tab === 'comments' && currentCommentSort === 'comments') currentCommentSort = 'new';

        if (tab !== 'activity') {
            const activeSort = tab === 'posts' ? currentSort : currentCommentSort;
            document.querySelectorAll('.feed-dropdown-item').forEach(el => {
                el.classList.toggle('selected', el.dataset.sort === activeSort);
            });
            updateFeedOptionsBtnLabel(activeSort);
        }

        $('statLabel').textContent = tab === 'posts' ? 'Posts found' : tab === 'comments' ? 'Comments found' : 'Subreddits';

        if (tab !== 'activity') buildSubredditDropdown();

        if (!skipPush && currentUser) {
            const typeParam = tab === 'posts' ? 'post' : tab === 'comments' ? 'comment' : 'activity';
            pushParams(currentUser, currentSort, currentCommentSort, typeParam);
        }

        updateTextSearchVisibility();

        if (tab === 'posts') {
            applySortToAllPosts(currentSort);
            updateStats();
        } else if (tab === 'comments') {
            if (!commentsFetched && !commentsFetching) {
                fetchAndShowComments();
            } else if (commentsFetched) {
                applySortToAllComments(currentCommentSort);
                updateCommentStats();
            }
        } else if (tab === 'activity') {
            renderActivity();
        }
    }

    function $(id) { return document.getElementById(id); }

    function esc(str) {
        const div = document.createElement('div');
        div.textContent = str;
        return div.innerHTML;
    }

    function nsfwTag(subLower) {
        return nsfwSubs.has(subLower) ? '<span class="sub-nsfw">18+</span>' : '';
    }

    function decodeHtmlEntities(str) {
        const textarea = document.createElement('textarea');
        textarea.innerHTML = str;
        return textarea.value;
    }

    function parseUser(str) {
        const s = str.trim().replace(/^\/?(u\/|user\/)?/i, '');
        return s || null;
    }

    let directMode = false;

    async function apiFetch(url) {
        const redditPath = url.replace('https://api.reddit.com', '');
        const sep = redditPath.includes('?') ? '&' : '?';

        let r, data, rawText;

        if (!directMode) {
            try {
                r = await fetch('/api/reddit' + redditPath + sep + '_=' + Date.now(), {
                    headers: { 'Accept': 'application/json' },
                    cache: 'no-store'
                });
            } catch(networkErr) {
                throw new Error('REDDIT_UNAVAILABLE');
            }

            if (r.status === 503) {
                let d503;
                try { d503 = await r.json(); } catch(e) { throw new Error('REDDIT_UNAVAILABLE'); }

                if (d503 && d503.fallback === true) {
                    console.warn('[Ghostddit] Worker blocked by Reddit WAF. Switching to direct mode.');
                    directMode = true;
                } else {
                    throw new Error('REDDIT_UNAVAILABLE');
                }
            }
        }

        if (directMode) {
            try {
                r = await fetch(url + (url.includes('?') ? '&' : '?') + '_=' + Date.now(), {
                    headers: { 'Accept': 'application/json' },
                    cache: 'no-store'
                });
            } catch(networkErr) {
                throw new Error('REDDIT_UNAVAILABLE');
            }
        }

        try {
            rawText = await r.text();
            data = JSON.parse(rawText);
        } catch(parseErr) {
            if (rawText && rawText.trim().startsWith('<')) {
                throw new Error('REDDIT_UNAVAILABLE');
            }
            throw new Error('REDDIT_UNAVAILABLE');
        }

        if (!r.ok || data.error) {
            if (r.status === 404 || data.error === 404) throw new Error('USER_NOT_FOUND');
            if (r.status === 403 || data.error === 403) throw new Error('BANNED_ACCOUNT');
            if (r.status === 429 || r.status >= 500)   throw new Error('REDDIT_UNAVAILABLE');
            if (typeof data.error === 'string' && data.error.includes('DOESNT_EXIST')) throw new Error('USER_NOT_FOUND');
            throw new Error(data.message || 'HTTP ' + r.status);
        }

        return data;
    }

    async function getUserAbout(username) {
        // All data from Arctic Shift — works for active, banned, deleted accounts
        try {
            const resp = await fetch(
                '/api/reddit/user-archive/about?author=' + encodeURIComponent(username),
                { headers: { 'Accept': 'application/json' }, cache: 'no-store' }
            );
            if (resp.ok) {
                const j = await resp.json();
                if (j && j.data && j.data.name) return j.data;
            }
            if (resp.status === 404) throw new Error('User not found');
        } catch(e) {
            if (e.message === 'User not found') throw e;
        }
        throw new Error('User not found');
    }

    async function isHidden(u) {
        try {
            const d = await apiFetch('https://api.reddit.com/user/' + encodeURIComponent(u) + '/submitted?limit=100');

            if (!d || !d.data) return { hidden: false };

            const children = d.data.children || [];

            if (children.length === 0) return { hidden: true };

            const nonProfilePosts = children.filter(c => c.data && c.data.subreddit_type !== 'user');

            return { hidden: nonProfilePosts.length === 0 };
        } catch(e) { return { hidden: false }; }
    }

    let isNsfwAccount = false;

    function arcticPostToRedditItem(p) {
        return {
            kind: 't3',
            data: {
                id:                    p.id,
                name:                  't3_' + p.id,
                title:                 p.title || '',
                selftext:              p.selftext || '',
                subreddit:             p.subreddit || '',
                subreddit_name_prefixed: p.subreddit_name_prefixed || ('r/' + p.subreddit),
                author:                p.author || '',
                score:                 p.score || 0,
                upvote_ratio:          p.upvote_ratio || 0,
                num_comments:          p.num_comments || 0,
                created_utc:           p.created_utc || 0,
                permalink:             p.permalink || '',
                url:                   p.url || '',
                is_self:               p.is_self || false,
                is_video:              p.is_video || false,
                is_gallery:            p.is_gallery || false,
                media_metadata:        p.media_metadata || null,
                post_hint:             p.post_hint || '',
                over_18:               p.over_18 || false,
                thumbnail:             p.thumbnail || '',
                preview:               p.preview || null,
                media:                 p.media || null,
                pinned:                p.pinned || false,
                subreddit_type:        p.subreddit_type || 'public',
            }
        };
    }

    async function fetchPosts(username, sort, after) {
        const q = 'author:"' + username + '"';
        let url = 'https://api.reddit.com/search/?q=' + encodeURIComponent(q) + '&sort=' + sort + '&limit=25';
        if (after) url += '&after=' + after;

        const data = await apiFetch(url);
        const posts = [];

        if (data && data.data) {
            afterToken = data.data.after || null;
            (data.data.children || []).forEach(function(item) {
                if (item.kind === 't3' && !seenIds.has(item.data.id)) {
                    seenIds.add(item.data.id);
                    posts.push(item);
                    if (item.data.over_18) nsfwSubs.add(item.data.subreddit.toLowerCase());
                }
            });
        }

        return posts;
    }

    async function fetchNsfwPosts(username, before) {
        let url = '/api/reddit/posts/search?author=' + encodeURIComponent(username) + '&limit=100';
        if (before) url += '&before=' + before;

        let resp, data;
        try {
            resp = await fetch(url);
            data = await resp.json();
        } catch(e) { return { items: [], before: null }; }

        const items = (data.data || [])
            .filter(p => !seenIds.has(p.id))
            .map(p => {
                seenIds.add(p.id);
                if (p.over_18) nsfwSubs.add((p.subreddit || '').toLowerCase());
                return arcticPostToRedditItem(p);
            });

        const oldest = items.length
            ? Math.min(...items.map(p => p.data.created_utc))
            : null;

        return { items, before: items.length >= 100 ? oldest : null };
    }

    async function fetchAllPosts(username) {
        afterToken = null;
        seenIds = new Set();
        allPosts = [];

        if (isNsfwAccount) {
            let before = null;
            let page = 0;
            while (true) {
                page++;
                if (page > 1) setStatus('Fetching posts… (page ' + page + ')');
                const { items, before: nextBefore } = await fetchNsfwPosts(username, before);
                if (!items.length) break;
                allPosts = allPosts.concat(items);
                if (currentTab === 'posts') applySortToAllPosts(currentSort);
                else if (currentTab === 'activity') renderActivity();
                buildSubredditDropdown();
                updateStats();
                if (!nextBefore) break;
                before = nextBefore;
                await new Promise(r => setTimeout(r, 300));
            }
        } else {
            const firstPage = await fetchPosts(username, 'relevance', null);
            allPosts = firstPage;
            if (currentTab === 'posts') applySortToAllPosts(currentSort);
            else if (currentTab === 'activity') renderActivity();
            buildSubredditDropdown();
            updateStats();

            let page = 1;
            while (afterToken) {
                page++;
                setStatus('Fetching posts… (page ' + page + ')');
                await new Promise(r => setTimeout(r, 600));
                const more = await fetchPosts(username, 'relevance', afterToken);
                if (!more.length) break;
                allPosts = allPosts.concat(more);
                if (currentTab === 'posts') applySortToAllPosts(currentSort);
                else if (currentTab === 'activity') renderActivity();
                buildSubredditDropdown();
                updateStats();
            }
        }

        updateTextSearchVisibility();
    }

    function setStatus(msg) {
        $('statusText').textContent = msg;
        $('statusBar').classList.add('on');
    }

    function hideStatus() {
        $('statusBar').classList.remove('on');
    }

    function showAlert(msg, type) {
        const el = $('alertBox');
        el.textContent = msg;
        el.className = 'alert on ' + type;
    }

    function hideAlert() {
        $('alertBox').className = 'alert';
    }

    function timeAgo(unix) {
        const now = Date.now() / 1000;
        const diff = Math.floor(now - unix);
        const m = 60, h = 3600, d = 86400, w = 604800, y = 31536000;
        if (diff < m) return diff + 's ago';
        if (diff < h) return Math.floor(diff / m) + 'm ago';
        if (diff < d) return Math.floor(diff / h) + 'h ago';
        if (diff < w) return Math.floor(diff / d) + 'd ago';
        if (diff < y) return Math.floor(diff / w) + 'w ago';
        return Math.floor(diff / y) + 'y ago';
    }

    function extractPreviewUrl(d) {
        if (d.preview && d.preview.images && d.preview.images[0]) {
            const img = d.preview.images[0];
            if (img.source && img.source.url) {
                return decodeURIComponent(img.source.url).replace(/&amp;/g, '&');
            }
        }

        if (d.is_gallery && d.media_metadata) {
            const firstId = Object.keys(d.media_metadata)[0];
            const firstItem = d.media_metadata[firstId];
            if (firstItem && firstItem.s && firstItem.s.u) {
                return decodeURIComponent(firstItem.s.u).replace(/&amp;/g, '&');
            }
        }

        if (d.selftext) {
            const previewMatch = d.selftext.match(/https?:\/\/preview\.redd\.it\/[^\s)]+/);
            if (previewMatch) {
                return previewMatch[0];
            }
        }

        return null;
    }

    function proxyVideoUrl(u) {
        return '/api/reddit/video-proxy?url=' + encodeURIComponent(u);
    }

    function getMediaHtml(d) {
        if (d.is_video && d.media && d.media.reddit_video) {
            const v = d.media.reddit_video;
            const mp4Url = proxyVideoUrl(v.fallback_url);
            return '<div class="card-media-wrap">' +
                '<video class="card-media" controls preload="metadata" src="' + esc(mp4Url) + '">' +
                '</video></div>';
        }

        const previewUrl = extractPreviewUrl(d);
        if (previewUrl) {
            return '<div class="card-media-wrap">' +
                '<img class="card-media" src="' + esc(previewUrl) + '" alt="Post media" loading="lazy">' +
                '</div>';
        }

        if (d.url && /\.(jpg|jpeg|png|gif|webp)$/i.test(d.url)) {
            return '<div class="card-media-wrap">' +
                '<img class="card-media" src="' + esc(d.url) + '" alt="Post image" loading="lazy">' +
                '</div>';
        }

        if (d.url && (d.url.includes('imgur.com') || d.url.includes('i.imgur.com'))) {
            if (d.url.includes('.gifv')) {
                const mp4 = d.url.replace('.gifv', '.mp4');
                return '<div class="card-media-wrap">' +
                    '<video class="card-media" controls loop muted preload="metadata">' +
                    '<source src="' + esc(mp4) + '" type="video/mp4">' +
                    '</video></div>';
            }
        }

        if (d.url && (d.url.includes('v.redd.it') || d.url.includes('youtube') || d.url.includes('youtu.be'))) {
            const thumb = d.thumbnail && d.thumbnail !== 'self' && d.thumbnail.startsWith('http')
                ? d.thumbnail
                : (extractPreviewUrl(d) || '');
            if (thumb) {
                return '<div class="card-media-wrap" style="position:relative">' +
                    '<img class="card-media" src="' + esc(thumb) + '" alt="Video thumbnail" loading="lazy">' +
                    '<div style="position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);' +
                    'background:rgba(0,0,0,.65);border-radius:50%;width:48px;height:48px;' +
                    'display:flex;align-items:center;justify-content:center;pointer-events:none">' +
                    '<span style="color:#fff;font-size:20px;margin-left:4px">&#9654;</span></div></div>';
            }
        }

        return '';
    }

    const COMMENT_IMG_STYLE = 'max-width:100%;border-radius:8px;margin:8px 0;display:block;cursor:pointer;';

    function renderMarkdown(text) {
        if (!text) return '';
        text = decodeHtmlEntities(text);
        var t = text;
        t = t.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');

        t = t.replace(/^### (.+)$/gm, '<h3 style="font-size:1rem;font-weight:700;margin:8px 0 4px 0;color:var(--text)">$1</h3>');
        t = t.replace(/^## (.+)$/gm, '<h2 style="font-size:1.1rem;font-weight:700;margin:10px 0 6px 0;color:var(--text)">$1</h2>');
        t = t.replace(/^# (.+)$/gm, '<h1 style="font-size:1.2rem;font-weight:700;margin:12px 0 8px 0;color:var(--text)">$1</h1>');

        t = t.replace(/!\[gif\]\(giphy\|([^)]+)\)/gi, function(_, id) {
            const src = 'https://media.giphy.com/media/' + id + '/giphy.gif';
            const href = 'https://giphy.com/gifs/' + id;
            return '<a href="' + href + '" target="_blank" rel="noopener noreferrer"><img src="' + src + '" alt="gif" style="' + COMMENT_IMG_STYLE + '" onerror="this.parentElement.style.display=\'none\'"></a>';
        });

        t = t.replace(/!\[([^\]]*)\]\((https?:\/\/[^)]+)\)/g, function(_, alt, url) {
            const decoded = url.replace(/&amp;/g, '&');
            return '<a href="' + decoded + '" target="_blank" rel="noopener noreferrer"><img src="' + decoded + '" alt="' + (alt || 'image') + '" style="' + COMMENT_IMG_STYLE + '" onerror="this.parentElement.style.display=\'none\'"></a>';
        });

        t = t.replace(/\[([^\]]+)\]\((https?:\/\/[^)]+)\)/g,
            '<a href="$2" target="_blank" rel="noopener noreferrer" style="color:var(--accent);text-decoration:none;border-bottom:1px solid var(--accent)">$1</a>');
        t = t.replace(/\[([^\]]+)\]\((\/[^)]+)\)/g,
            '<a href="https://reddit.com$2" target="_blank" rel="noopener noreferrer" style="color:var(--accent);text-decoration:none;border-bottom:1px solid var(--accent)">$1</a>');

        t = t.replace(/(^|\n)(https?:\/\/(?:preview\.redd\.it|i\.redd\.it|i\.imgur\.com|i\.ibb\.co)[^\s<]+)/g, function(_, pre, url) {
            const decoded = url.replace(/&amp;/g, '&');
            return pre + '<a href="' + decoded + '" target="_blank" rel="noopener noreferrer"><img src="' + decoded + '" alt="image" style="' + COMMENT_IMG_STYLE + '" onerror="this.parentElement.style.display=\'none\'"></a>';
        });

        t = t.replace(/(^|\n)(https?:\/\/[^\s<]+\.(?:jpg|jpeg|png|gif|webp)(?:\?[^\s<]*)?)/gi, function(_, pre, url) {
            const decoded = url.replace(/&amp;/g, '&');
            return pre + '<a href="' + decoded + '" target="_blank" rel="noopener noreferrer"><img src="' + decoded + '" alt="image" style="' + COMMENT_IMG_STYLE + '" onerror="this.parentElement.style.display=\'none\'"></a>';
        });

        t = t.replace(/((?:^\|.+\|\n?)+)/gm, function(block) {
            const lines = block.trim().split('\n');
            const rows = lines.map(line => {
                const cells = line.split('|').slice(1,-1).map(c => c.trim());
                if (cells.every(c => /^[-: ]+$/.test(c))) return null;
                return '<tr>' + cells.map(c =>
                    '<td style="padding:5px 10px;border:1px solid var(--border);font-size:.82rem;vertical-align:top">' + c + '</td>'
                ).join('') + '</tr>';
            }).filter(Boolean);
            if (!rows.length) return '';
            return '<div style="overflow-x:auto;margin:8px 0"><table style="border-collapse:collapse;width:100%">' + rows.join('') + '</table></div>';
        });

        t = t.replace(/\*\*(.+?)\*\*/g, '<strong style="font-weight:700;color:var(--text)">$1</strong>');
        t = t.replace(/__(.+?)__/g, '<strong style="font-weight:700;color:var(--text)">$1</strong>');
        t = t.replace(/\*([^*]+)\*/g, '<em>$1</em>');
        t = t.replace(/_([^_]+)_/g, '<em>$1</em>');
        t = t.replace(/~~(.+?)~~/g, '<s>$1</s>');

        t = t.replace(/`([^`]+)`/g, '<code style="background:var(--bg3);padding:2px 6px;border-radius:4px;font-family:monospace;font-size:.85em;color:var(--accent)">$1</code>');
        t = t.replace(/^(---|\*\*\*)$/gm, '<hr style="border:none;border-top:1px solid var(--border);margin:12px 0">');
        t = t.replace(/(^|\n)&gt; ?([^\n]*)/g,
            '$1<blockquote style="border-left:3px solid var(--accent);padding-left:12px;margin:8px 0;color:var(--text3);font-style:italic">$2</blockquote>');
        t = t.replace(/^[\-\*] (.+)$/gm, '<li style="margin-left:20px;margin-bottom:4px">$1</li>');

        t = t.replace(/\^\(([^)]+)\)/g, '<sup style="font-size:.7em;color:var(--text3)">$1</sup>');
        t = t.replace(/\^(\S+)/g, '<sup style="font-size:.7em;color:var(--text3)">$1</sup>');

        t = t.replace(/\n\n/g, '<br><br>').replace(/\n/g, '<br>');
        t = t.replace(/(<br>)+(<\/?(div|table|tr|td|h[1-3]|hr|blockquote|li)[^>]*>)/gi, '$2');
        t = t.replace(/(<\/?(div|table|tr|td|h[1-3]|hr|blockquote|li)[^>]*>)(<br>)+/gi, '$1');

        return t;
    }

    function getPostType(d) {
        if (d.is_video || (d.media && d.media.reddit_video)) return { type: 'video', label: 'Video' };
        if (d.is_gallery || d.media_metadata) return { type: 'gallery', label: 'Gallery' };
        if (d.post_hint === 'image' || (d.url && /\.(jpg|jpeg|png|gif|webp)$/i.test(d.url))) return { type: 'image', label: 'Image' };
        if (d.is_self || d.selftext) return { type: 'text', label: 'Text' };
        return { type: 'link', label: 'Link' };
    }

    function renderPost(p) {
        const d   = p.data;
        const url = 'https://reddit.com' + d.permalink;
        const sub = d.subreddit_name_prefixed || ('r/' + d.subreddit);
        const media = getMediaHtml(d);
        const { type, label } = getPostType(d);

        const bodyText = d.selftext || '';
        const isJustUrl = /^https?:\/\/\S+$/.test(bodyText.trim());
        const isPreviewUrl = /^https?:\/\/preview\.redd\.it\/\S+$/.test(bodyText.trim());
        const body = (bodyText && !isJustUrl && !isPreviewUrl)
            ? '<div class="card-body">' + renderMarkdown(bodyText) + '</div>'
            : '';

        const typeBadge = '<span class="post-type ' + type + '">' + label + '</span>';
        const comments = d.num_comments || 0;

        let html = '<div class="card">' +
            '<div class="card-title"><a href="' + url + '" target="_blank" rel="noopener">' + esc(d.title || 'Untitled') + '</a></div>' +
            '<span class="card-sub">' + esc(sub) + '</span>' + nsfwTag(d.subreddit.toLowerCase()) + typeBadge +
            media + body +
            '<div class="card-foot">' +
                '<span class="card-score"><span class="arrow">▲</span>' + (d.score||0) + '</span>' +
                '<span class="card-comments">💬 ' + comments + '</span>' +
                '<span class="card-time">' + timeAgo(d.created_utc) + '</span>' +
                '<a class="card-open" href="' + url + '" target="_blank" rel="noopener">Open ↗</a>' +
            '</div></div>';

        if (textSearchQuery) html = highlightText(html);
        return html;
    }

    function initHlsVideos(container) {
        const videos = (container || document).querySelectorAll('video[data-hls]');
        if (!videos.length) return;
        videos.forEach(video => {
            if (video.dataset.hlsInit) return;
            video.dataset.hlsInit = '1';
            video.src = video.dataset.mp4;
        });
    }

    const CHUNK_SIZE = 20;
    let renderQueue = [];
    let renderTimer = null;
    let scrollSentinel = null;
    let scrollObserver = null;

    function cancelRenderQueue() {
        renderQueue = [];
        if (renderTimer) { clearTimeout(renderTimer); renderTimer = null; }
        if (scrollObserver) { scrollObserver.disconnect(); scrollObserver = null; }
        scrollSentinel = null;
    }

    function attachSentinel(container, onMore) {
        if (scrollSentinel) scrollSentinel.remove();
        scrollSentinel = document.createElement('div');
        scrollSentinel.style.cssText = 'height:1px;width:100%;';
        container.appendChild(scrollSentinel);

        if (scrollObserver) scrollObserver.disconnect();
        scrollObserver = new IntersectionObserver(entries => {
            if (entries[0].isIntersecting) onMore();
        }, { rootMargin: '300px' });
        scrollObserver.observe(scrollSentinel);
    }

    function renderChunk(container, items, renderFn, postProcess, chunkIndex) {
        if (!renderQueue.length && chunkIndex >= items.length) {
            if (scrollSentinel) { scrollSentinel.remove(); scrollSentinel = null; }
            if (scrollObserver) { scrollObserver.disconnect(); scrollObserver = null; }
            if (postProcess) postProcess(container);
            return;
        }

        const chunk = items.slice(chunkIndex, chunkIndex + CHUNK_SIZE);
        if (!chunk.length) {
            if (scrollSentinel) { scrollSentinel.remove(); scrollSentinel = null; }
            if (scrollObserver) { scrollObserver.disconnect(); scrollObserver = null; }
            if (postProcess) postProcess(container);
            return;
        }

        const frag = document.createDocumentFragment();
        chunk.forEach(item => {
            const div = document.createElement('div');
            div.innerHTML = renderFn(item);
            while (div.firstChild) frag.appendChild(div.firstChild);
        });
        container.appendChild(frag);

        const nextIndex = chunkIndex + CHUNK_SIZE;
        if (nextIndex < items.length) {
            attachSentinel(container, () => {
                renderChunk(container, items, renderFn, postProcess, nextIndex);
            });
        } else {
            if (scrollSentinel) { scrollSentinel.remove(); scrollSentinel = null; }
            if (scrollObserver) { scrollObserver.disconnect(); scrollObserver = null; }
            if (postProcess) postProcess(container);
        }
    }

    function renderPosts(posts) {
        cancelRenderQueue();
        const list = $('postsList');
        if (!posts.length) {
            list.innerHTML = textSearchQuery
                ? '<div class="empty">No posts match "<strong>' + esc(textSearchQuery) + '</strong>".</div>'
                : '<div class="empty">No posts found for this user.</div>';
            return;
        }
        list.innerHTML = '';
        renderChunk(list, posts, renderPost, (container) => {
            initHlsVideos(container);
        }, 0);
    }

    function renderComments(comments) {
        cancelRenderQueue();
        renderedCommentIds = new Set();
        const list = $('postsList');
        if (!comments.length) {
            list.innerHTML = textSearchQuery
                ? '<div class="empty">No comments match "<strong>' + esc(textSearchQuery) + '</strong>".</div>'
                : '<div class="empty">No comments found for this user.</div>';
            return;
        }
        list.innerHTML = '';
        comments.forEach(c => renderedCommentIds.add(c.id));
        renderChunk(list, comments, renderComment, (container) => {
            fixExpandButtons(container);
        }, 0);
    }

    function updateStats() {
        const count = selectedSubreddits.size > 0
            ? allPosts.filter(p => selectedSubreddits.has(p.data.subreddit.toLowerCase())).length
            : allPosts.length;
        $('statPosts').textContent = count + (afterToken ? '+' : '');
        if (currentTab === 'posts') $('statLabel').textContent = 'Posts found';
    }

    function updateCommentStats() {
        const count = selectedCommentSubs.size > 0
            ? allComments.filter(c => selectedCommentSubs.has(c.subreddit.toLowerCase())).length
            : allComments.length;
        $('statPosts').textContent = count + (commentsFetching ? '+' : '');
        $('statLabel').textContent = 'Comments found';
    }

    function formatNumber(num) {
        if (num >= 1000000) return (num / 1000000).toFixed(1) + 'M';
        if (num >= 1000) return (num / 1000).toFixed(1) + 'K';
        return num.toString();
    }

    function getAccountAge(createdUtc) {
        const now = Date.now() / 1000;
        const ageSeconds = now - createdUtc;
        const years = Math.floor(ageSeconds / 31536000);
        const months = Math.floor((ageSeconds % 31536000) / 2592000);
        const days = Math.floor((ageSeconds % 2592000) / 86400);

        const parts = [];
        if (years > 0) parts.push(years + (years === 1 ? ' year' : ' years'));
        if (months > 0) parts.push(months + (months === 1 ? ' month' : ' months'));
        if (days > 0 && years === 0) parts.push(days + (days === 1 ? ' day' : ' days'));

        return parts.join(', ') || '0 days';
    }

    const DEFAULT_TITLE = 'Ghostddit — Reddit Hidden Profile Viewer | Posts & Comments Finder';
    const DEFAULT_DESC  = 'Ghostddit finds hidden Reddit posts AND comments. Search any Reddit username to see their hidden posts and full comment history — even if their profile is completely hidden. Free, no login required.';

    function updatePageMeta(userData, isHidden) {
        const u     = userData.name;
        const name  = (userData.subreddit && userData.subreddit.title) || u;
        const karma = formatNumber(userData.total_karma || 0);
        const age   = getAccountAge(userData.created_utc);
        const about = ((userData.subreddit && userData.subreddit.public_description) || '').replace(/\n/g, ' ').trim();
        const status = isHidden ? 'Hidden Profile' : 'Public Profile';
        const nsfw   = userData._over18 ? ' · 18+ NSFW' : '';

        const title = 'u/' + u + ' - Ghostddit — Reddit Hidden Profile Viewer';
        const desc  = name + ' (u/' + u + ') — ' + status + nsfw +
            ' · ' + karma + ' karma · Account age: ' + age +
            (about ? ' · "' + about.slice(0, 120) + (about.length > 120 ? '…' : '') + '"' : '') +
            ' · View hidden posts & comments on Ghostddit.';

        const banner = (userData.subreddit && (
            userData.subreddit.banner_img ||
            userData.subreddit.banner_background_image ||
            userData.subreddit.mobile_banner_image
        ) || '').replace(/&amp;/g, '&').split('?')[0];

        let pfp = (userData.icon_img || userData.snoovatar_img || '').replace(/&amp;/g, '&').split('?')[0];

        const ogImage = banner || pfp || 'https://ghostddit.pages.dev/og-image.png';
        const twitterImage = pfp || banner || 'https://ghostddit.pages.dev/og-image.png';

        document.title = title;
        setMeta('name',     'description',         desc);
        setMeta('property', 'og:title',            title);
        setMeta('property', 'og:description',      desc);
        setMeta('property', 'og:url',              window.location.href);
        setMeta('property', 'og:image',            ogImage);
        setMeta('property', 'og:image:alt',        name + ' (u/' + u + ') profile on Ghostddit');
        setMeta('name',     'twitter:title',       title);
        setMeta('name',     'twitter:description', desc);
        setMeta('name',     'twitter:image',       twitterImage);
        setMeta('name',     'twitter:image:alt',   name + ' (u/' + u + ')');
        setMeta('name',     'twitter:card',        banner ? 'summary_large_image' : 'summary');
    }

    function resetPageMeta() {
        document.title = DEFAULT_TITLE;
        setMeta('name',     'description',         DEFAULT_DESC);
        setMeta('property', 'og:title',            'Ghostddit — Reddit Hidden Profile, Posts & Comments Finder');
        setMeta('property', 'og:description',      DEFAULT_DESC);
        setMeta('property', 'og:url',              window.location.origin + '/');
        setMeta('property', 'og:image',            'https://ghostddit.pages.dev/og-image.png');
        setMeta('property', 'og:image:alt',        'Ghostddit — Reddit Hidden Profile, Posts & Comments Finder');
        setMeta('name',     'twitter:title',       'Ghostddit — Reddit Hidden Profile, Posts & Comments Finder');
        setMeta('name',     'twitter:description', 'Find posts AND comments from hidden Reddit profiles. Free, no login needed.');
        setMeta('name',     'twitter:image',       'https://ghostddit.pages.dev/og-image.png');
        setMeta('name',     'twitter:card',        'summary_large_image');
    }

    function setMeta(attrName, attrVal, content) {
        let el = document.querySelector('meta[' + attrName + '="' + attrVal + '"]');
        if (!el) {
            el = document.createElement('meta');
            el.setAttribute(attrName, attrVal);
            document.head.appendChild(el);
        }
        el.setAttribute('content', content);
    }

    function displayAccountInfo(userData, isHidden) {
        let pfp = userData.icon_img || userData.snoovatar_img || 'https://www.redditstatic.com/avatars/defaults/v2/avatar_default_1.png';
        pfp = pfp.replace(/&amp;/g, '&');
        $('accountPfp').src = pfp;

        const banner = (userData.subreddit && (userData.subreddit.banner_img || userData.subreddit.mobile_banner_image)) || '';
        const bannerEl = $('accountBanner');
        if (banner) {
            bannerEl.style.background = 'url(' + banner.replace(/&amp;/g,'&') + ') center/cover no-repeat';
        } else {
            bannerEl.style.background = 'linear-gradient(135deg,#ff4500 0%,#ff6534 50%,#ff8c69 100%)';
        }

        const displayName = (userData.subreddit && userData.subreddit.title) || userData.name;
        $('accountName').textContent = displayName;
        $('accountUsername').textContent = 'u/' + userData.name;

        // Only show 18+ if at least one post from this user is actually NSFW
        $('nsfwBadge').style.display = userData._over18 === true ? 'inline-flex' : 'none';

        const statusBadge = $('accountStatus');
        statusBadge.textContent = '';
        statusBadge.className = 'account-status';
        statusBadge.style.display = 'none';

        const about = (userData.subreddit && userData.subreddit.public_description) || '';
        $('accountAbout').textContent = about ? decodeHtmlEntities(about) : '';
        $('accountAbout').style.display = about ? 'block' : 'none';

        $('totalKarma').textContent = formatNumber(userData.total_karma || 0);
        $('postKarma').textContent = formatNumber(userData.link_karma || 0);
        $('commentKarma').textContent = formatNumber(userData.comment_karma || 0);

        const accountAge = getAccountAge(userData.created_utc);
        $('accountAge').textContent = accountAge;

        $('accountInfo').className = 'rprofile on';
        updatePageMeta(userData, isHidden);
    }

    function getParams() {
        const path = window.location.pathname;
        const match = path.match(/^\/(?:user|u)\/([^/]+)\/?$/i);
        const username = match ? decodeURIComponent(match[1]) : '';
        const p = new URLSearchParams(window.location.search);
        return {
            username,
            sort:        p.get('sort')  || 'new',
            commentSort: p.get('csort') || 'new',
            type:        p.get('type')  || 'post'
        };
    }

    function pushParams(u, s, cs, type) {
        const p = new URLSearchParams();
        if (s    && s    !== 'new') p.set('sort',  s);
        if (cs   && cs   !== 'new')       p.set('csort', cs);
        if (type && type !== 'post')      p.set('type',  type);
        const qs = p.toString() ? '?' + p.toString() : '';
        const newPath = '/user/' + encodeURIComponent(u) + '/' + qs;
        history.pushState({ username: u }, '', newPath);
    }

    function replaceParams(u, s, cs, type) {
        const p = new URLSearchParams();
        if (s    && s    !== 'new') p.set('sort',  s);
        if (cs   && cs   !== 'new')       p.set('csort', cs);
        if (type && type !== 'post')      p.set('type',  type);
        const qs = p.toString() ? '?' + p.toString() : '';
        const newPath = '/user/' + encodeURIComponent(u) + '/' + qs;
        history.replaceState({ username: u }, '', newPath);
    }

    function buildSubredditDropdown() {
        const profileSub = 'u_' + currentUser.toLowerCase();
        const isComments = currentTab === 'comments';
        const items = isComments ? allComments : allPosts;

        const counts = {};
        if (isComments) {
            items.forEach(c => { const s = c.subreddit; counts[s] = (counts[s]||0)+1; });
        } else {
            items.forEach(p => { const s = p.data.subreddit; counts[s] = (counts[s]||0)+1; });
        }

        const subs = Object.keys(counts).sort((a, b) => {
            const aP = a.toLowerCase() === profileSub;
            const bP = b.toLowerCase() === profileSub;
            if (aP) return -1; if (bP) return 1;
            return b - a;
        }).sort((a, b) => {
            const aP = a.toLowerCase() === profileSub;
            const bP = b.toLowerCase() === profileSub;
            if (aP) return -1; if (bP) return 1;
            return counts[b] - counts[a];
        });

        const list = $('subDropdownList');
        list.innerHTML = subs.map((sub, i) => {
            const isProfile = sub.toLowerCase() === profileSub;
            const label = isProfile ? 'u/' + currentUser : 'r/' + sub;
            const selectedSet = isComments ? selectedCommentSubs : selectedSubreddits;
            const isSel = selectedSet.has(sub.toLowerCase());
            const nsfw = nsfwSubs.has(sub.toLowerCase()) ? '<span class="sub-nsfw">18+</span>' : '';
            return `<div class="sub-dropdown-item${isProfile ? ' profile-sub' : ''}${isSel ? ' selected' : ''}" data-sub="${esc(sub.toLowerCase())}" data-label="${esc(label)}" onclick="toggleSubDropdownItem(this)"><span class="sub-label">${esc(label)}${nsfw}</span><span class="sub-count">${counts[sub]}</span></div>`;
        }).join('');

        const wrap = $('subFilterWrap');
        wrap.style.display = subs.length > 1 ? '' : 'none';

        updateSubFilterLabel();
    }

    function filterSubList() {
        const q = $('subSearchInput').value.toLowerCase();
        $('subDropdownList').querySelectorAll('.sub-dropdown-item').forEach(el => {
            el.style.display = el.dataset.label.toLowerCase().includes(q) ? '' : 'none';
        });
    }

    function toggleSubDropdownItem(el) {
        const sub = el.dataset.sub;
        const isComments = currentTab === 'comments';
        const selectedSet = isComments ? selectedCommentSubs : selectedSubreddits;

        if (selectedSet.has(sub)) {
            selectedSet.delete(sub);
            el.classList.remove('selected');
        } else {
            selectedSet.add(sub);
            el.classList.add('selected');
        }
        updateSubFilterLabel();
        if (isComments) {
            applySortToAllComments(currentCommentSort);
            updateCommentStats();
        } else {
            applySortToAllPosts(currentSort);
            updateStats();
        }
    }

    function updateSubFilterLabel() {
        const isComments = currentTab === 'comments';
        const selectedSet = isComments ? selectedCommentSubs : selectedSubreddits;
        const btn = $('subFilterBtn');
        const label = $('subFilterLabel');
        if (selectedSet.size === 0) {
            label.textContent = 'Subreddit';
            btn.classList.remove('active-filter');
        } else if (selectedSet.size === 1) {
            const sub = [...selectedSet][0];
            const isProfile = sub === 'u_' + currentUser.toLowerCase();
            label.textContent = isProfile ? 'u/' + currentUser : 'r/' + sub;
            btn.classList.add('active-filter');
        } else {
            label.textContent = selectedSet.size + ' subreddits';
            btn.classList.add('active-filter');
        }
    }

    function toggleSubredditTag(btn) { toggleSubDropdownItem(btn); }
    function toggleSubFilter() {}

    let commentsFetching = false;
    let commentFetchSession = 0;

    async function fetchAllComments(username) {
        const session = ++commentFetchSession;
        commentsFetching = true;
        allComments = [];
        seenCommentIds = new Set();
        renderedCommentIds = new Set();
        let before = null;
        let page = 0;

        while (true) {
            if (session !== commentFetchSession) return;

            page++;
            setStatus('Fetching comments… (page ' + page + ')');
            let url = '/api/reddit/comments/search?author=' + encodeURIComponent(username) + '&limit=100';
            if (before) url += '&before=' + before;

            let resp, data;
            try {
                resp = await fetch(url);
                data = await resp.json();
            } catch(e) { break; }

            if (session !== commentFetchSession) return;

            const items = data.data || [];
            if (!items.length) break;

            const newItems = [];
            items.forEach(c => {
                if (!seenCommentIds.has(c.id)) {
                    seenCommentIds.add(c.id);
                    allComments.push(c);
                    newItems.push(c);
                    if (c.over_18) nsfwSubs.add((c.subreddit || '').toLowerCase());
                }
            });

            if (currentTab === 'comments' && session === commentFetchSession) {
                if (currentCommentSort === 'new' || currentCommentSort === 'relevance') {
                    if (!textSearchQuery) {
                        appendComments(newItems);
                    } else {
                        applySortToAllComments(currentCommentSort);
                    }
                } else {
                    applySortToAllComments(currentCommentSort);
                }
                updateCommentStats();
                updateTextSearchVisibility();
            } else if (currentTab === 'activity' && session === commentFetchSession) {
                renderActivity();
            }

            buildSubredditDropdown();

            const oldest = Math.min(...items.map(c => c.created_utc));
            if (items.length < 100) break;
            before = oldest;
            await new Promise(r => setTimeout(r, 300));
        }

        if (session !== commentFetchSession) return;

        commentsFetching = false;
        commentsFetched = true;
        if (currentTab === 'comments' && session === commentFetchSession) {
            hideStatus();
            if (currentCommentSort !== 'new' && currentCommentSort !== 'relevance') {
                applySortToAllComments(currentCommentSort);
            } else if (textSearchQuery) {
                applySortToAllComments(currentCommentSort);
            }
            updateCommentStats();
            updateTextSearchVisibility();
        } else if (currentTab === 'activity' && session === commentFetchSession) {
            hideStatus();
            renderActivity();
        }
    }

    async function fetchAndShowComments() {
        $('postsList').innerHTML = '<div class="empty" style="padding:32px 0">Loading comments…</div>';
        if (!commentsFetched && !commentsFetching) {
            await fetchAllComments(currentUser);
        }
        if (currentTab !== 'comments') return;
        applySortToAllComments(currentCommentSort);
        updateCommentStats();
        hideStatus();
        updateTextSearchVisibility();
    }

    function toggleCommentExpand(btn) {
        const body = btn.previousElementSibling;
        const isPreview = body.classList.contains('comment-body-preview');
        if (isPreview) {
            body.classList.remove('comment-body-preview');
            body.classList.add('comment-body-full');
            btn.innerHTML = '<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="18 15 12 9 6 15"/></svg> Show less';
        } else {
            body.classList.remove('comment-body-full');
            body.classList.add('comment-body-preview');
            btn.innerHTML = '<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"/></svg> Show more';
        }
    }

    function renderComment(c) {
        const url = 'https://reddit.com' + c.permalink;
        const sub = c.subreddit_name_prefixed || ('r/' + c.subreddit);
        const body = renderMarkdown(c.body || '');
        const created = typeof c.created_utc === 'string' ? parseInt(c.created_utc, 10) : (c.created_utc || 0);

        const needsExpand = (c.body || '').length > 200 || (c.body || '').split('\n').length > 5;
        const expandBtnHtml = needsExpand
            ? '<button class="comment-expand-btn" onclick="toggleCommentExpand(this)">' +
              '<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"/></svg> Show more</button>'
            : '';
        const bodyClass = needsExpand ? 'comment-body comment-body-preview' : 'comment-body';

        let html = '<div class="comment-card">' +
            '<div class="comment-thread-ctx">' +
                '<span class="card-sub" style="font-size:.72rem">' + esc(sub) + '</span>' +
                nsfwTag((c.subreddit || '').toLowerCase()) +
                '<span style="opacity:.4">·</span>' +
                '<a href="' + esc(url) + '" target="_blank" rel="noopener" style="color:var(--text3);font-size:.75rem;text-decoration:none;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:200px" title="View thread">In thread ↗</a>' +
            '</div>' +
            '<div class="' + bodyClass + '">' + body + '</div>' +
            expandBtnHtml +
            '<div class="comment-foot">' +
                '<span class="card-score"><span class="arrow">▲</span>' + (c.score || 0) + '</span>' +
                '<span class="card-time">' + (created ? timeAgo(created) : '') + '</span>' +
                '<a class="card-open" href="' + esc(url) + '" target="_blank" rel="noopener">View ↗</a>' +
            '</div>' +
        '</div>';

        if (textSearchQuery) html = highlightText(html);
        return html;
    }

    function appendComments(newComments) {
        if (!newComments.length) return;
        const list = $('postsList');
        if (list.querySelector('.empty')) list.innerHTML = '';
        cancelRenderQueue();
        const frag = document.createDocumentFragment();
        newComments.forEach(c => {
            renderedCommentIds.add(c.id);
            const div = document.createElement('div');
            div.innerHTML = renderComment(c);
            while (div.firstChild) frag.appendChild(div.firstChild);
        });
        list.appendChild(frag);
        fixExpandButtons(list);
    }

    let renderedCommentIds = new Set();

    function fixExpandButtons(container) {
        requestAnimationFrame(() => {
            requestAnimationFrame(() => {
                container.querySelectorAll('.comment-expand-btn').forEach(btn => {
                    if (btn.dataset.checked) return;
                    btn.dataset.checked = '1';
                    const body = btn.previousElementSibling;
                    if (!body) return;
                    if (body.scrollHeight < body.clientHeight) {
                        btn.style.display = 'none';
                        body.classList.remove('comment-body-preview');
                    }
                });
            });
        });
    }

    function toggleActivitySortDropdown() {
        $('activitySortDropdown').classList.toggle('open');
    }

    function closeActivitySortDropdown() {
        $('activitySortDropdown') && $('activitySortDropdown').classList.remove('open');
    }

    document.addEventListener('click', function(e) {
        if (!e.target.closest('.activity-sort-wrap')) closeActivitySortDropdown();
    }, true);

    const activitySortLabels = {
        'activity-desc':  'Activity (High → Low)',
        'activity-asc':   'Activity (Low → High)',
        'posts-desc':     'Posts (High → Low)',
        'posts-asc':      'Posts (Low → High)',
        'comments-desc':  'Comments (High → Low)',
        'comments-asc':   'Comments (Low → High)',
        'karma-desc':     'Karma (High → Low)',
        'karma-asc':      'Karma (Low → High)',
    };

    function selectActivitySort(sort) {
        currentActivitySort = sort;
        $('activitySortLabel').textContent = activitySortLabels[sort] || sort;
        document.querySelectorAll('.activity-sort-item').forEach(el => {
            el.classList.toggle('selected', el.dataset.asort === sort);
        });
        closeActivitySortDropdown();
        renderActivity();
    }

    function renderActivity() {
        const postCounts = {}, commentCounts = {}, postKarma = {}, commentKarma = {};

        allPosts.forEach(p => {
            const s = p.data.subreddit;
            postCounts[s] = (postCounts[s] || 0) + 1;
            postKarma[s]  = (postKarma[s]  || 0) + (p.data.score || 0);
        });
        allComments.forEach(c => {
            const s = c.subreddit;
            commentCounts[s] = (commentCounts[s] || 0) + 1;
            commentKarma[s]  = (commentKarma[s]  || 0) + (c.score || 0);
        });

        const allSubs = new Set([...Object.keys(postCounts), ...Object.keys(commentCounts)]);
        let rows = [...allSubs].map(sub => ({
            sub,
            posts:        postCounts[sub]   || 0,
            comments:     commentCounts[sub] || 0,
            total:        (postCounts[sub]   || 0) + (commentCounts[sub] || 0),
            postKarma:    postKarma[sub]    || 0,
            commentKarma: commentKarma[sub] || 0,
            karma:        (postKarma[sub]   || 0) + (commentKarma[sub] || 0),
        }));

        switch (currentActivitySort) {
            case 'activity-desc':  rows.sort((a, b) => b.total        - a.total);        break;
            case 'activity-asc':   rows.sort((a, b) => a.total        - b.total);        break;
            case 'posts-desc':     rows.sort((a, b) => b.posts        - a.posts);        break;
            case 'posts-asc':      rows.sort((a, b) => a.posts        - b.posts);        break;
            case 'comments-desc':  rows.sort((a, b) => b.comments     - a.comments);     break;
            case 'comments-asc':   rows.sort((a, b) => a.comments     - b.comments);     break;
            case 'karma-desc':     rows.sort((a, b) => b.karma        - a.karma);        break;
            case 'karma-asc':      rows.sort((a, b) => a.karma        - b.karma);        break;
        }

        const getBarVal = row => {
            switch (currentActivitySort) {
                case 'posts-desc': case 'posts-asc':       return row.posts;
                case 'comments-desc': case 'comments-asc': return row.comments;
                case 'karma-desc': case 'karma-asc':       return row.karma;
                default:                                    return row.total;
            }
        };
        const maxVal = rows.reduce((m, r) => Math.max(m, getBarVal(r)), 1);

        $('statPosts').textContent = rows.length;
        $('statLabel').textContent = 'Subreddits';

        if (!rows.length) {
            $('postsList').innerHTML = '<div class="empty">No activity data yet — fetch some posts or comments first.</div>';
            return;
        }

        const fetching = afterToken || commentsFetching;
        const isKarmaSort = currentActivitySort.startsWith('karma');

        $('postsList').innerHTML =
            '<div class="activity-header"><span>Subreddit</span><span>' + (fetching ? 'Still loading…' : rows.length + ' subreddits') + '</span></div>' +
            '<div class="post-list">' +
            rows.map((row, i) => {
                const pct = Math.round((getBarVal(row) / maxVal) * 100);
                const isProfile = row.sub.toLowerCase() === 'u_' + currentUser.toLowerCase();
                const label = isProfile ? 'u/' + currentUser : 'r/' + row.sub;
                const href  = isProfile
                    ? 'https://reddit.com/user/' + currentUser
                    : 'https://reddit.com/r/' + row.sub;

                const postsBadge    = row.posts    ? '<span class="activity-badge posts">📝 ' + row.posts    + ' post'    + (row.posts    !== 1 ? 's' : '') + '</span>' : '';
                const commentsBadge = row.comments ? '<span class="activity-badge comments">💬 ' + row.comments + ' comment' + (row.comments !== 1 ? 's' : '') + '</span>' : '';
                const karmaBadge    = isKarmaSort  ? '<span class="activity-badge karma">⬆ ' + formatNumber(row.karma) + ' karma</span>' : '';
                const nsfw = nsfwSubs.has(row.sub.toLowerCase()) ? '<span class="sub-nsfw">18+</span>' : '';

                const displayVal = isKarmaSort ? formatNumber(row.karma) : row.total;

                return '<div class="activity-card">' +
                    '<div class="activity-rank">' + (i + 1) + '</div>' +
                    '<div class="activity-sub">' +
                        '<div class="activity-sub-name"><a href="' + esc(href) + '" target="_blank" rel="noopener">' + esc(label) + '</a>' + nsfw + '</div>' +
                        '<div class="activity-badges">' + postsBadge + commentsBadge + karmaBadge + '</div>' +
                    '</div>' +
                    '<div class="activity-bar-wrap">' +
                        '<div class="activity-bar-bg"><div class="activity-bar-fill" style="width:' + pct + '%"></div></div>' +
                    '</div>' +
                    '<div class="activity-total">' + displayVal + '</div>' +
                '</div>';
            }).join('') +
            '</div>';
    }

    async function startSearch() {
        const username = parseUser($('usernameInput').value);
        if (!username) { showAlert('Please enter a username.', 'error'); return; }

        currentSort = 'new';
        currentCommentSort = 'new';
        currentTab = 'posts';
        isNsfwAccount = false;

        clearTextSearch(true);
        $('textSearchRow').classList.remove('visible');

        replaceParams(username, currentSort, currentCommentSort, 'post');
        currentUser = username;
        afterToken  = null;
        seenIds     = new Set();
        allPosts    = [];
        allComments = [];
        seenCommentIds = new Set();
        renderedCommentIds = new Set();
        commentsFetched = false;
        commentsFetching = false;
        commentFetchSession++;
        selectedSubreddits = new Set();
        nsfwSubs = new Set();
        selectedCommentSubs = new Set();

        $('tabPosts').classList.add('active');
        $('tabComments').classList.remove('active');
        $('tabActivity').classList.remove('active');
        $('contentTabs').style.display = 'none';
        $('feedControlsRow').style.display = 'none';
        $('activityControlsRow').style.display = 'none';
        $('subFilterWrap').style.display = 'none';

        currentActivitySort = 'activity-desc';
        $('activitySortLabel').textContent = 'Activity (High → Low)';
        document.querySelectorAll('.activity-sort-item').forEach(el => {
            el.classList.toggle('selected', el.dataset.asort === 'activity-desc');
        });

        updateFeedOptionsBtnLabel('new');
        $('subFilterLabel').textContent = 'Subreddit';
        $('subFilterBtn').classList.remove('active-filter');

        document.querySelectorAll('.feed-dropdown-item').forEach(el => {
            el.classList.toggle('selected', el.dataset.sort === 'new');
        });
        document.querySelectorAll('.posts-only').forEach(el => el.classList.remove('hidden-item'));

        $('searchBtn').disabled = true;
        $('profileCard').className = 'profile-bar';
        $('accountInfo').className = 'rprofile';
        $('accountPfp').src = '';
        $('accountName').textContent = '';
        $('accountUsername').textContent = '';
        $('accountStatus').textContent = '';
        $('accountStatus').className = 'account-status';
        $('nsfwBadge').style.display = 'none';
        $('accountAbout').textContent = '';
        $('accountAbout').style.display = 'none';
        $('totalKarma').textContent = '0';
        $('postKarma').textContent = '0';
        $('commentKarma').textContent = '0';
        $('accountAge').textContent = '';
        $('postsList').innerHTML = '';
        $('fetchNotice').style.display = 'none';
        $('statLabel').textContent = 'Posts found';
        hideAlert();
        resetPageMeta();

        try {
            setStatus('Checking account…');
            let userData;
            try {
                userData = await getUserAbout(username);
            } catch(e) {
                hideStatus();
                let errorMsg = 'u/' + username + ' does not exist.';
                if (e.message === 'REDDIT_UNAVAILABLE' || e.message.includes('unavailable') || e.message.includes('503')) {
                    errorMsg = '\u26a0\ufe0f Reddit is temporarily unavailable or blocking requests from the server. Retrying directly... please wait.';
                    showAlert(errorMsg, 'warn');
                    setTimeout(() => startSearch(), 1500);
                } else if (e.message.includes('banned') || e.message.includes('suspended')) {
                    errorMsg = 'u/' + username + ' is banned or suspended.';
                    showAlert(errorMsg, 'error');
                } else {
                    showAlert(errorMsg, 'error');
                }
                $('searchBtn').disabled = false;
                return;
            }

            setStatus('Loading profile…');
            isNsfwAccount = !!(userData._over18);
            // All accounts use Arctic — no live Reddit profile check
            displayAccountInfo(userData, false);

            $('profileName').textContent = 'u/' + username;
            $('profileCard').className = 'profile-bar on';
            $('contentTabs').style.display = '';
            $('feedControlsRow').style.display = '';

            setStatus('Fetching posts…');
            isNsfwAccount = true; // Always use Arctic path for all accounts
            await fetchAllPosts(username);
            hideStatus();
            $('fetchNotice').style.display = 'none';

            if (!allPosts.length)
                showAlert('No posts found for this user.', 'info');

        } catch(err) {
            hideStatus();
            showAlert('Error: ' + err.message, 'error');
        }
        $('searchBtn').disabled = false;
    }

    $('usernameInput').addEventListener('keydown', function(e) {
        if (e.key === 'Enter') startSearch();
    });

    document.addEventListener('keydown', function(e) {
        const row = $('textSearchRow');
        if (!row.classList.contains('visible')) return;
        const inp = $('textSearchInput');
        if (document.activeElement && document.activeElement.tagName === 'INPUT') return;
        if (e.key === '/') {
            e.preventDefault();
            inp.focus();
            inp.select();
        }
    });

    let isNavigating = false;
    window.addEventListener('popstate', function() {
        if (isNavigating) return;
        isNavigating = true;

        const { username, sort, commentSort, type } = getParams();

        if (username && username === currentUser) {
            const tab = type === 'comment' ? 'comments' : type === 'activity' ? 'activity' : 'posts';
            if (tab !== currentTab) {
                switchTab(tab, true);
            } else if (sort !== currentSort) {
                currentSort = sort;
                document.querySelectorAll('.feed-dropdown-item').forEach(c => {
                    c.classList.toggle('selected', c.dataset.sort === sort);
                });
                if ($('profileCard').classList.contains('on')) {
                    applySortToAllPosts(sort);
                }
            }
            isNavigating = false;
        } else if (username) {
            $('usernameInput').value = username;
            currentSort = sort;
            document.querySelectorAll('.feed-dropdown-item').forEach(c => {
                c.classList.toggle('selected', c.dataset.sort === sort);
            });
            startSearch().finally(() => { isNavigating = false; });
        } else {
            currentUser = '';
            selectedSubreddits = new Set();
            nsfwSubs = new Set();
            selectedCommentSubs = new Set();
            allComments = [];
            commentsFetched = false;
            $('usernameInput').value = '';
            $('contentTabs').style.display = 'none';
            $('feedControlsRow').style.display = 'none';
            $('activityControlsRow').style.display = 'none';
            $('textSearchRow').classList.remove('visible');
            clearTextSearch(true);
            $('profileCard').className = 'profile-bar';
            $('accountInfo').className = 'rprofile';
            $('postsList').innerHTML = '';
            hideAlert();
            resetPageMeta();
            currentSort = 'new';
            document.querySelectorAll('.feed-dropdown-item').forEach(c => {
                c.classList.toggle('selected', c.dataset.sort === 'new');
            });
            isNavigating = false;
        }
    });

    (function() {
        initTheme();

        if (window.location.pathname.match(/^\/u\//i)) {
            const newPath = window.location.pathname.replace(/^\/u\//i, '/user/') + window.location.search;
            history.replaceState({}, '', newPath);
        }

        const { username, sort, commentSort, type } = getParams();
        currentSort = sort;
        currentCommentSort = commentSort;
        if (type === 'comment') currentTab = 'comments';
        else if (type === 'activity') currentTab = 'activity';

        document.querySelectorAll('.feed-dropdown-item').forEach(c => {
            c.classList.toggle('selected', c.dataset.sort === sort);
        });
        updateFeedOptionsBtnLabel(sort);

        if (username) {
            $('usernameInput').value = username;
            startSearchFromURL(username, sort, commentSort, type);
        }
    })();

    async function startSearchFromURL(username, sort, commentSort, type) {
        currentSort = sort;
        currentCommentSort = commentSort;

        clearTextSearch(true);
        $('textSearchRow').classList.remove('visible');

        replaceParams(username, currentSort, currentCommentSort, type);
        currentUser = username;
        currentTab = 'posts';
        afterToken  = null;
        seenIds     = new Set();
        allPosts    = [];
        allComments = [];
        seenCommentIds = new Set();
        renderedCommentIds = new Set();
        commentsFetched = false;
        commentsFetching = false;
        commentFetchSession++;
        selectedSubreddits = new Set();
        selectedCommentSubs = new Set();

        $('tabPosts').classList.add('active');
        $('tabComments').classList.remove('active');
        $('tabActivity').classList.remove('active');
        $('contentTabs').style.display = 'none';
        $('feedControlsRow').style.display = 'none';
        $('activityControlsRow').style.display = 'none';
        $('subFilterWrap').style.display = 'none';
        updateFeedOptionsBtnLabel(currentSort);
        document.querySelectorAll('.feed-dropdown-item').forEach(el => {
            el.classList.toggle('selected', el.dataset.sort === currentSort);
        });
        document.querySelectorAll('.posts-only').forEach(el => el.classList.remove('hidden-item'));

        $('searchBtn').disabled = true;
        $('profileCard').className = 'profile-bar';
        $('accountInfo').className = 'rprofile';
        $('accountPfp').src = ''; $('accountName').textContent = '';
        $('accountUsername').textContent = ''; $('accountStatus').textContent = '';
        $('accountStatus').className = 'account-status';
        $('accountAbout').textContent = ''; $('accountAbout').style.display = 'none';
        $('nsfwBadge').style.display = 'none';
        $('totalKarma').textContent = '0'; $('postKarma').textContent = '0';
        $('commentKarma').textContent = '0'; $('accountAge').textContent = '';
        $('postsList').innerHTML = ''; $('fetchNotice').style.display = 'none';
        $('statLabel').textContent = 'Posts found';
        hideAlert();

        try {
            setStatus('Checking account…');
            let userData;
            try { userData = await getUserAbout(username); }
            catch(e) {
                hideStatus();
                let errorMsg = 'u/' + username + ' does not exist.';
                if (e.message === 'REDDIT_UNAVAILABLE' || e.message.includes('unavailable') || e.message.includes('503')) {
                    errorMsg = '⚠️ Reddit is temporarily unavailable. Retrying…';
                    showAlert(errorMsg, 'warn');
                    setTimeout(() => startSearchFromURL(username, sort, commentSort, type), 1500);
                } else if (e.message.includes('banned') || e.message.includes('suspended')) {
                    showAlert('u/' + username + ' is banned or suspended.', 'error');
                } else { showAlert(errorMsg, 'error'); }
                $('searchBtn').disabled = false; return;
            }

            setStatus('Loading profile…');
            isNsfwAccount = !!(userData._over18);
            // All accounts use Arctic — no live Reddit profile check
            displayAccountInfo(userData, false);

            $('profileName').textContent = 'u/' + username;
            $('profileCard').className = 'profile-bar on';
            $('contentTabs').style.display = '';
            $('feedControlsRow').style.display = '';

            setStatus('Fetching posts…');
            isNsfwAccount = true; // Always use Arctic path for all accounts
            await fetchAllPosts(username);
            hideStatus();
            $('fetchNotice').style.display = 'none';

            if (!allPosts.length) showAlert('No posts found for this user.', 'info');

            if (type === 'comment') {
                switchTab('comments', true);
            } else if (type === 'activity') {
                switchTab('activity', true);
            }

        } catch(err) { hideStatus(); showAlert('Error: ' + err.message, 'error'); }
        $('searchBtn').disabled = false;
    }
</script>
<!-- ═══════════════════════════════════════════════
     DISCORD BANNER
     ═══════════════════════════════════════════════ -->
<div id="dc-banner" aria-live="polite" aria-label="Join Ghostddit Discord" role="complementary">
    <div class="dc-inner">
        <div class="dc-top-row">
            <div class="dc-left">
                <div class="dc-icon-wrap">
                    <div class="dc-pulse-ring"></div>
                    <svg class="dc-icon" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
                        <path d="M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057.1 18.08.114 18.1.135 18.114a19.9 19.9 0 0 0 5.993 3.03.077.077 0 0 0 .084-.028 14.09 14.09 0 0 0 1.226-1.994.076.076 0 0 0-.041-.106 13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10.2 10.2 0 0 0 .372-.292.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03z"/>
                    </svg>
                </div>
                <div class="dc-text">
                    <span class="dc-headline">Join the community</span>
                    <span class="dc-sub">Chat, suggestions &amp; updates</span>
                </div>
            </div>
            <button class="dc-close" id="dc-close-btn" aria-label="Dismiss Discord banner">
                <svg viewBox="0 0 16 16" fill="currentColor" width="13" height="13" aria-hidden="true">
                    <path d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z"/>
                </svg>
            </button>
        </div>
        <a href="/discord" target="_blank" rel="noopener noreferrer" class="dc-btn" id="dc-join-btn">
            <svg viewBox="0 0 24 24" fill="currentColor" width="15" height="15" aria-hidden="true">
                <path d="M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057.1 18.08.114 18.1.135 18.114a19.9 19.9 0 0 0 5.993 3.03.077.077 0 0 0 .084-.028 14.09 14.09 0 0 0 1.226-1.994.076.076 0 0 0-.041-.106 13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10.2 10.2 0 0 0 .372-.292.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03z"/>
            </svg>
            Join Ghostddit Server
            <svg viewBox="0 0 16 16" fill="currentColor" width="12" height="12" aria-hidden="true">
                <path d="M3 8a.5.5 0 0 1 .5-.5h7.793L9.146 5.354a.5.5 0 1 1 .708-.708l3 3a.5.5 0 0 1 0 .708l-3 3a.5.5 0 0 1-.708-.708L11.293 8.5H3.5A.5.5 0 0 1 3 8z"/>
            </svg>
        </a>
    </div>
</div>

<style>
/* ── Discord Banner ───────────────────────────────────────── */
#dc-banner {
    position: fixed;
    top: 70px;
    left: 50%;
    transform: translateX(-50%) translateY(-160px);
    z-index: 999;
    width: calc(100% - 24px);
    max-width: 520px;
    background: var(--bg2);
    border: 1px solid #5865f235;
    border-radius: 16px;
    box-shadow: 0 8px 32px rgba(0,0,0,0.5), 0 0 0 1px #5865f210;
    overflow: hidden;
    opacity: 0;
    transition: transform 0.5s cubic-bezier(0.34, 1.56, 0.64, 1),
                opacity 0.4s ease;
    pointer-events: none;
}
#dc-banner::before {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(135deg, #5865f20a 0%, transparent 55%);
    pointer-events: none;
    border-radius: inherit;
}
#dc-banner.dc-visible {
    transform: translateX(-50%) translateY(0);
    opacity: 1;
    pointer-events: all;
}
#dc-banner.dc-hiding {
    transform: translateX(-50%) translateY(-160px);
    opacity: 0;
    pointer-events: none;
    transition: transform 0.35s cubic-bezier(0.4, 0, 1, 1),
                opacity 0.3s ease;
}
.dc-inner {
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding: 14px;
}
.dc-top-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
}
.dc-left {
    display: flex;
    align-items: center;
    gap: 10px;
    flex: 1;
    min-width: 0;
}
.dc-icon-wrap {
    position: relative;
    flex-shrink: 0;
    width: 36px;
    height: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
}
.dc-pulse-ring {
    position: absolute;
    top: -2px;
    right: -2px;
    width: 11px;
    height: 11px;
    border-radius: 50%;
    background: #23a55a;
    border: 2px solid var(--bg2);
    z-index: 2;
}
.dc-pulse-ring::before {
    content: '';
    position: absolute;
    inset: -3px;
    border-radius: 50%;
    border: 2px solid #23a55a;
    animation: dc-pulse 2s ease-out infinite;
    opacity: 0;
}
@keyframes dc-pulse {
    0%   { transform: scale(0.8); opacity: 0.9; }
    100% { transform: scale(2.4); opacity: 0; }
}
.dc-icon {
    width: 34px;
    height: 34px;
    color: #5865f2;
    filter: drop-shadow(0 0 6px #5865f240);
}
.dc-text {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}
.dc-headline {
    font-size: 0.9rem;
    font-weight: 700;
    color: var(--text);
    letter-spacing: -0.01em;
    line-height: 1.2;
}
.dc-sub {
    font-size: 0.72rem;
    color: var(--text2);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.dc-close {
    background: var(--bg3);
    border: 1px solid var(--border);
    color: var(--text3);
    border-radius: 8px;
    width: 28px;
    height: 28px;
    min-width: 28px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    flex-shrink: 0;
    transition: border-color 0.2s, color 0.2s, background 0.2s;
}
.dc-close:hover {
    border-color: #ef4444;
    color: #f87171;
    background: rgba(239,68,68,0.08);
}
.dc-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    width: 100%;
    background: #5865f2;
    color: #fff;
    font-family: inherit;
    font-size: 0.88rem;
    font-weight: 700;
    padding: 11px 16px;
    border-radius: 10px;
    text-decoration: none;
    transition: background 0.2s, transform 0.15s, box-shadow 0.2s;
    box-shadow: 0 2px 16px #5865f240;
    letter-spacing: 0.01em;
}
.dc-btn:hover {
    background: #4752c4;
    transform: translateY(-1px);
    box-shadow: 0 4px 24px #5865f260;
}
.dc-btn:active { transform: scale(0.98); }
</style>

<script>
(function () {
    const STORAGE_KEY = 'rg_dc_joined';
    const DELAY_MS    = 4000;

    const banner   = document.getElementById('dc-banner');
    const closeBtn = document.getElementById('dc-close-btn');
    const joinBtn  = document.getElementById('dc-join-btn');

    if (!banner) return;

    if (localStorage.getItem(STORAGE_KEY)) {
        banner.remove();
        return;
    }

    function hideBanner(permanent) {
        banner.classList.remove('dc-visible');
        banner.classList.add('dc-hiding');
        if (permanent) localStorage.setItem(STORAGE_KEY, '1');
        setTimeout(() => banner.remove(), 400);
    }

    setTimeout(() => {
        banner.classList.add('dc-visible');
    }, DELAY_MS);

    closeBtn.addEventListener('click', () => hideBanner(false));
    joinBtn.addEventListener('click', () => hideBanner(true));

    setTimeout(() => {
        if (banner.classList.contains('dc-visible')) hideBanner(false);
    }, DELAY_MS + 12000);
})();
</script>

<!-- Cloudflare Pages Analytics --><script defer src='https://static.cloudflareinsights.com/beacon.min.js' data-cf-beacon='{"token": "308efa42e7b2451f998f9c10084d2784"}'></script><!-- Cloudflare Pages Analytics --></body>
</html>