diff --git a/static/css/style.css b/static/css/style.css index 4883542..23fb764 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -3,13 +3,17 @@ --bg-dark: #0b0b14; --bg-card: #161625; --primary: #00d9ff; + --primary-hover: #00b8d9; --primary-glow: rgba(0, 217, 255, 0.3); --secondary: #ff6b6b; + --secondary-hover: #e55a5a; --text-main: #ffffff; --text-dim: #a0a0b0; --accent: #00ff88; + --danger: #ff4d4d; --card-radius: 12px; - --transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); + --input-radius: 8px; + --transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1); } * { @@ -36,7 +40,7 @@ body { .container { padding: 0 20px; } } -/* Header & Typography */ +/* Typography */ h1 { font-size: 2.5rem; font-weight: 800; @@ -47,6 +51,12 @@ h1 { -webkit-text-fill-color: transparent; } +.subtitle { + color: var(--text-dim); + font-size: 1.1rem; + margin-bottom: 30px; +} + .section-header { display: flex; justify-content: space-between; @@ -61,6 +71,105 @@ h1 { padding-left: 15px; } +/* Global Button System */ +.btn { + display: inline-flex; + align-items: center; + justify-content: center; + gap: 8px; + padding: 10px 20px; + border-radius: var(--input-radius); + font-size: 0.9rem; + font-weight: 600; + cursor: pointer; + transition: var(--transition); + border: 1px solid transparent; + text-decoration: none; + color: #fff; + white-space: nowrap; +} + +.btn:disabled { + opacity: 0.6; + cursor: not-allowed; +} + +.btn-primary { + background: var(--primary); + color: #000; +} + +.btn-primary:hover:not(:disabled) { + background: var(--primary-hover); + box-shadow: 0 0 15px var(--primary-glow); + transform: translateY(-1px); +} + +.btn-secondary { + background: rgba(255, 255, 255, 0.05); + border-color: rgba(255, 255, 255, 0.1); + color: var(--text-main); +} + +.btn-secondary:hover:not(:disabled) { + background: rgba(255, 255, 255, 0.1); + border-color: rgba(255, 255, 255, 0.2); +} + +.btn-accent { + background: var(--accent); + color: #000; +} + +.btn-danger { + background: rgba(255, 77, 77, 0.15); + border-color: rgba(255, 77, 77, 0.3); + color: var(--danger); +} + +.btn-danger:hover:not(:disabled) { + background: var(--danger); + color: #fff; +} + +.btn-small, .btn-sm { + padding: 6px 12px; + font-size: 0.8rem; +} + +.btn-xs { + padding: 4px 8px; + font-size: 0.75rem; +} + +.btn-large { + padding: 14px 28px; + font-size: 1rem; +} + +.btn-block { + display: flex; + width: 100%; +} + +.btn-circle { + width: 45px; + height: 45px; + border-radius: 50%; + padding: 0; + font-size: 1.2rem; +} + +/* Legacy class mapping for compatibility */ +.btn-card { + padding: 8px 4px; + font-size: 0.75rem; + font-weight: 700; + text-transform: uppercase; +} +.btn-watch { background: var(--primary); color: #000; } +.btn-download { background: rgba(255, 255, 255, 0.05); border: 1px solid rgba(255, 255, 255, 0.1); color: #fff; } + /* Horizontal Rows (Netflix Style) */ .streaming-row { display: flex; @@ -106,7 +215,7 @@ h1 { .anime-poster { position: relative; - padding-top: 150%; /* standard anime poster ratio */ + padding-top: 150%; background: #000; } @@ -150,21 +259,6 @@ h1 { justify-content: center; } -.btn-circle { - width: 45px; - height: 45px; - border-radius: 50%; - background: var(--primary); - color: #000; - border: none; - display: flex; - align-items: center; - justify-content: center; - cursor: pointer; - font-size: 1.2rem; - box-shadow: 0 4px 15px var(--primary-glow); -} - /* Info Area */ .anime-info { padding: 12px; @@ -198,7 +292,7 @@ h1 { color: var(--text-dim); } -/* Action Buttons (The fix for text overflow) */ +/* Action Buttons Grid */ .anime-card-buttons { display: grid; grid-template-columns: 1fr 1fr; @@ -206,64 +300,23 @@ h1 { margin-bottom: 10px; } -.btn-card { - padding: 8px 4px; - border-radius: 6px; - font-size: 0.7rem; - font-weight: 700; - text-transform: uppercase; - border: none; - cursor: pointer; - display: flex; - align-items: center; - justify-content: center; - gap: 4px; - transition: var(--transition); - white-space: nowrap; - overflow: hidden; -} - -.btn-card i { font-size: 0.8rem; } - -.btn-watch { background: var(--primary); color: #000; } -.btn-download { background: #2a2a3a; color: #fff; border: 1px solid #444; } - -.btn-watch:hover { background: #fff; } -.btn-download:hover { border-color: #fff; } - -.btn-add-watchlist { - width: 100%; - padding: 8px; - background: rgba(255, 255, 255, 0.05); - border: 1px solid rgba(255, 255, 255, 0.1); - color: var(--text-dim); - font-size: 0.75rem; - font-weight: 600; - border-radius: 6px; - cursor: pointer; -} - -.btn-add-watchlist:hover { - background: rgba(255, 255, 255, 0.1); - color: #fff; -} - .btn-add-watchlist.followed { border-color: var(--accent); color: var(--accent); background: rgba(0, 255, 136, 0.1); } -/* Tabs & UI */ +/* Tabs UI */ .tabs { display: flex; - gap: 30px; + gap: 20px; border-bottom: 1px solid rgba(255, 255, 255, 0.1); margin-bottom: 30px; + overflow-x: auto; } .tab { - padding: 15px 0; + padding: 15px 10px; background: none; border: none; color: var(--text-dim); @@ -271,6 +324,19 @@ h1 { cursor: pointer; position: relative; transition: var(--transition); + display: flex; + align-items: center; + gap: 8px; + white-space: nowrap; +} + +.tab svg { + width: 18px; + height: 18px; +} + +.tab:hover { + color: var(--text-main); } .tab.active { @@ -287,31 +353,296 @@ h1 { box-shadow: 0 0 10px var(--primary-glow); } -/* Forms */ +/* Modern Forms & Input Groups */ .input-group { display: flex; - background: rgba(0, 0, 0, 0.4); - border-radius: 12px; - padding: 5px; - border: 1px solid rgba(255, 255, 255, 0.1); + background: rgba(255, 255, 255, 0.03); + border-radius: var(--card-radius); + padding: 6px; + border: 1px solid rgba(255, 255, 255, 0.08); + transition: var(--transition); +} + +.input-group:focus-within { + border-color: var(--primary); + background: rgba(255, 255, 255, 0.05); + box-shadow: 0 0 15px rgba(0, 217, 255, 0.1); } .input-group input { background: none; border: none; - padding: 12px 20px; + padding: 10px 15px; color: #fff; flex-grow: 1; + font-size: 1rem; } .input-group input:focus { outline: none; } .btn-search { - background: var(--primary); - color: #000; - border-radius: 8px; padding: 0 25px; - font-weight: 700; +} + +/* Auth Section UI */ +.auth-panel { + margin-bottom: 25px; + padding: 15px 20px; + background: linear-gradient(90deg, rgba(0, 217, 255, 0.1), transparent); + border: 1px solid rgba(0, 217, 255, 0.15); + border-radius: var(--card-radius); + display: flex; + justify-content: space-between; + align-items: center; +} + +.auth-container { + max-width: 450px; + margin: 80px auto; + padding: 40px; + background: var(--bg-card); + border-radius: 20px; + border: 1px solid rgba(255, 255, 255, 0.05); + box-shadow: 0 20px 50px rgba(0, 0, 0, 0.5); +} + +.auth-title { + text-align: center; + margin-bottom: 30px; +} + +.auth-tabs { + display: flex; + margin-bottom: 30px; + border-bottom: 1px solid rgba(255, 255, 255, 0.1); +} + +.auth-tab { + flex: 1; + padding: 15px; + text-align: center; + cursor: pointer; + color: var(--text-dim); + transition: var(--transition); + font-weight: 600; +} + +.auth-tab.active { + color: var(--primary); + border-bottom: 2px solid var(--primary); +} + +.auth-form { + display: none; +} + +.auth-form.active { + display: block; +} + +.form-group { + margin-bottom: 20px; +} + +.form-group label { + display: block; + margin-bottom: 8px; + color: var(--text-dim); + font-size: 0.9rem; + font-weight: 500; +} + +.form-group input { + width: 100%; + padding: 12px 15px; + background: rgba(255, 255, 255, 0.03); + border: 1px solid rgba(255, 255, 255, 0.1); + border-radius: var(--input-radius); + color: #fff; + font-size: 1rem; + transition: var(--transition); +} + +.form-group input:focus { + outline: none; + border-color: var(--primary); + background: rgba(255, 255, 255, 0.05); + box-shadow: 0 0 10px rgba(0, 217, 255, 0.2); +} + +.auth-error, .auth-success { + padding: 12px 15px; + border-radius: var(--input-radius); + margin-bottom: 20px; + font-size: 0.9rem; + display: none; +} + +.auth-error { + background: rgba(255, 77, 77, 0.1); + border: 1px solid rgba(255, 77, 77, 0.3); + color: var(--danger); +} + +.auth-success { + background: rgba(0, 255, 136, 0.1); + border: 1px solid rgba(0, 255, 136, 0.3); + color: var(--accent); +} + +.show { display: block !important; } + +/* Progress Bars */ +.progress-container { + height: 8px; + background: rgba(0, 0, 0, 0.3); + border-radius: 4px; + margin: 10px 0; + overflow: hidden; +} + +.progress-bar { + height: 100%; + background: linear-gradient(90deg, var(--primary), var(--accent)); + transition: width 0.3s ease; +} + +/* Icon Buttons */ +.btn-icon { + width: 36px; + height: 36px; + padding: 0; + border-radius: 8px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid rgba(255, 255, 255, 0.1); + color: var(--text-main); + display: inline-flex; + align-items: center; + justify-content: center; + cursor: pointer; + transition: var(--transition); +} + +.btn-icon:hover { + background: rgba(255, 255, 255, 0.1); + border-color: rgba(255, 255, 255, 0.2); +} + +.btn-icon.danger { + color: var(--danger); +} + +.btn-icon.danger:hover { + background: rgba(255, 77, 77, 0.15); + border-color: rgba(255, 77, 77, 0.3); +} + +.btn-icon.success { + color: var(--accent); +} + +.btn-icon.success:hover { + background: rgba(0, 255, 136, 0.15); + border-color: rgba(0, 255, 136, 0.3); +} + +/* Download Items */ +.downloads-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); + gap: 20px; +} + +.download-item { + background: var(--bg-card); + border-radius: var(--card-radius); + padding: 20px; + border: 1px solid rgba(255, 255, 255, 0.05); + transition: var(--transition); +} + +.download-item:hover { + border-color: var(--primary); + box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3); +} + +.download-info { + display: flex; + justify-content: space-between; + align-items: flex-start; + gap: 15px; + margin-bottom: 12px; +} + +.download-name { + font-weight: 600; + font-size: 0.95rem; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + flex: 1; +} + +.download-meta { + display: flex; + justify-content: space-between; + font-size: 0.8rem; + color: var(--text-dim); +} + +.download-actions { + display: flex; + gap: 10px; + margin-top: 15px; + justify-content: flex-end; +} + +/* Badge System Enhancements */ +.badge-completed { color: var(--accent); background: rgba(0, 255, 136, 0.1); } +.badge-failed { color: var(--danger); background: rgba(255, 77, 77, 0.1); } +.badge-downloading { color: var(--primary); background: rgba(0, 217, 255, 0.1); } +.badge-paused { color: #ffcc00; background: rgba(255, 204, 0, 0.1); } + +/* Loading Spinners & Empty States */ +.loading-placeholder, .loading-spinner-container { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 60px 20px; + color: var(--text-dim); + gap: 15px; +} + +.spinner { + width: 30px; + height: 30px; + border: 3px solid rgba(0, 217, 255, 0.1); + border-top-color: var(--primary); + border-radius: 50%; + animation: spin 1s linear infinite; +} + +@keyframes spin { + to { transform: rotate(360deg); } +} + +.empty-state, .no-results { + text-align: center; + padding: 80px 20px; + color: var(--text-dim); +} + +.empty-state i, .no-results i { + font-size: 3.5rem; + margin-bottom: 20px; + display: block; + opacity: 0.15; +} + +/* Section Containers */ +.section-container { + margin-bottom: 50px; } /* Responsive Grid for Search */ @@ -324,6 +655,34 @@ h1 { @media (max-width: 768px) { .anime-card { flex: 0 0 160px; } .anime-grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 15px; } - .btn-card span { display: none; } /* Hide text on very small screens, keep icons */ + .btn-card span { display: none; } .btn-card { padding: 10px; } + .tabs { gap: 10px; } + .auth-panel { flex-direction: column; gap: 15px; text-align: center; } +} + +/* Alerts & Toasts */ +.toast-container { + position: fixed; + bottom: 30px; + right: 30px; + z-index: 9999; +} + +.toast { + padding: 15px 25px; + background: var(--bg-card); + border-left: 4px solid var(--primary); + border-radius: 8px; + margin-top: 10px; + box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5); + display: flex; + align-items: center; + gap: 15px; + animation: slideIn 0.3s ease-out; +} + +@keyframes slideIn { + from { transform: translateX(100%); opacity: 0; } + to { transform: translateX(0); opacity: 1; } } diff --git a/static/js/anime-details.js b/static/js/anime-details.js index 551f844..51d36ca 100644 --- a/static/js/anime-details.js +++ b/static/js/anime-details.js @@ -268,10 +268,10 @@ function renderAnimeDetails(anime) { ` : ''}
- + 🔗 Voir sur MAL -
@@ -291,7 +291,7 @@ function renderAnimeDetails(anime) {

📖 Synopsis

-
@@ -405,7 +405,7 @@ function renderStreamingResult(result, query) { ${episodes.length > 20 ? `` : ''} -
diff --git a/static/js/recommendations.js b/static/js/recommendations.js index 3c3559f..a6505c2 100644 --- a/static/js/recommendations.js +++ b/static/js/recommendations.js @@ -26,7 +26,7 @@ async function loadRecommendations() {

Soit l'API MyAnimeList est inaccessible, soit vous n'avez pas encore de téléchargements.

- @@ -40,7 +40,7 @@ async function loadRecommendations() {

❌ Erreur lors du chargement des recommandations.

${error.message}

-
@@ -75,7 +75,7 @@ async function loadLatestReleases() {

L'API MyAnimeList pourrait être temporairement inaccessible.

- @@ -89,7 +89,7 @@ async function loadLatestReleases() {

❌ Erreur lors du chargement des sorties.

${error.message}

-
@@ -180,10 +180,10 @@ function renderRecommendationCard(anime) { ` : ''}
- -
@@ -233,10 +233,10 @@ function renderReleaseCard(anime) { ` : ''}
- -
diff --git a/static/js/series-search.js b/static/js/series-search.js index c60dd1f..3a51f9d 100644 --- a/static/js/series-search.js +++ b/static/js/series-search.js @@ -54,10 +54,10 @@ async function handleSeriesSearch() { ` : ''}
- -
@@ -111,7 +111,7 @@ async function loadSeriesEpisodesDirect(url, title) { `).join('')} - - @@ -98,10 +98,10 @@ function renderSeriesReleaseCard(series) {
- -
@@ -238,7 +238,7 @@ async function loadSeriesReleases() {

❌ Erreur lors du chargement des séries

${error.message}

-
`; @@ -280,11 +280,11 @@ async function loadProvidersGrid() { ` : ''}
${domains.length > 0 ? ` - ` : ''} -
@@ -310,7 +310,7 @@ async function loadProvidersGrid() {
${host.icon} ${host.name}
-
@@ -332,7 +332,7 @@ async function loadProvidersGrid() {

❌ Erreur lors du chargement des fournisseurs

${error.message}

-
diff --git a/templates/components/anime_card.html b/templates/components/anime_card.html index 30c84fa..bdc9182 100644 --- a/templates/components/anime_card.html +++ b/templates/components/anime_card.html @@ -16,7 +16,7 @@
- -
{% if not in_watchlist %} - {% else %} - {% endif %} diff --git a/templates/components/downloads_list.html b/templates/components/downloads_list.html index 181a44b..f372d91 100644 --- a/templates/components/downloads_list.html +++ b/templates/components/downloads_list.html @@ -4,7 +4,7 @@
{{ task.filename }} - {{ task.status }} + {{ task.status | upper }}
@@ -23,21 +23,25 @@ {% elif task.status == 'paused' %} - {% endif %} {% if task.status == 'completed' %} - + + + + {% endif %}
@@ -45,52 +49,8 @@ {% endfor %}
{% else %} -
+
+

Aucun téléchargement en cours

{% endif %} - - diff --git a/templates/components/episode_list.html b/templates/components/episode_list.html index d3bf842..5f3a190 100644 --- a/templates/components/episode_list.html +++ b/templates/components/episode_list.html @@ -1,23 +1,26 @@ -
-
-
-

{{ anime_title }}

- {{ episodes|length }} épisodes disponibles +
+
+
+

{{ anime_title }}

+ {{ episodes|length }} épisodes disponibles
-
- - -
-
+ +
+ +
{% if episodes %} {% for ep in episodes %}
@@ -26,105 +29,103 @@ {{ ep.title or 'Épisode ' ~ (ep.episode_number or loop.index) }}
- -
{% endfor %} {% else %} -

Aucun épisode trouvé pour ce lien.

+
+ +

Aucun épisode trouvé pour cette source.

+
{% endif %}
- - -
@@ -140,7 +30,7 @@ aria-required="true" aria-describedby="loginUsernameHelp" > - Champ obligatoire +
@@ -152,7 +42,7 @@ aria-required="true" >
- + @@ -206,11 +96,11 @@ aria-required="true" >
- + - @@ -219,14 +109,6 @@