Files
Huntarr.io/frontend/templates/components/home_section.html
Admin9705 b49041ea6e Refactor
2026-02-20 05:33:36 -05:00

2550 lines
94 KiB
HTML

<section id="homeSection" class="content-section">
<link rel="stylesheet" href="./static/css/home.css">
<!-- Add initially hidden class to prevent flickering before JS initializes -->
<div class="dashboard-grid stack-layout mobile-scrollable" style="opacity: 0; transition: opacity 0.15s ease;">
<!-- NZB Hunt Home Status Card (auto-shown when NZB Hunt has servers) -->
<div class="card nzb-home-card" id="nzb-hunt-home-card" style="display: none;">
<div class="home-section-bar">
<div class="home-section-bar-left">
<i class="fas fa-download home-section-icon" style="color: #60a5fa;"></i>
<span class="home-section-title">NZB Hunt</span>
</div>
<div class="home-section-bar-right">
<button id="nzb-home-pause-btn" class="home-section-btn" title="Pause/Resume all downloads" style="min-width: auto; padding: 4px 10px;">
<i class="fas fa-pause"></i>
</button>
</div>
</div>
<div class="nzb-home-status-bar">
<div class="nzb-home-stat">
<i class="fas fa-plug"></i>
<span id="nzb-home-connections">0</span>
<span class="nzb-home-stat-label">Connections</span>
</div>
<div class="nzb-home-stat">
<i class="fas fa-tachometer-alt"></i>
<span id="nzb-home-speed">0 B/s</span>
<span class="nzb-home-stat-label">Speed</span>
</div>
<div class="nzb-home-stat">
<i class="fas fa-clock"></i>
<span id="nzb-home-eta">--</span>
<span class="nzb-home-stat-label">ETA</span>
</div>
<div class="nzb-home-stat">
<i class="fas fa-arrow-down"></i>
<span id="nzb-home-remaining">0 B</span>
<span class="nzb-home-stat-label">Remaining</span>
</div>
<div class="nzb-home-stat">
<i class="fas fa-hdd"></i>
<span id="nzb-home-space">--</span>
<span class="nzb-home-stat-label">Space</span>
</div>
</div>
</div>
<div class="card requestarr-home-card" style="display: none;">
<div class="requestarr-home-content">
<div class="global-search-bar">
<i class="fas fa-search"></i>
<input type="text" id="home-requestarr-search-input" placeholder="Search Movies & TV" autocomplete="off">
</div>
<!-- Instance Selectors (same server-side defaults as Requestarr) -->
<div class="home-instance-controls" id="home-instance-controls" style="display: none;">
<div class="instance-selector-container">
<select id="home-movie-instance-select" class="control-select instance-select">
<option value="">Loading movie instances...</option>
</select>
</div>
<div class="instance-selector-container">
<select id="home-tv-instance-select" class="control-select instance-select">
<option value="">Loading TV instances...</option>
</select>
</div>
</div>
<div id="home-search-results-view" style="display: none;">
<h2 class="search-results-title">Search Results</h2>
<div id="home-search-results-grid">
<!-- Search results will be populated here -->
</div>
</div>
<div id="home-requestarr-discover-view" style="display: none;">
<!-- Smart Hunt Section (replaces rotating Trending/Movies/TV) -->
<section class="carousel-section" id="home-smarthunt-section">
<div class="section-title-container">
<h2 class="section-title">Smart Hunt <span class="fire-emoji smarthunt-flame">🔥</span></h2>
</div>
<div class="trending-bar"></div>
<div class="carousel-container">
<button class="carousel-arrow left" data-target="home-smarthunt-carousel">
<i class="fas fa-chevron-left"></i>
</button>
<div id="home-smarthunt-carousel" class="media-carousel">
<div class="loading-spinner">
<i class="fas fa-spinner fa-spin"></i>
<p>Loading Smart Hunt...</p>
</div>
</div>
<button class="carousel-arrow right" data-target="home-smarthunt-carousel">
<i class="fas fa-chevron-right"></i>
</button>
</div>
</section>
</div>
</div>
</div>
<!-- Hunt Activity -->
<div class="card stats-card">
<div class="home-section-bar">
<div class="home-section-bar-left">
<i class="fas fa-crosshairs home-section-icon"></i>
<span class="home-section-title">Hunt Activity</span>
</div>
<div class="home-section-bar-right">
<div class="view-toggle-group" id="dashboard-view-toggle">
<button class="view-toggle-btn" data-view="grid" title="Grid View">
<i class="fas fa-th"></i>
</button>
<button class="view-toggle-btn active" data-view="list" title="List View">
<i class="fas fa-list"></i>
</button>
</div>
<button id="reset-stats" class="home-section-btn" title="Reset Stats">
<i class="fas fa-sync-alt"></i> Reset Stats
</button>
</div>
</div>
<div class="media-stats-container">
<!-- Empty State for Live Hunts -->
<div id="live-hunts-empty-state" style="display: none; flex-direction: column; align-items: center; justify-content: center; padding: 40px 20px; text-align: center; color: #9ca3af; width: 100%;">
<div style="margin-bottom: 20px; opacity: 0.4;">
<img src="./static/logo/512.png" alt="Huntarr Logo" style="width: 80px; height: 80px; filter: grayscale(1);">
</div>
<p style="font-size: 18px; margin-bottom: 10px; font-weight: 500; color: #e2e8f0;">No Instances Configured</p>
<p style="font-size: 14px; line-height: 1.6; opacity: 0.8; max-width: 400px; margin-bottom: 20px;">
Get started by heading to Media Hunt or configure your 3rd Party Apps.
</p>
<div style="display: flex; gap: 12px; align-items: center;">
<button onclick="window.location.hash = '#media-hunt-collection'" class="action-button" style="background: rgba(99, 102, 241, 0.2); border: 1px solid rgba(99, 102, 241, 0.4); color: #818cf8; padding: 8px 16px; border-radius: 6px; cursor: pointer; transition: all 0.2s ease;">
<i class="fas fa-rocket" style="margin-right: 8px;"></i> Media Hunt
</button>
<span style="color: #64748b; font-size: 14px;">or</span>
<button onclick="window.location.hash = '#sonarr'" class="action-button" style="background: rgba(99, 102, 241, 0.2); border: 1px solid rgba(99, 102, 241, 0.4); color: #818cf8; padding: 8px 16px; border-radius: 6px; cursor: pointer; transition: all 0.2s ease; white-space: nowrap;">
<i class="fas fa-th-large" style="margin-right: 8px;"></i> 3rd Party Apps
</button>
</div>
</div>
<div class="app-stats-grid" id="app-stats-grid">
<!-- Movie Hunt Card (first: Huntarr icon, so users see Movie Hunt upfront) -->
<div class="app-stats-card movie_hunt" style="display: none;">
<div class="status-container" style="display: none;">
<span id="movie_huntHomeStatus" class="status-badge"></span>
</div>
<div class="hourly-cap-container">
<div class="hourly-cap-status" id="movie_hunt-hourly-cap">
<span class="hourly-cap-icon" id="movie_hunt-cap-icon"></span>
<span class="hourly-cap-text">API: <span id="movie_hunt-api-count">0</span> / <span id="movie_hunt-api-limit"></span></span>
</div>
<div class="api-progress-container">
<div class="api-progress-bar">
<div class="api-progress-fill" id="movie_hunt-api-progress" style="width: 0%;"></div>
</div>
<div class="api-progress-text">
API: <span id="movie_hunt-api-used">0</span> / <span id="movie_hunt-api-total"></span>
</div>
</div>
</div>
<div class="app-content">
<div class="app-icon-wrapper">
<img src="./static/logo/256.png" alt="Movie" class="app-logo" title="Movie">
</div>
<h4>Movie</h4>
</div>
<div class="stats-numbers">
<div class="stat-box">
<span class="stat-number" id="movie_hunt-hunted">0</span>
<span class="stat-label">Searches Triggered</span>
</div>
<div class="stat-box">
<span class="stat-number" id="movie_hunt-upgraded">0</span>
<span class="stat-label">Upgrades Triggered</span>
</div>
</div>
<div class="reset-button-container">
<button class="cycle-reset-button" data-app="movie_hunt"><i class="fas fa-sync-alt"></i> Reset</button>
</div>
</div>
<!-- Sonarr Card -->
<div class="app-stats-card sonarr" style="display: none;">
<div class="status-container" style="display: none;">
<span id="sonarrHomeStatus" class="status-badge"></span>
</div>
<div class="hourly-cap-container">
<div class="hourly-cap-status" id="sonarr-hourly-cap">
<span class="hourly-cap-icon" id="sonarr-cap-icon"></span>
<span class="hourly-cap-text">API: <span id="sonarr-api-count">0</span> / <span id="sonarr-api-limit">20</span></span>
</div>
<div class="api-progress-container">
<div class="api-progress-bar">
<div class="api-progress-fill" id="sonarr-api-progress" style="width: 0%;"></div>
</div>
<div class="api-progress-text">
API: <span id="sonarr-api-used">0</span> / <span id="sonarr-api-total">20</span>
</div>
</div>
</div>
<div class="app-content">
<div class="app-icon-wrapper">
<img src="./static/images/app-icons/sonarr.png" alt="Sonarr Logo" class="app-logo">
</div>
<h4>Sonarr</h4>
</div>
<div class="stats-numbers">
<div class="stat-box">
<div class="stat-number" id="sonarr-hunted">0</div>
<div class="stat-label">Searches Triggered</div>
</div>
<div class="stat-box">
<div class="stat-number" id="sonarr-upgraded">0</div>
<div class="stat-label">Upgrades Triggered</div>
</div>
</div>
<div class="reset-button-container">
<button class="cycle-reset-button" data-app="sonarr"><i class="fas fa-sync-alt"></i> Reset</button>
</div>
</div>
<!-- Radarr Card -->
<div class="app-stats-card radarr" style="display: none;">
<div class="status-container" style="display: none;">
<span id="radarrHomeStatus" class="status-badge"></span>
</div>
<div class="hourly-cap-container">
<div class="hourly-cap-status" id="radarr-hourly-cap">
<span class="hourly-cap-icon" id="radarr-cap-icon"></span>
<span class="hourly-cap-text">API: <span id="radarr-api-count">0</span> / <span id="radarr-api-limit">20</span></span>
</div>
<div class="api-progress-container">
<div class="api-progress-bar">
<div class="api-progress-fill" id="radarr-api-progress" style="width: 0%;"></div>
</div>
<div class="api-progress-text">
API: <span id="radarr-api-used">0</span> / <span id="radarr-api-total">20</span>
</div>
</div>
</div>
<div class="app-content">
<div class="app-icon-wrapper">
<img src="./static/images/app-icons/radarr.png" alt="Radarr Logo" class="app-logo">
</div>
<h4>Radarr</h4>
</div>
<div class="stats-numbers">
<div class="stat-box">
<span class="stat-number" id="radarr-hunted">0</span>
<span class="stat-label">Searches Triggered</span>
</div>
<div class="stat-box">
<span class="stat-number" id="radarr-upgraded">0</span>
<span class="stat-label">Upgrades Triggered</span>
</div>
</div>
<div class="reset-button-container">
<button class="cycle-reset-button" data-app="radarr"><i class="fas fa-sync-alt"></i> Reset</button>
</div>
</div>
<!-- Lidarr Card -->
<div class="app-stats-card lidarr" style="display: none;">
<div class="status-container" style="display: none;">
<span id="lidarrHomeStatus" class="status-badge"></span>
</div>
<div class="hourly-cap-container">
<div class="hourly-cap-status" id="lidarr-hourly-cap">
<span class="hourly-cap-icon" id="lidarr-cap-icon"></span>
<span class="hourly-cap-text">API: <span id="lidarr-api-count">0</span> / <span id="lidarr-api-limit">20</span></span>
</div>
<div class="api-progress-container">
<div class="api-progress-bar">
<div class="api-progress-fill" id="lidarr-api-progress" style="width: 0%;"></div>
</div>
<div class="api-progress-text">
API: <span id="lidarr-api-used">0</span> / <span id="lidarr-api-total">20</span>
</div>
</div>
</div>
<div class="app-content">
<div class="app-icon-wrapper">
<img src="./static/images/app-icons/lidarr.png" alt="Lidarr Logo" class="app-logo">
</div>
<h4>Lidarr</h4>
</div>
<div class="stats-numbers">
<div class="stat-box">
<span class="stat-number" id="lidarr-hunted">0</span>
<span class="stat-label">Searches Triggered</span>
</div>
<div class="stat-box">
<span class="stat-number" id="lidarr-upgraded">0</span>
<span class="stat-label">Upgrades Triggered</span>
</div>
</div>
<div class="reset-button-container">
<button class="cycle-reset-button" data-app="lidarr"><i class="fas fa-sync-alt"></i> Reset</button>
</div>
</div>
<!-- Readarr Card -->
<div class="app-stats-card readarr" style="display: none;">
<div class="status-container" style="display: none;">
<span id="readarrHomeStatus" class="status-badge"></span>
</div>
<div class="hourly-cap-container">
<div class="hourly-cap-status" id="readarr-hourly-cap">
<span class="hourly-cap-icon" id="readarr-cap-icon"></span>
<span class="hourly-cap-text">API: <span id="readarr-api-count">0</span> / <span id="readarr-api-limit">20</span></span>
</div>
<div class="api-progress-container">
<div class="api-progress-bar">
<div class="api-progress-fill" id="readarr-api-progress" style="width: 0%;"></div>
</div>
<div class="api-progress-text">
API: <span id="readarr-api-used">0</span> / <span id="readarr-api-total">20</span>
</div>
</div>
</div>
<div class="app-content">
<div class="app-icon-wrapper">
<img src="./static/images/app-icons/readarr.png" alt="Readarr Logo" class="app-logo">
</div>
<h4>Readarr</h4>
</div>
<div class="stats-numbers">
<div class="stat-box">
<span class="stat-number" id="readarr-hunted">0</span>
<span class="stat-label">Searches Triggered</span>
</div>
<div class="stat-box">
<span class="stat-number" id="readarr-upgraded">0</span>
<span class="stat-label">Upgrades Triggered</span>
</div>
</div>
<div class="reset-button-container">
<button class="cycle-reset-button" data-app="readarr"><i class="fas fa-sync-alt"></i> Reset</button>
</div>
</div>
<!-- Whisparr Card -->
<div class="app-stats-card whisparr" style="display: none;">
<div class="status-container" style="display: none;">
<span id="whisparrHomeStatus" class="status-badge"></span>
</div>
<div class="hourly-cap-container">
<div class="hourly-cap-status" id="whisparr-hourly-cap">
<span class="hourly-cap-icon" id="whisparr-cap-icon"></span>
<span class="hourly-cap-text">API: <span id="whisparr-api-count">0</span> / <span id="whisparr-api-limit">20</span></span>
</div>
<div class="api-progress-container">
<div class="api-progress-bar">
<div class="api-progress-fill" id="whisparr-api-progress" style="width: 0%;"></div>
</div>
<div class="api-progress-text">
API: <span id="whisparr-api-used">0</span> / <span id="whisparr-api-total">20</span>
</div>
</div>
</div>
<div class="app-content">
<div class="app-icon-wrapper">
<img src="./static/images/app-icons/whisparr.png" alt="Whisparr Logo" class="app-logo">
</div>
<h4>Whisparr V2</h4>
</div>
<div class="stats-numbers">
<div class="stat-box">
<span class="stat-number" id="whisparr-hunted">0</span>
<span class="stat-label">Searches Triggered</span>
</div>
<div class="stat-box">
<span class="stat-number" id="whisparr-upgraded">0</span>
<span class="stat-label">Upgrades Triggered</span>
</div>
</div>
<div class="reset-button-container">
<button class="cycle-reset-button" data-app="whisparr"><i class="fas fa-sync-alt"></i> Reset</button>
</div>
</div>
<!-- Eros Card -->
<div class="app-stats-card eros" style="display: none;">
<div class="status-container" style="display: none;">
<span id="erosHomeStatus" class="status-badge"></span>
</div>
<div class="hourly-cap-container">
<div class="hourly-cap-status" id="eros-hourly-cap">
<span class="hourly-cap-icon" id="eros-cap-icon"></span>
<span class="hourly-cap-text">API: <span id="eros-api-count">0</span> / <span id="eros-api-limit">20</span></span>
</div>
<div class="api-progress-container">
<div class="api-progress-bar">
<div class="api-progress-fill" id="eros-api-progress" style="width: 0%;"></div>
</div>
<div class="api-progress-text">
API: <span id="eros-api-used">0</span> / <span id="eros-api-total">20</span>
</div>
</div>
</div>
<div class="app-content">
<div class="app-icon-wrapper">
<img src="./static/images/app-icons/whisparr.png" alt="Whisparr V3 Logo" class="app-logo">
</div>
<h4>Whisparr V3</h4>
</div>
<div class="stats-numbers">
<div class="stat-box">
<span class="stat-number" id="eros-hunted">0</span>
<span class="stat-label">Searches Triggered</span>
</div>
<div class="stat-box">
<span class="stat-number" id="eros-upgraded">0</span>
<span class="stat-label">Upgrades Triggered</span>
</div>
</div>
<div class="reset-button-container">
<button class="cycle-reset-button" data-app="eros"><i class="fas fa-sync-alt"></i> Reset</button>
</div>
</div>
</div>
</div>
</div>
<!-- Swaparr Status Card (only shows when Swaparr is enabled) -->
<div class="card stats-card" id="swaparrStatusCard" style="display: none;">
<div class="home-section-bar">
<div class="home-section-bar-left">
<i class="fas fa-download home-section-icon"></i>
<span class="home-section-title">Swaparr Status</span>
</div>
<button id="reset-swaparr-data" class="home-section-btn" title="Reset">
<i class="fas fa-trash"></i> Reset
</button>
</div>
<div class="media-stats-container">
<div class="swaparr-stats-grid">
<!-- Swaparr Stats Card -->
<div class="app-stats-card swaparr">
<div class="stats-numbers">
<div class="stat-box">
<div class="stat-number" id="swaparr-processed">0</div>
<div class="stat-label">Session Processed</div>
</div>
<div class="stat-box">
<div class="stat-number" id="swaparr-strikes">0</div>
<div class="stat-label">Session Strikes</div>
</div>
<div class="stat-box">
<div class="stat-number" id="swaparr-removals">0</div>
<div class="stat-label">Session Removals</div>
</div>
<div class="stat-box">
<div class="stat-number" id="swaparr-ignored">0</div>
<div class="stat-label">Session Ignored</div>
</div>
</div>
<div class="reset-button-container">
<button id="reset-swaparr-cycle-inline" class="cycle-reset-button" data-app="swaparr"><i class="fas fa-sync-alt"></i> Reset</button>
</div>
</div>
</div>
</div>
</div>
<!-- Index Master Status Card (only shown when at least 1 indexer configured) -->
<div class="card stats-card" id="indexerHuntStatusCard" style="display: none;">
<!-- Main Header Card -->
<div class="prowlarr-main-card">
<div class="prowlarr-header-section">
<div class="app-icon-wrapper">
<img src="./static/logo/256.png" alt="Huntarr Logo" class="app-logo">
</div>
<div class="prowlarr-info">
<h4>Index Master</h4>
<span id="ihHomeConnectionStatus" class="status-badge">⚫ Loading...</span>
</div>
</div>
</div>
<!-- Sub Cards Container -->
<div class="prowlarr-subcards">
<!-- Left Sub-Card: Indexers List -->
<div class="prowlarr-subcard prowlarr-indexers-card">
<div class="subcard-header">
<h5><i class="fas fa-list"></i> Indexers</h5>
</div>
<div class="indexers-list" id="ih-home-indexers-list">
<div class="loading-text">Loading indexers...</div>
</div>
</div>
<!-- Right Sub-Card: Statistics -->
<div class="prowlarr-subcard prowlarr-statistics-card">
<div class="subcard-header">
<h5><i class="fas fa-chart-bar"></i> Statistics</h5>
</div>
<div class="statistics-content" id="ih-home-statistics-content">
<div class="loading-text">Loading statistics...</div>
</div>
</div>
</div>
</div>
<!-- Prowlarr Status Card -->
<div class="card stats-card" id="prowlarrStatusCard" style="display: none;">
<!-- Main Prowlarr Card -->
<div class="prowlarr-main-card">
<div class="prowlarr-header-section">
<div class="app-icon-wrapper">
<img src="./static/images/app-icons/prowlarr.png" alt="Prowlarr Logo" class="app-logo">
</div>
<div class="prowlarr-info">
<h4>Prowlarr</h4>
<span id="prowlarrConnectionStatus" class="status-badge">⚫ Disconnected</span>
</div>
</div>
</div>
<!-- Sub Cards Container -->
<div class="prowlarr-subcards">
<!-- Left Sub-Card: Indexers List -->
<div class="prowlarr-subcard prowlarr-indexers-card">
<div class="subcard-header">
<h5><i class="fas fa-list"></i> Indexers</h5>
</div>
<div class="indexers-list" id="prowlarr-indexers-list">
<div class="loading-text">Loading indexers...</div>
</div>
</div>
<!-- Right Sub-Card: Statistics -->
<div class="prowlarr-subcard prowlarr-statistics-card">
<div class="subcard-header">
<h5><i class="fas fa-chart-bar"></i> Statistics</h5>
</div>
<div class="statistics-content" id="prowlarr-statistics-content">
<div class="loading-text">Loading statistics...</div>
</div>
</div>
</div>
<!-- Status Legend (Hidden on Mobile) -->
<div class="prowlarr-legend">
<div class="legend-title">Status Legend:</div>
<div class="legend-items">
<div class="legend-item">
<span class="indexer-status active">Active</span>
<span class="legend-description">Indexer is working normally</span>
</div>
<div class="legend-item">
<span class="indexer-status throttled">Throttled</span>
<span class="legend-description">Rate limited - reduce search frequency</span>
</div>
<div class="legend-item">
<span class="indexer-status failed">Failed</span>
<span class="legend-description">Disabled or not responding</span>
</div>
</div>
</div>
</div>
<!-- Enhanced Support Links with Modern Design -->
<div class="card support-links-card" id="huntarr-support-section" style="display: none;">
<div class="card-header">
<h3>Support</h3>
</div>
<div class="support-links-container">
<div class="support-links-grid">
<a href="https://github.com/plexguide/huntarr" target="_blank" class="support-link github">
<div class="icon-container github-icon">
<i class="fab fa-github"></i>
<i class="fas fa-star star-inner-icon"></i>
</div>
<div class="link-details">
<span class="link-title">Star on GitHub</span>
<span class="link-description">Support development &amp; features</span>
</div>
</a>
<!-- Hide the sponsor widget until it's configured -->
<div id="sponsor-widget-container" class="support-link sponsor-widget" style="visibility: hidden;">
<div id="sponsor-avatar-container" class="icon-container" style="visibility: hidden;">
<!-- JavaScript will inject sponsor avatar here -->
<!-- Initially hidden until content is loaded -->
</div>
<div class="link-details">
<a href="https://plexguide.github.io/Huntarr.io/donate.html" target="_blank" class="sponsor-title-link full-title">Daughter's Sponsor</a>
<span id="rotating-sponsor-content" class="link-description" style="visibility: hidden;">
<!-- JavaScript will inject sponsor name here -->
<!-- Initially hidden until content is loaded -->
</span>
</div>
</div>
<a href="https://plexguide.github.io/Huntarr.io/donate.html" target="_blank" class="support-link donate">
<div class="icon-container donate-icon">
<i class="fas fa-heart"></i>
</div>
<div class="link-details">
<span class="link-title">Donate</span>
<span class="link-description">Daughter's College Fund!</span>
</div>
</a>
</div>
</div>
</div>
</div>
</section>
<style>
.stack-layout {
display: flex;
flex-direction: column;
gap: 20px;
width: 100%;
padding-bottom: 20px; /* Reduced padding since we removed the fixed banner */
}
.stack-layout .card {
width: 100%;
}
.thanks-list {
text-align: left;
padding-left: 20px;
}
.thanks-list li {
margin-bottom: 10px;
}
/* Banner card styles */
.banner-card {
background-color: var(--bg-secondary);
padding: 12px 15px;
border-left: 3px solid var(--accent-color);
}
.banner-content {
display: flex;
justify-content: center;
align-items: center;
text-align: center;
}
.donation-icon {
color: #ff6b6b;
}
.star-icon {
color: #ffd700;
}
/* Improved important links */
.important-links {
display: flex;
flex-wrap: wrap;
gap: 10px;
margin-top: 10px;
justify-content: center;
}
.link-button {
display: flex;
align-items: center;
gap: 6px;
padding: 8px 14px;
background-color: var(--bg-tertiary);
border-radius: 6px;
color: var(--text-primary);
text-decoration: none;
transition: all 0.2s ease;
font-weight: 500;
font-size: 0.85rem;
box-shadow: none;
border: 1px solid var(--border-color);
}
.link-button i {
font-size: 0.85em;
}
.link-button:hover {
transform: none;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
background-color: var(--accent-color);
color: white;
border-color: var(--accent-color);
}
.sponsor-button {
background-color: #4e54c8;
color: white;
}
.sponsor-button:hover {
background-color: #24c6dc;
}
/* Stats card styling */
.stats-card {
width: 100%;
background-color: rgba(24, 28, 37, 0.6);
border: 1px solid rgba(90, 109, 137, 0.2);
border-radius: 10px;
overflow: hidden;
}
.stats-card .card-header {
display: flex;
justify-content: space-between;
align-items: flex-end;
padding: 6px 0 8px;
margin-bottom: 12px;
background-color: transparent;
border-bottom: 1px solid rgba(90, 109, 137, 0.2);
}
.stats-card .card-header h3 {
margin: 0;
color: #e0e6ed;
font-size: 0.94em;
font-weight: 600;
line-height: 1.2;
}
.media-stats-container {
padding: 20px;
background-color: rgba(15, 18, 24, 0.4);
}
.app-stats-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 20px;
align-items: start;
}
.app-stats-card-wrapper {
display: contents;
}
.app-stats-card {
background: linear-gradient(145deg, rgba(26, 32, 44, 0.9), rgba(20, 24, 33, 0.8));
border-radius: 18px;
padding: 0 20px 0 20px;
text-align: center;
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.25), 0 1px 1px rgba(255, 255, 255, 0.05) inset;
transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
position: relative;
display: flex;
flex-direction: column;
align-items: center;
min-height: 200px;
justify-content: flex-start;
border: 1px solid rgba(120, 140, 180, 0.15);
overflow: hidden;
backdrop-filter: blur(5px);
}
.app-stats-card:hover {
transform: translateY(-5px);
box-shadow: 0 15px 30px rgba(0, 0, 0, 0.3), 0 1px 1px rgba(255, 255, 255, 0.07) inset;
border-color: rgba(120, 140, 180, 0.3);
/* Fix for text blur on hover in Firefox */
backface-visibility: hidden;
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
perspective: 1000px;
-webkit-perspective: 1000px;
-moz-perspective: 1000px;
transform-style: preserve-3d;
-webkit-transform-style: preserve-3d;
-moz-transform-style: preserve-3d;
}
/* Enhanced status container styling */
.status-container {
width: 100%;
margin: 0 0 15px 0;
padding: 10px 0;
display: flex;
justify-content: center;
align-items: center;
flex-wrap: wrap;
gap: 5px;
background: linear-gradient(to bottom, rgba(17, 23, 35, 0.7), rgba(13, 17, 26, 0.5));
border-bottom: 1px solid rgba(255, 255, 255, 0.05);
border-radius: 16px 16px 0 0;
margin-left: -20px;
margin-right: -20px;
width: calc(100% + 40px);
backdrop-filter: blur(10px);
}
.status-badge {
padding: 5px 14px;
border-radius: 30px;
font-weight: 600;
font-size: 11px;
display: inline-flex;
align-items: center;
gap: 6px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
letter-spacing: 0.5px;
backdrop-filter: blur(5px);
}
/* App content styling */
.app-content {
display: flex;
flex-direction: column;
align-items: center;
margin: 10px 0 5px 0;
position: relative;
z-index: 1;
}
/* App icon wrapper base styling */
.app-icon-wrapper {
width: 76px;
height: 76px;
display: flex;
justify-content: center;
align-items: center;
border-radius: 50%;
background: radial-gradient(circle at 30% 30%, rgba(35, 42, 55, 0.9), rgba(22, 27, 38, 0.8));
margin-bottom: 12px;
position: relative;
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.3), 0 0 0 1px rgba(255, 255, 255, 0.05) inset;
transform: perspective(800px) rotateX(10deg);
backdrop-filter: blur(5px);
}
.app-logo {
width: 40px;
height: 40px;
filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.3));
transform: scale(1.15);
transition: transform 0.3s ease;
}
.app-stats-card:hover .app-logo {
transform: scale(1.25);
}
.app-stats-card h4 {
margin: 0;
font-size: 17px;
font-weight: 600;
color: #e0e6ed;
letter-spacing: 0.7px;
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
background: linear-gradient(to bottom, #fff, #a0a8b8);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
}
.app-stats-card h4 .instance-name-link {
color: inherit;
text-decoration: none;
background: inherit;
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
cursor: pointer;
transition: opacity 0.2s ease;
}
.app-stats-card h4 .instance-name-link:hover {
opacity: 0.9;
text-decoration: underline;
}
.app-stats-card .instance-icon-link {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
text-decoration: none;
cursor: pointer;
border-radius: 50%;
}
.app-stats-card .instance-icon-link:hover {
opacity: 0.9;
}
/* Common styles for app icon wrappers */
.app-stats-card .app-icon-wrapper::before,
.app-stats-card .app-icon-wrapper::after {
content: '';
position: absolute;
top: -4px;
left: -4px;
right: -4px;
bottom: -4px;
border-radius: 50%;
border: 2px solid transparent;
}
.app-stats-card .app-icon-wrapper::after {
top: -8px;
left: -8px;
right: -8px;
bottom: -8px;
opacity: 0.5;
}
/* Sonarr blue glowing rings */
.app-stats-card.sonarr .app-icon-wrapper::before {
border-color: rgba(0, 174, 240, 0.8);
box-shadow: 0 0 15px rgba(0, 174, 240, 0.6);
}
.app-stats-card.sonarr .app-icon-wrapper::after {
border-color: rgba(0, 174, 240, 0.4);
box-shadow: 0 0 20px rgba(0, 174, 240, 0.3);
}
/* Radarr yellow glowing rings */
.app-stats-card.radarr .app-icon-wrapper::before {
border-color: rgba(253, 203, 43, 0.8);
box-shadow: 0 0 15px rgba(253, 203, 43, 0.6);
}
.app-stats-card.radarr .app-icon-wrapper::after {
border-color: rgba(253, 203, 43, 0.4);
box-shadow: 0 0 20px rgba(253, 203, 43, 0.3);
}
/* Lidarr green glowing rings */
.app-stats-card.lidarr .app-icon-wrapper::before {
border-color: rgba(49, 197, 56, 0.8);
box-shadow: 0 0 15px rgba(49, 197, 56, 0.6);
}
.app-stats-card.lidarr .app-icon-wrapper::after {
border-color: rgba(49, 197, 56, 0.4);
box-shadow: 0 0 20px rgba(49, 197, 56, 0.3);
}
/* Readarr red glowing rings */
.app-stats-card.readarr .app-icon-wrapper::before {
border-color: rgba(192, 45, 40, 0.8);
box-shadow: 0 0 15px rgba(192, 45, 40, 0.6);
}
.app-stats-card.readarr .app-icon-wrapper::after {
border-color: rgba(192, 45, 40, 0.4);
box-shadow: 0 0 20px rgba(192, 45, 40, 0.3);
}
/* Whisparr purple glowing rings */
.app-stats-card.whisparr .app-icon-wrapper::before {
border-color: rgba(195, 0, 230, 0.8);
box-shadow: 0 0 15px rgba(195, 0, 230, 0.6);
}
.app-stats-card.whisparr .app-icon-wrapper::after {
border-color: rgba(195, 0, 230, 0.4);
box-shadow: 0 0 20px rgba(195, 0, 230, 0.3);
}
/* Eros purple glowing rings (same as Whisparr) */
.app-stats-card.eros .app-icon-wrapper::before {
border-color: rgba(195, 0, 230, 0.8);
box-shadow: 0 0 15px rgba(195, 0, 230, 0.6);
}
.app-stats-card.eros .app-icon-wrapper::after {
border-color: rgba(195, 0, 230, 0.4);
box-shadow: 0 0 20px rgba(195, 0, 230, 0.3);
}
/* Movie Hunt & TV Hunt amber/gold glowing rings (Huntarr branding) */
.app-stats-card.movie_hunt .app-icon-wrapper::before,
.app-stats-card.tv_hunt .app-icon-wrapper::before {
border-color: rgba(245, 158, 11, 0.8);
box-shadow: 0 0 15px rgba(245, 158, 11, 0.6);
}
.app-stats-card.movie_hunt .app-icon-wrapper::after,
.app-stats-card.tv_hunt .app-icon-wrapper::after {
border-color: rgba(245, 158, 11, 0.4);
box-shadow: 0 0 20px rgba(245, 158, 11, 0.3);
}
.app-logo {
width: 40px;
height: 40px;
}
.app-stats-card h4 {
margin: 0;
font-size: 16px;
font-weight: 600;
color: #e0e6ed;
letter-spacing: 0.5px;
}
/* Enhanced stats numbers display */
.stats-numbers {
display: flex;
justify-content: space-around;
width: 100%;
padding: 15px 0;
margin-top: auto;
margin-bottom: 0;
border-top: none;
background: transparent;
}
.stat-box {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
}
/* Make the stat numbers more vibrant and prominent */
.stat-number {
font-size: 36px;
font-weight: 700;
line-height: 1;
margin-bottom: 8px;
letter-spacing: -0.5px;
text-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
}
/* App-specific stat number styles */
.app-stats-card.sonarr .stat-number {
background: linear-gradient(to bottom right, #5acdff, #00aef0);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
}
.app-stats-card.radarr .stat-number {
background: linear-gradient(to bottom right, #ffe066, #fdcb2b);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
}
.app-stats-card.lidarr .stat-number {
background: linear-gradient(to bottom right, #5de264, #31c538);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
}
.app-stats-card.readarr .stat-number {
background: linear-gradient(to bottom right, #e35751, #c02d28);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
}
.app-stats-card.whisparr .stat-number {
background: linear-gradient(to bottom right, #e64dff, #c300e6);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
}
.app-stats-card.eros .stat-number {
background: linear-gradient(to bottom right, #e64dff, #c300e6);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
}
.app-stats-card.swaparr .stat-number {
background: linear-gradient(to bottom right, #6366f1, #818cf8);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
}
.stat-label {
font-size: 11px;
color: rgba(160, 168, 184, 0.9);
font-weight: 500;
letter-spacing: 0.7px;
text-transform: uppercase;
opacity: 0.8;
}
/* App-specific accent colors for Movie Hunt & TV Hunt (Huntarr gold/amber) */
.app-stats-card.movie_hunt .app-icon-wrapper,
.app-stats-card.tv_hunt .app-icon-wrapper {
border-color: rgba(245, 158, 11, 0.5);
box-shadow: 0 0 15px rgba(245, 158, 11, 0.2);
}
/* App-specific accent colors for sonarr */
.app-stats-card.sonarr .app-icon-wrapper {
border-color: rgba(0, 174, 240, 0.5);
box-shadow: 0 0 15px rgba(0, 174, 240, 0.2);
}
/* App-specific accent colors for radarr */
.app-stats-card.radarr .app-icon-wrapper {
border-color: rgba(253, 203, 43, 0.5);
box-shadow: 0 0 15px rgba(253, 203, 43, 0.2);
}
/* App-specific accent colors for lidarr */
.app-stats-card.lidarr .app-icon-wrapper {
border-color: rgba(49, 197, 56, 0.5);
box-shadow: 0 0 15px rgba(49, 197, 56, 0.2);
}
/* App-specific accent colors for readarr */
.app-stats-card.readarr .app-icon-wrapper {
border-color: rgba(192, 45, 40, 0.5);
box-shadow: 0 0 15px rgba(192, 45, 40, 0.2);
}
/* App-specific accent colors for whisparr */
.app-stats-card.whisparr .app-icon-wrapper {
border-color: rgba(195, 0, 230, 0.5);
box-shadow: 0 0 15px rgba(195, 0, 230, 0.2);
}
/* App-specific accent colors for eros */
.app-stats-card.eros .app-icon-wrapper {
border-color: rgba(195, 0, 230, 0.5);
box-shadow: 0 0 15px rgba(195, 0, 230, 0.2);
}
/* Status badge colors */
.status-badge.connected {
background: linear-gradient(145deg, rgba(39, 174, 96, 0.15), rgba(46, 204, 113, 0.05));
color: #2ecc71;
border: 1px solid rgba(39, 174, 96, 0.3);
box-shadow: 0 3px 10px rgba(46, 204, 113, 0.1);
}
.status-badge.partially-connected {
background: linear-gradient(145deg, rgba(243, 156, 18, 0.15), rgba(241, 196, 15, 0.05));
color: #f39c12;
border: 1px solid rgba(243, 156, 18, 0.3);
box-shadow: 0 3px 10px rgba(243, 156, 18, 0.1);
}
.status-badge.not-connected {
background: linear-gradient(145deg, rgba(231, 76, 60, 0.15), rgba(192, 57, 43, 0.05));
color: #e74c3c;
border: 1px solid rgba(231, 76, 60, 0.3);
/* Swaparr Status Card Styling */
.swaparr-stats-grid {
display: grid;
grid-template-columns: 1fr;
gap: 20px;
}
.swaparr-status-container {
padding: 20px !important;
background-color: rgba(15, 18, 24, 0.4) !important;
display: block !important;
width: 100% !important;
box-sizing: border-box !important;
}
.swaparr-stats-horizontal {
display: grid !important;
grid-template-columns: repeat(4, 1fr) !important;
gap: 15px !important;
margin-bottom: 25px !important;
width: 100% !important;
}
.swaparr-action-buttons {
display: flex;
justify-content: center;
gap: 15px;
margin-top: 10px;
}
@media (max-width: 600px) {
.swaparr-action-buttons {
flex-direction: column;
gap: 10px;
}
}
.swaparr-stat-box {
background: linear-gradient(145deg, rgba(26, 32, 44, 0.9), rgba(20, 24, 33, 0.8)) !important;
border-radius: 8px !important;
padding: 15px !important;
text-align: center !important;
border: 1px solid rgba(120, 140, 180, 0.15) !important;
transition: all 0.3s ease !important;
backdrop-filter: blur(5px) !important;
min-height: 80px !important;
display: flex !important;
flex-direction: column !important;
justify-content: center !important;
width: 100% !important;
box-sizing: border-box !important;
}
.swaparr-stat-box:hover {
transform: translateY(-2px);
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.2);
border-color: rgba(120, 140, 180, 0.3);
}
.swaparr-stat-box .stat-label {
font-size: 11px !important;
color: rgba(160, 168, 184, 0.9) !important;
font-weight: 600 !important;
letter-spacing: 1px !important;
text-transform: uppercase !important;
margin-bottom: 8px !important;
margin-top: 0 !important;
line-height: 1.2 !important;
}
.swaparr-stat-box .stat-value {
font-size: 28px !important;
font-weight: 700 !important;
color: #fff !important;
background: linear-gradient(to bottom right, #6366f1, #818cf8) !important;
-webkit-background-clip: text !important;
background-clip: text !important;
-webkit-text-fill-color: transparent !important;
text-shadow: 0 2px 10px rgba(0, 0, 0, 0.3) !important;
margin: 0 !important;
line-height: 1 !important;
}
.swaparr-countdown-section {
text-align: center;
}
.swaparr-countdown-section h4 {
margin: 0 0 15px 0;
color: #e0e6ed;
font-size: 16px;
font-weight: 600;
}
.countdown-timer-container {
display: flex;
justify-content: center;
align-items: center;
margin-bottom: 20px;
}
.countdown-display {
display: flex;
align-items: center;
gap: 10px;
font-size: 24px;
font-weight: 600;
color: #6366f1;
}
.countdown-display i {
font-size: 20px;
}
.timer-value {
font-family: 'Courier New', monospace;
background: linear-gradient(to bottom right, #6366f1, #818cf8);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
}
.swaparr-action-buttons {
display: flex;
justify-content: center;
gap: 15px;
margin-top: 10px;
}
.swaparr-action-buttons .action-button {
padding: 8px 16px;
border-radius: 6px;
border: none;
cursor: pointer;
font-weight: 600;
font-size: 13px;
transition: all 0.3s ease;
display: flex;
align-items: center;
gap: 6px;
}
.swaparr-action-buttons .action-button.danger {
background-color: #e74c3c;
color: white;
}
.swaparr-action-buttons .action-button.danger:hover {
background-color: #c0392b;
transform: translateY(-1px);
}
.swaparr-action-buttons .action-button.secondary {
background-color: #6366f1;
color: white;
}
.swaparr-action-buttons .action-button.secondary:hover {
background-color: #818cf8;
transform: translateY(-1px);
}
box-shadow: 0 3px 10px rgba(231, 76, 60, 0.1);
}
.status-badge.loading {
background: linear-gradient(145deg, rgba(41, 128, 185, 0.15), rgba(99, 102, 241, 0.05));
color: #6366f1;
border: 1px solid rgba(41, 128, 185, 0.3);
box-shadow: 0 3px 10px rgba(41, 128, 185, 0.1);
}
/* Improved hourly cap container styling */
.hourly-cap-container {
padding: 0 10px;
margin: 5px 0 20px 0; /* Increase bottom margin from 5px to 20px */
width: 100%;
}
.api-link {
text-decoration: none;
display: inline-block;
}
.api-link:hover .hourly-cap-status {
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25);
transform: translateY(-1px);
cursor: pointer;
}
.api-link:active .hourly-cap-status {
transform: translateY(0);
transition: transform 0.1s;
}
.hourly-cap-status {
display: flex;
align-items: center;
justify-content: center;
padding: 5px 12px;
border-radius: 8px;
font-size: 12px;
font-weight: 600;
background: linear-gradient(145deg, rgba(20, 25, 35, 0.6), rgba(15, 19, 26, 0.4));
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15), 0 1px 0 rgba(255, 255, 255, 0.05) inset;
border-left: 3px solid rgba(255, 255, 255, 0.2);
transition: all 0.2s ease;
position: relative;
backdrop-filter: blur(5px);
margin: 0 auto;
max-width: 200px;
}
.hourly-cap-status:after {
content: '';
position: absolute;
bottom: -2px;
left: 0;
width: 0;
height: 1px;
background: rgba(255, 255, 255, 0.5);
transition: width 0.2s ease;
}
.api-link:hover .hourly-cap-status:after {
width: 100%;
}
.hourly-cap-icon {
margin-right: 5px;
font-size: 0.9rem;
}
.hourly-cap-text {
color: rgba(255, 255, 255, 0.9);
font-weight: 500;
letter-spacing: 0.3px;
}
/* API Cap Status Colors */
.hourly-cap-status.good {
background: linear-gradient(145deg, rgba(20, 25, 35, 0.5), rgba(15, 19, 26, 0.3));
border-left: 3px solid rgba(46, 204, 113, 0.9);
box-shadow: 0 3px 10px rgba(46, 204, 113, 0.15);
}
.hourly-cap-status.warning {
background: linear-gradient(145deg, rgba(20, 25, 35, 0.5), rgba(15, 19, 26, 0.3));
border-left: 3px solid rgba(243, 156, 18, 0.9);
box-shadow: 0 3px 10px rgba(243, 156, 18, 0.15);
}
.hourly-cap-status.danger {
background: linear-gradient(145deg, rgba(20, 25, 35, 0.5), rgba(15, 19, 26, 0.3));
border-left: 3px solid rgba(231, 76, 60, 0.9);
box-shadow: 0 3px 10px rgba(231, 76, 60, 0.15);
}
.hourly-cap-status.good .hourly-cap-icon:before {
content: "\f201"; /* fa-chart-line */
font-family: "Font Awesome 5 Free";
font-weight: 900;
color: #2ecc71;
}
.hourly-cap-status.warning .hourly-cap-icon:before {
content: "\f252"; /* fa-hourglass-half */
font-family: "Font Awesome 5 Free";
font-weight: 900;
color: #f39c12;
}
.hourly-cap-status.danger .hourly-cap-icon:before {
content: "\f056"; /* fa-minus-circle */
font-family: "Font Awesome 5 Free";
font-weight: 900;
color: #e74c3c;
}
/* Header for cards */
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15px;
}
.card h3 {
margin-top: 0;
margin-bottom: 0;
}
/* Special card styling and afterglow effects */
.app-content {
display: flex;
flex-direction: column;
align-items: center;
margin: 10px 0 5px 0;
position: relative;
z-index: 1;
}
/* Add subtle after-glow to the cards */
.app-stats-card::after {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: radial-gradient(circle at 50% 10%, rgba(255, 255, 255, 0.08), transparent 60%);
pointer-events: none;
z-index: 0;
}
/* App-specific gradients */
.app-stats-card.sonarr::after {
background: radial-gradient(circle at 50% 10%, rgba(0, 174, 240, 0.08), transparent 70%);
}
.app-stats-card.radarr::after {
background: radial-gradient(circle at 50% 10%, rgba(253, 203, 43, 0.08), transparent 70%);
}
.app-stats-card.lidarr::after {
background: radial-gradient(circle at 50% 10%, rgba(49, 197, 56, 0.08), transparent 70%);
}
.app-stats-card.readarr::after {
background: radial-gradient(circle at 50% 10%, rgba(192, 45, 40, 0.08), transparent 70%);
}
.app-stats-card.whisparr::after, .app-stats-card.eros::after {
background: radial-gradient(circle at 50% 10%, rgba(195, 0, 230, 0.08), transparent 70%);
}
/* Ensure button in header doesn't inherit odd margins and adjust padding */
.card-header .action-button {
margin: 0;
padding: 6px 12px;
font-size: 0.9em;
flex-grow: 0;
}
/* Enhanced action button styling */
.card-header .action-button {
margin: 0;
padding: 6px 12px;
font-size: 0.85em;
flex-grow: 0;
background: linear-gradient(145deg, rgba(244, 67, 54, 0.12), rgba(229, 57, 53, 0.07));
border: 1px solid rgba(244, 67, 54, 0.25);
border-radius: 6px;
transition: all 0.2s ease;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}
.action-button.danger {
background-color: rgba(244, 67, 54, 0.1);
color: #f44336;
}
.action-button.danger:hover {
background: linear-gradient(145deg, rgba(244, 67, 54, 0.9), rgba(229, 57, 53, 0.8));
color: white;
border-color: #f44336;
transform: translateY(-1px);
box-shadow: 0 4px 8px rgba(244, 67, 54, 0.2);
}
.action-button.danger:active {
background: linear-gradient(145deg, rgba(229, 57, 53, 0.9), rgba(244, 67, 54, 0.8));
transform: translateY(0);
}
/* Responsive adjustments */
@media (max-width: 768px) {
.important-links {
flex-direction: column;
}
.link-button {
width: 100%;
justify-content: center;
}
}
/* Version display styling */
.version-icon {
color: #6366f1;
}
#version-number {
color: var(--text-primary);
font-weight: 500;
}
#version-value {
font-weight: 600;
}
/* Added style for latest version number */
#latest-version-value {
font-weight: 600;
}
/* Developer credit styling */
.developer-credit {
color: var(--text-secondary);
font-weight: 500;
}
.developer-credit a {
color: #6366f1;
font-weight: 600;
text-decoration: none;
}
.developer-credit a:hover {
text-decoration: underline;
}
/* Community & Resources Hub styling */
.community-hub-card {
width: 100%;
background-color: rgba(24, 28, 37, 0.6);
border: 1px solid rgba(90, 109, 137, 0.2);
border-radius: 10px;
overflow: hidden;
}
.community-hub-card .card-header,
.support-links-card .card-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 0 8px;
margin-bottom: 12px;
background-color: transparent;
border-bottom: 1px solid rgba(90, 109, 137, 0.2);
}
.community-hub-card .card-header h3,
.support-links-card .card-header h3 {
margin: 0;
color: #e0e6ed;
font-size: 0.75em;
font-weight: 600;
line-height: 1.2;
}
/* Enhanced Community Hub Card with Glass Effect */
.community-hub-card {
margin-bottom: 20px;
background: rgba(15, 20, 30, 0.5);
border: 1px solid rgba(79, 93, 115, 0.2);
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
overflow: hidden;
}
.community-resources-container {
padding: 15px;
}
.community-links-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
gap: 12px;
}
.community-link {
display: flex;
align-items: center;
background: linear-gradient(145deg, rgba(25, 30, 40, 0.4), rgba(20, 25, 35, 0.7));
border-radius: 10px;
padding: 15px;
transition: all 0.3s ease;
text-decoration: none;
color: #ffffff;
position: relative;
overflow: hidden;
backdrop-filter: blur(5px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
border: 1px solid rgba(70, 90, 120, 0.15);
z-index: 1;
}
.community-link::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(135deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0));
z-index: -1;
opacity: 0.3;
transition: opacity 0.3s ease;
}
.community-link:hover {
transform: translateY(-3px);
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.2);
}
.community-link:hover::before {
opacity: 0.5;
}
.community-link .icon-container {
width: 42px;
height: 42px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
margin-right: 15px;
flex-shrink: 0;
font-size: 20px;
color: white;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
position: relative;
}
.community-link .link-details {
display: flex;
flex-direction: column;
}
.community-link .link-title {
font-weight: 600;
font-size: 15px;
color: #ffffff;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
}
/* Icon styles for each link type with glass effect */
.icon-container.discord-icon {
background: linear-gradient(135deg, #5865F2, #404EED);
box-shadow: 0 0 10px rgba(88, 101, 242, 0.5);
}
.icon-container.reddit-icon {
background: linear-gradient(135deg, #FF4500, #FF6A33);
box-shadow: 0 0 10px rgba(255, 69, 0, 0.5);
}
.icon-container.issues-icon {
background: linear-gradient(135deg, #2D3436, #636E72);
box-shadow: 0 0 10px rgba(45, 52, 54, 0.5);
}
.icon-container.wiki-icon {
background: linear-gradient(135deg, #00B894, #00A087);
box-shadow: 0 0 10px rgba(0, 184, 148, 0.5);
}
.icon-container.changelog-icon {
background: linear-gradient(135deg, #0984E3, #0570C2);
box-shadow: 0 0 10px rgba(9, 132, 227, 0.5);
}
/* Media queries for responsiveness */
@media (max-width: 768px) {
.community-links-grid {
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}
}
@media (max-width: 500px) {
.community-links-grid {
grid-template-columns: 1fr;
}
}
/* Mobile scrolling fix */
.mobile-scrollable {
padding-bottom: 100px;
}
@media (max-width: 768px) {
#homeSection {
overflow-y: auto !important;
height: auto !important;
min-height: 100%;
}
.mobile-scrollable {
padding-bottom: 150px;
}
}
/* Modern Support Links styling with glass effect */
.support-links-card {
overflow: hidden;
background: rgba(15, 20, 30, 0.5);
border: 1px solid rgba(79, 93, 115, 0.2);
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.25);
}
.support-links-container {
padding: 4px;
fixe }
.support-links-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 15px;
}
.support-link {
display: flex;
align-items: center;
padding: 20px;
background: linear-gradient(145deg, rgba(25, 30, 40, 0.4), rgba(20, 25, 35, 0.8));
border-radius: 12px;
transition: all 0.3s ease;
text-decoration: none;
color: #ffffff;
position: relative;
overflow: hidden;
backdrop-filter: blur(5px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
border: 1px solid rgba(70, 90, 120, 0.15);
z-index: 1;
}
.support-link::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(135deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0));
z-index: -1;
opacity: 0.4;
transition: opacity 0.3s ease;
}
.support-link:hover {
transform: translateY(-3px);
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.3);
}
.support-link:hover::before {
opacity: 0.6;
}
.support-link .icon-container {
display: flex;
justify-content: center;
align-items: center;
width: 50px;
height: 50px;
font-size: 1.5rem;
margin-right: 20px;
flex-shrink: 0;
border-radius: 50%;
position: relative;
}
/* GitHub icon styling */
.support-link .icon-container.github-icon {
background: linear-gradient(135deg, #24292e, #1a202c);
color: #ffffff;
box-shadow: 0 0 15px rgba(255, 193, 7, 0.6);
/* Animation removed, static glow instead */
}
.support-link .icon-container.github-icon .star-inner-icon {
position: absolute;
font-size: 0.9em;
margin-left: 10px;
margin-top: -10px;
color: #ffc107;
filter: drop-shadow(0 0 5px rgba(255, 193, 7, 0.8));
}
/* Forum icon styling */
.support-link .icon-container.forum-icon {
background: linear-gradient(135deg, #0473BB, #1E3A8A);
color: #ffffff;
box-shadow: 0 0 15px rgba(4, 115, 187, 0.6);
/* No animation, static glow */
}
/* Donation icon styling */
.support-link .icon-container.donate-icon {
background: linear-gradient(135deg, #d63031, #e84393);
color: #ffffff;
box-shadow: 0 0 15px rgba(255, 107, 107, 0.5);
}
.support-link .link-details {
display: flex;
flex-direction: column;
}
.support-link .link-title {
font-weight: 700;
font-size: 1.1rem;
margin-bottom: 5px;
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
}
.support-link .link-description {
font-size: 0.85rem;
color: rgba(255, 255, 255, 0.8);
white-space: normal;
word-wrap: break-word;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
}
/* Mobile optimizations for support links */
@media (max-width: 768px) {
.support-links-grid {
gap: 8px;
}
.support-link {
padding: 15px;
}
.support-link .icon-container {
width: 42px;
height: 42px;
font-size: 1.3rem;
margin-right: 12px;
}
.support-link .link-title {
font-size: 0.95rem;
}
.support-link .link-description {
font-size: 0.75rem;
}
}
/* Even smaller screens */
@media (max-width: 480px) {
.support-links-grid {
grid-template-columns: 1fr;
}
}
/* Reset button container */
.reset-button-container {
margin-top: auto;
padding: 12px 0;
background: linear-gradient(to bottom, rgba(20, 26, 38, 0.5), rgba(16, 20, 30, 0.8));
border-top: 1px solid rgba(255, 255, 255, 0.05);
border-radius: 0 0 16px 16px;
display: flex;
justify-content: center;
width: 100%;
min-height: 45px;
margin-left: -20px;
margin-right: -20px;
padding-left: 20px;
padding-right: 20px;
width: calc(100% + 40px);
}
/* Enhanced cycle reset button */
.cycle-reset-button {
padding: 6px 14px;
background: linear-gradient(145deg, rgba(99, 102, 241, 0.2), rgba(41, 128, 185, 0.1));
color: #6366f1;
border: 1px solid rgba(99, 102, 241, 0.3);
border-radius: 6px;
font-size: 0.8rem;
font-weight: 500;
cursor: pointer;
transition: all 0.2s ease;
display: inline-flex;
align-items: center;
gap: 6px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
backdrop-filter: blur(5px);
}
.cycle-reset-button:hover {
background: linear-gradient(145deg, rgba(99, 102, 241, 0.3), rgba(41, 128, 185, 0.2));
transform: translateY(-1px);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
}
.cycle-reset-button:active {
background: linear-gradient(145deg, rgba(41, 128, 185, 0.3), rgba(99, 102, 241, 0.2));
transform: translateY(0);
}
.cycle-reset-button i {
font-size: 0.75rem;
filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.3));
}
.cycle-reset-button.resetting {
opacity: 0.7;
pointer-events: none;
}
/* API Progress Bar Styling */
.api-progress-container {
margin-top: 8px;
padding: 0;
}
.api-progress-bar {
width: 100%;
height: 6px;
background: rgba(0, 0, 0, 0.3);
border-radius: 3px;
overflow: hidden;
position: relative;
box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.2);
}
.api-progress-fill {
height: 100%;
background: #22c55e; /* Default green, will be overridden by JavaScript */
border-radius: 3px;
transition: width 0.3s ease, background-color 0.3s ease;
position: relative;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
}
.api-progress-fill::after {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(90deg, rgba(255, 255, 255, 0.2) 0%, rgba(255, 255, 255, 0.1) 50%, rgba(255, 255, 255, 0.2) 100%);
border-radius: 3px;
}
.api-progress-text {
font-size: 0.75rem;
color: #9ca3af;
margin-top: 4px;
text-align: center;
font-weight: 500;
letter-spacing: 0.3px;
}
/* Hide the old chunky API text */
.hourly-cap-status {
display: none;
}
/* Mobile responsiveness for progress bars */
@media (max-width: 768px) {
.api-progress-container {
margin-top: 6px;
}
.api-progress-bar {
height: 5px;
}
.api-progress-text {
font-size: 0.7rem;
margin-top: 3px;
}
}
@media (max-width: 480px) {
.api-progress-bar {
height: 4px;
}
.api-progress-text {
font-size: 0.65rem;
}
}
</style>
<script>
// DOM loaded event listener - removed card clickability
document.addEventListener('DOMContentLoaded', function() {
// App cards are no longer clickable
});
</script>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Set a small timeout to allow all DOM elements to initialize
// Load cached stats immediately to prevent flashing
(function() {
try {
const cachedStats = localStorage.getItem('huntarr-stats-cache');
if (cachedStats) {
const statsData = JSON.parse(cachedStats);
const cacheAge = Date.now() - (statsData.timestamp || 0);
// Use cache if less than 5 minutes old
if (cacheAge < 300000 && statsData.stats) {
const stats = statsData.stats;
const apps = ['sonarr', 'radarr', 'lidarr', 'readarr', 'whisparr', 'eros'];
const statTypes = ['hunted', 'upgraded'];
// Immediately populate stats with cached values
apps.forEach(app => {
if (stats[app]) {
statTypes.forEach(type => {
const element = document.getElementById(`${app}-${type}`);
if (element) {
const value = Math.max(0, parseInt(stats[app][type]) || 0);
element.textContent = formatLargeNumber(value);
}
});
}
});
console.log('[HomeOptimization] Loaded cached stats immediately');
}
}
} catch (e) {
console.log('[HomeOptimization] Failed to load cached stats');
}
// Helper function for number formatting (simplified version)
function formatLargeNumber(num) {
if (num < 1000) return num.toString();
else if (num < 10000) return (num / 1000).toFixed(1) + 'K';
else if (num < 100000) return (num / 1000).toFixed(1) + 'K';
else if (num < 1000000) return Math.floor(num / 1000) + 'K';
else if (num < 10000000) return (num / 1000000).toFixed(1) + 'M';
else if (num < 100000000) return (num / 1000000).toFixed(1) + 'M';
else if (num < 1000000000) return Math.floor(num / 1000000) + 'M';
else if (num < 1000000000000) return (num / 1000000000).toFixed(1) + 'B';
else return (num / 1000000000000).toFixed(1) + 'T';
}
})();
setTimeout(function() {
// Show the dashboard after initialization
document.querySelector('.dashboard-grid').style.opacity = '1';
}, 25);
const sponsorContainer = document.getElementById('rotating-sponsor-content');
let sponsors = [];
let weightedSponsorPool = [];
let currentSponsorIndex = 0;
let intervalId = null;
// Function to shuffle an array (Fisher-Yates algorithm)
function shuffleArray(array) {
let currentIndex = array.length, randomIndex;
// While there remain elements to shuffle
while (currentIndex > 0) {
// Pick a remaining element
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex--;
// And swap it with the current element
[array[currentIndex], array[randomIndex]] = [array[randomIndex], array[currentIndex]];
}
return array;
}
// Apply transition styles for smooth sponsor changes
const avatarContainer = document.getElementById('sponsor-avatar-container');
const descContainer = document.getElementById('rotating-sponsor-content');
// Add transition effects but keep them faster
avatarContainer.style.transition = 'opacity 0.15s ease';
descContainer.style.transition = 'opacity 0.15s ease';
// Set to visible with opacity 0 for smoother loading
avatarContainer.style.visibility = 'visible';
descContainer.style.visibility = 'visible';
avatarContainer.style.opacity = '0';
descContainer.style.opacity = '0';
// Make the container visible immediately
document.getElementById('sponsor-widget-container').style.visibility = 'visible';
// Function to create weighted sponsor pool based on category
function createWeightedPool(sponsors) {
const pool = [];
sponsors.forEach(sponsor => {
let weight;
switch(sponsor.category) {
case 'featured': weight = 1.5; break; // 50% more selections
case 'past': weight = 0.5; break; // 50% fewer selections
default: weight = 1.0; break; // Normal selections for active/others
}
// Add sponsor to pool multiple times based on weight
const entries = Math.round(weight * 10); // Multiply by 10 for better granularity
for (let i = 0; i < entries; i++) {
pool.push(sponsor);
}
});
return shuffleArray(pool);
}
// Function to get a weighted random sponsor (avoiding immediate repeats)
function getNextSponsor() {
if (weightedSponsorPool.length === 0) return null;
// If only one unique sponsor, just return it
if (sponsors.length === 1) return sponsors[0];
let attempts = 0;
let selectedSponsor;
// Try to avoid showing the same sponsor twice in a row
do {
const randomIndex = Math.floor(Math.random() * weightedSponsorPool.length);
selectedSponsor = weightedSponsorPool[randomIndex];
attempts++;
} while (attempts < 10 && selectedSponsor && selectedSponsor.login ===
(sponsors[currentSponsorIndex] && sponsors[currentSponsorIndex].login));
// Update current sponsor index for next comparison
if (selectedSponsor) {
currentSponsorIndex = sponsors.findIndex(s => s.login === selectedSponsor.login);
}
return selectedSponsor;
}
// Display the sponsor information in the UI
function displaySponsor(sponsor) {
if (!sponsor) return;
// Get the containers
const avatarContainer = document.getElementById('sponsor-avatar-container');
const descContainer = sponsorContainer;
// Faster transition - only apply fade-out if we're changing sponsors after initial load
if (!avatarContainer.classList.contains('sponsor-icon')) {
// First load - just add content without animations
updateSponsorContent(sponsor, avatarContainer, descContainer);
return;
}
// Apply quick fade-out for transitions
avatarContainer.style.opacity = '0';
descContainer.style.opacity = '0';
// Very short wait for fade-out, then update content
setTimeout(() => {
updateSponsorContent(sponsor, avatarContainer, descContainer);
}, 75); // Much faster transition
}
// Helper function to update sponsor content
function updateSponsorContent(sponsor, avatarContainer, descContainer) {
// Create elements without href to prevent prefetching, add click handlers instead
const avatarDiv = document.createElement('div');
avatarDiv.style.cssText = 'width: 100%; height: 100%; cursor: pointer; border-radius: 50%;';
avatarDiv.title = `Visit ${sponsor.name}'s GitHub profile`;
avatarDiv.onclick = function(e) {
e.preventDefault();
window.open(sponsor.url || '#', '_blank', 'noopener,noreferrer');
};
const avatarImg = document.createElement('img');
avatarImg.src = sponsor.avatarUrl;
avatarImg.alt = `${sponsor.name}'s avatar`;
avatarImg.style.cssText = 'width: 100%; height: 100%; border-radius: 50%; object-fit: cover; display: block;';
avatarDiv.appendChild(avatarImg);
avatarContainer.innerHTML = '';
avatarContainer.appendChild(avatarDiv);
// Create name element without href to prevent prefetching
const nameDiv = document.createElement('div');
nameDiv.textContent = sponsor.name;
nameDiv.style.cssText = 'cursor: pointer; color: inherit;';
nameDiv.title = `Visit ${sponsor.name}'s GitHub profile`;
nameDiv.onclick = function(e) {
e.preventDefault();
window.open(sponsor.url || '#', '_blank', 'noopener,noreferrer');
};
descContainer.innerHTML = '';
descContainer.appendChild(nameDiv);
// Add sponsor-icon class
avatarContainer.classList.add('sponsor-icon');
// Make elements visible and fade in
avatarContainer.style.visibility = 'visible';
descContainer.style.visibility = 'visible';
avatarContainer.style.opacity = '1';
descContainer.style.opacity = '1';
}
// Function to rotate to the next weighted random sponsor
function rotateSponsor() {
const sponsor = getNextSponsor();
if (sponsor) {
displaySponsor(sponsor);
}
}
// Create a placeholder sponsor while loading
function displayPlaceholderSponsor() {
const placeholderSponsor = {
name: "Daughter's College Fund",
url: "https://plexguide.github.io/Huntarr.io/donate.html"
};
// Style the container directly and apply the styling immediately
document.getElementById('sponsor-widget-container').style.visibility = 'visible';
// Create a solid orange-red circle with gold border exactly like image #2 (no href to prevent prefetching)
const placeholderDiv = document.createElement('div');
placeholderDiv.style.cssText = 'width: 100%; height: 100%; border-radius: 50%; background-color: #FF6347; border: 3px solid #ffb700; box-sizing: border-box; cursor: pointer;';
placeholderDiv.title = `Support ${placeholderSponsor.name}`;
placeholderDiv.onclick = function(e) {
e.preventDefault();
window.open(placeholderSponsor.url, '_blank', 'noopener,noreferrer');
};
avatarContainer.innerHTML = '';
avatarContainer.appendChild(placeholderDiv);
const placeholderNameDiv = document.createElement('div');
placeholderNameDiv.textContent = placeholderSponsor.name;
placeholderNameDiv.style.cssText = 'cursor: pointer; color: inherit;';
placeholderNameDiv.title = 'Support us';
placeholderNameDiv.onclick = function(e) {
e.preventDefault();
window.open(placeholderSponsor.url, '_blank', 'noopener,noreferrer');
};
descContainer.innerHTML = '';
descContainer.appendChild(placeholderNameDiv);
// Add sponsor-icon class and show immediately
avatarContainer.classList.add('sponsor-icon');
avatarContainer.style.visibility = 'visible';
descContainer.style.visibility = 'visible';
avatarContainer.style.opacity = '1';
descContainer.style.opacity = '1';
}
// Show placeholder immediately
displayPlaceholderSponsor();
// Fetch sponsors from the API
async function fetchSponsors() {
try {
// Fetch in the background without waiting for visual updates
const response = await HuntarrUtils.fetchWithTimeout('./api/github_sponsors');
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
sponsors = await response.json();
if (sponsors && sponsors.length > 0) {
// Create weighted pool where featured sponsors appear more often
weightedSponsorPool = createWeightedPool(sponsors);
// Show first weighted random sponsor almost immediately
setTimeout(() => {
const firstSponsor = getNextSponsor();
if (firstSponsor) {
displaySponsor(firstSponsor);
// Set up regular rotation every 1 minute (stays same across page changes)
if (intervalId) clearInterval(intervalId);
intervalId = setInterval(rotateSponsor, 60000);
}
}, 100); // Very short delay to avoid visual glitches
} else {
// If no sponsors, show a fallback message
sponsorContainer.textContent = 'Support us on GitHub!';
}
} catch (error) {
console.error('Error fetching sponsors:', error);
sponsorContainer.textContent = 'Support us on GitHub!';
}
}
// Initialize sponsors on page load
fetchSponsors();
// Home sponsor banner is driven by app-sponsor-rotation.js (same rotation as app pages)
});
</script>
<!-- Welcome Message Modal -->
<div id="huntarr-welcome-modal" style="display: none;">
<div class="huntarr-welcome-backdrop" id="huntarr-welcome-backdrop"></div>
<div class="huntarr-welcome-content">
<div class="huntarr-welcome-header">
<button type="button" class="huntarr-welcome-close" id="huntarr-welcome-close" aria-label="Close">
<i class="fas fa-times"></i>
</button>
<div class="huntarr-welcome-logo">
<i class="fas fa-rocket"></i>
</div>
<h2 class="huntarr-welcome-title">Welcome to Huntarr</h2>
<p class="huntarr-welcome-subtitle">Your all-in-one media management companion</p>
</div>
<div class="huntarr-welcome-body">
<p>Thanks for choosing Huntarr! This app is built with one goal in mind: <strong>making media management simple</strong>. Rather than overwhelming you with hundreds of advanced settings, Huntarr focuses on what matters most &mdash; helping you find and organize your media with ease.</p>
<p>Huntarr is designed for the <strong>90% of users</strong> who just want things to work. If you're new to the *arr ecosystem, you're in the right place.</p>
<div class="huntarr-welcome-tip">
<i class="fas fa-lightbulb"></i>
<div>
<strong>A note on updates:</strong> If you're running Huntarr via Docker with the <code>huntarr/huntarr:latest</code> tag, expect frequent updates and rapid changes &mdash; we move fast! For a more stable experience, pin to a specific version like <code>huntarr/huntarr:9.3.0</code>.
</div>
</div>
<p>Huntarr is a free, community-driven project. The goal has always been to make your media experience enjoyable and hassle-free.</p>
<p>A heartfelt thank you to everyone who has supported <strong>my daughter's education</strong> through sponsorships &mdash; it truly means the world to our family. Knowing that so many people I've never even met genuinely care is the greatest motivation I could ever ask for. A special shoutout to the <strong>r/Unraid</strong> community &mdash; where it all started! I build this for you.</p>
<p class="huntarr-welcome-signoff">Happy hunting!<br><strong>&mdash; Admin9705</strong></p>
</div>
<div class="huntarr-welcome-footer">
<button type="button" class="huntarr-welcome-dismiss" id="huntarr-welcome-dismiss">
<i class="fas fa-check"></i> Got it, thanks!
</button>
</div>
</div>
</div>
<style>
#huntarr-welcome-modal {
position: fixed;
top: 0; left: 0; right: 0; bottom: 0;
z-index: 10000;
display: none;
align-items: center;
justify-content: center;
}
#huntarr-welcome-modal[style*="display: flex"] { display: flex !important; }
.huntarr-welcome-backdrop {
position: fixed;
top: 0; left: 0; right: 0; bottom: 0;
background: rgba(0, 0, 0, 0.75);
backdrop-filter: blur(14px);
-webkit-backdrop-filter: blur(14px);
z-index: 10000;
}
.huntarr-welcome-content {
position: relative;
z-index: 10001;
background: rgba(15, 23, 42, 0.98);
border: 2px solid rgba(99, 102, 241, 0.35);
border-radius: 16px;
max-width: 780px;
width: 94%;
max-height: 85vh;
overflow-y: auto;
box-shadow: 0 30px 60px rgba(0, 0, 0, 0.6), 0 0 60px rgba(99, 102, 241, 0.1);
animation: welcomeFadeIn 0.3s ease-out;
}
@keyframes welcomeFadeIn {
from { opacity: 0; transform: scale(0.95) translateY(10px); }
to { opacity: 1; transform: scale(1) translateY(0); }
}
.huntarr-welcome-header {
position: relative;
padding: 28px 28px 18px;
text-align: center;
background: linear-gradient(135deg, #1e293b 0%, #334155 50%, #0f172a 100%);
border-bottom: 1px solid rgba(148, 163, 184, 0.08);
}
.huntarr-welcome-close {
position: absolute;
top: 14px; right: 14px;
background: transparent;
border: none;
color: #94a3b8;
font-size: 1.2rem;
cursor: pointer;
padding: 4px;
transition: color 0.15s;
}
.huntarr-welcome-close:hover { color: #f8fafc; }
.huntarr-welcome-logo {
display: inline-flex;
align-items: center;
justify-content: center;
width: 56px; height: 56px;
border-radius: 50%;
background: linear-gradient(135deg, #6366f1, #4f46e5);
margin-bottom: 12px;
font-size: 1.5rem;
color: #fff;
box-shadow: 0 4px 20px rgba(99, 102, 241, 0.3);
}
.huntarr-welcome-title {
margin: 0 0 4px;
font-size: 1.5rem;
font-weight: 700;
color: #f8fafc;
}
.huntarr-welcome-subtitle {
margin: 0;
font-size: 0.95rem;
color: #94a3b8;
}
.huntarr-welcome-body {
padding: 22px 28px;
color: #cbd5e1;
font-size: 0.92rem;
line-height: 1.65;
}
.huntarr-welcome-body p {
margin: 0 0 14px;
}
.huntarr-welcome-body p:last-child {
margin-bottom: 0;
}
.huntarr-welcome-body strong {
color: #f1f5f9;
}
.huntarr-welcome-body code {
background: rgba(99, 102, 241, 0.12);
color: #a5b4fc;
padding: 2px 6px;
border-radius: 4px;
font-size: 0.85em;
font-family: 'JetBrains Mono', 'Fira Code', monospace;
}
.huntarr-welcome-tip {
display: flex;
gap: 12px;
padding: 14px 16px;
background: rgba(234, 179, 8, 0.06);
border: 1px solid rgba(234, 179, 8, 0.18);
border-radius: 10px;
margin: 14px 0;
color: #cbd5e1;
font-size: 0.88rem;
line-height: 1.55;
}
.huntarr-welcome-tip > i {
color: #eab308;
font-size: 1.1rem;
margin-top: 2px;
flex-shrink: 0;
}
.huntarr-welcome-signoff {
margin-top: 8px !important;
color: #94a3b8;
font-size: 0.9rem;
}
.huntarr-welcome-signoff strong {
color: #a5b4fc;
}
.huntarr-welcome-footer {
display: flex;
justify-content: flex-end;
padding: 20px 28px 24px;
border-top: 1px solid rgba(148, 163, 184, 0.08);
}
.huntarr-welcome-dismiss {
padding: 10px 24px;
background: linear-gradient(135deg, #6366f1, #4f46e5);
border: none;
border-radius: 8px;
color: #fff;
font-size: 0.9rem;
font-weight: 600;
cursor: pointer;
transition: filter 0.15s, transform 0.1s;
}
.huntarr-welcome-dismiss:hover { filter: brightness(1.15); }
.huntarr-welcome-dismiss:active { transform: scale(0.98); }
@media (max-width: 600px) {
.huntarr-welcome-content {
width: 96%;
max-width: none;
border-radius: 12px;
}
.huntarr-welcome-header { padding: 20px 18px 14px; }
.huntarr-welcome-body { padding: 16px 18px; font-size: 0.88rem; }
.huntarr-welcome-footer { padding: 16px 18px 20px; }
.huntarr-welcome-title { font-size: 1.25rem; }
.huntarr-welcome-tip { font-size: 0.84rem; padding: 12px 14px; }
}
</style>
</section>