From 909ae7de6e8707d2ee979c701998670a4c47c98d Mon Sep 17 00:00:00 2001 From: Berack96 Date: Mon, 16 Feb 2026 00:40:34 +0100 Subject: [PATCH] Aggiungi progetto Database Film con integrazione OMDb API --- javascript/12_Progetti/film/README.md | 146 +++++ javascript/12_Progetti/film/index.html | 51 ++ javascript/12_Progetti/film/index.js | 67 +++ javascript/12_Progetti/film/preferiti.html | 44 ++ javascript/12_Progetti/film/preferiti.js | 29 + javascript/12_Progetti/film/style.css | 647 +++++++++++++++++++++ 6 files changed, 984 insertions(+) create mode 100644 javascript/12_Progetti/film/README.md create mode 100644 javascript/12_Progetti/film/index.html create mode 100644 javascript/12_Progetti/film/index.js create mode 100644 javascript/12_Progetti/film/preferiti.html create mode 100644 javascript/12_Progetti/film/preferiti.js create mode 100644 javascript/12_Progetti/film/style.css diff --git a/javascript/12_Progetti/film/README.md b/javascript/12_Progetti/film/README.md new file mode 100644 index 0000000..0781d49 --- /dev/null +++ b/javascript/12_Progetti/film/README.md @@ -0,0 +1,146 @@ +# Database Film + +Questo è un progetto del corso JavaScript. +Dovrai creare una pagina web per cercare film usando l'**API OMDb** e salvarli nei preferiti con **localStorage**. + +Le funzionalità principali da implementare sono: +1. **Ricerca film** - Usare `fetch` per cercare film per titolo +2. **Mostrare i risultati in una tabella** - con poster, titolo, anno, tipo e pulsante "Aggiungi ai Preferiti" +3. **Salvare nei preferiti** - Usare `localStorage` per salvare i film preferiti +4. **Gestire i preferiti** - Disabilitare il pulsante se il film è già nei preferiti, e creare una pagina separata per visualizzare e rimuovere i preferiti + +## 🔑 Ottenere la Chiave API di OMDb + +Prima di iniziare, devi ottenere una **chiave API gratuita** da OMDb. + +### Passaggi per ottenere la chiave: + +1. **Vai sul sito OMDb**: http://www.omdbapi.com/apikey.aspx +2. **Scegli il piano FREE (Gratis)**: seleziona *"FREE! (1,000 daily limit)"* che ti permette di fare 1000 richieste al giorno senza pagare. Non è necessario inserire i dati della carta di credito. +3. **Compila il Form** con dei dati: + - **Email Address**: il tuo indirizzo email (DEVE ESSERE VALIDO, riceverai un'email) + - **First Name**: il tuo nome (puoi mettere un nome fittizio se vuoi) + - **Last Name**: il tuo cognome (anche questo può essere fittizio) + - **Use**: metti "Learning JavaScript" o qualcosa di simile + - Premi il pulsante "Submit" per inviare la richiesta +4. **Controlla la Email**: riceverai un'email da OMDb con il soggetto "OMDb API - Free API Key". Se non la vedi, controlla la cartella spam o posta indesiderata. Qui troverai un link per attivare la tua chiave API e la tua chiave API stessa. Nota che se non attivi la chiave cliccando sul link, non funzionerà! + +5. **Copia la Chiave API**: dopo aver cliccato sul link di attivazione, vedrai la tua chiave API (è una stringa alfanumerica tipo `abc12345`). Copia questa chiave e incollala nel file `script.js` alla riga dove c'è la costante `API_KEY`. + + ```javascript + const API_KEY = 'abc12345'; // <-- Sostituisci con la tua chiave + ``` + +### Come Funziona l'API OMDb + +URL Base +``` +http://www.omdbapi.com/ +``` + +Cercare Film per Titolo +``` +http://www.omdbapi.com/?apikey=TUA_CHIAVE&s=matrix +``` + +**Parametri**: +- `apikey`: la tua chiave API +- `s`: termine di ricerca (search) + +**Esempio di Risposta**: +```json +{ + "Search": [ + { + "Title": "The Matrix", + "Year": "1999", + "imdbID": "tt0133093", + "Type": "movie", + "Poster": "https://..." + }, + { + "Title": "The Matrix Reloaded", + "Year": "2003", + "imdbID": "tt0234215", + "Type": "movie", + "Poster": "https://..." + } + ], + "totalResults": "12", + "Response": "True" +} +``` + +**Cosa Fare nel Codice**: +1. Costruisci l'URL con la chiave API e il termine di ricerca +2. Fai un `fetch()` all'URL +3. Usa l'array `Search` per mostrare i film + + +## Come Iniziare + +1. **Ottieni la Chiave API**: Segui i passaggi sopra per ottenere la tua chiave OMDb. + +2. **Crea la Repository su GitHub**: Crea una nuova repository su github.com con il seguente nome: DatabaseFilm + +3. **Clona il Progetto** + ```bash + git clone https://github.com/[tuonome]/DatabaseFilm.git + cd DatabaseFilm + ``` + +4. **Copia i File**: Copia tutti i file del progetto nella tua cartella: + - `index.html` + - `preferiti.html` + - `style.css` + - `script.js` + - `preferiti.js` + +5. **Inserisci la Chiave API**: ricorda di inserire la tua chiave API in `script.js` prima di fare il commit iniziale, altrimenti non potrai prendere i dati dei film dall'API. + +6. **Commit Iniziale**: Fai un commit iniziale con i file base e la chiave API configurata. + + +## 💡 Suggerimenti per l'Implementazione + +1. **Usa `fetch()` per chiamare l'API**: costruisci l'URL con la chiave API e il termine di ricerca, poi usa `fetch()` per ottenere i dati. Nella costruzione dell'URL, assicurati di includere tutti i parametri necessari. ***ATTENZIONE*** ai nomi delle proprietà che sono maiuscole negli oggetti restituiti dall'API (es. `Title`, `Year`, `imdbID`, `Type`, `Poster`). + +2. **Gestisci i Poster Mancanti**: se il campo `Poster` è "N/A", mostra un'immagine di placeholder invece del poster del film. Puoi usare un'immagine generica come questa: `https://via.placeholder.com/60x90?text=No+Poster`. + +3. **Crea le Righe della Tabella**: per ogni film nei risultati, crea una riga nella tabella con il poster, titolo, anno, tipo e un pulsante "Aggiungi ai Preferiti". Usa `innerHTML` per inserire i dati dinamicamente. Puoi anche aggiungere una classe CSS al pulsante per poterlo stilizzare e gestire più facilmente. Inoltre consiglio di spezzare la creazione della riga in una funzione separata rispetto alla creazione della tabella, in modo da mantenere il codice più organizzato. + +4. **Salvare nei Preferiti**: quando l'utente clicca su "Aggiungi ai Preferiti", salva il film in un array di preferiti e poi salva questo array in `localStorage` usando `JSON.stringify()`. Assicurati di gestire i casi in cui `localStorage` è vuoto (devi inizializzare l'array) e di non aggiungere duplicati (controlla con l'imdbID). + +6. **Gestire i Preferiti**: nella pagina `preferiti.html`, recupera i preferiti da `localStorage` usando `JSON.parse()`, e mostra la tabella dei preferiti. Aggiungi un pulsante "Rimuovi" per ogni film che, quando cliccato, rimuove il film dai preferiti e aggiorna la visualizzazione. Puoi usare `array.splice()` per rimuovere l'elemento dall'array dei preferiti in base all'indice, oppure `array.filter()` per creare un nuovo array senza il film da rimuovere. + + +## 🐛 Debug + +### La chiave API non funziona +- Hai attivato la chiave cliccando sul link nell'email? +- Hai copiato la chiave completa senza spazi? +- Hai sostituito `'TUA_CHIAVE_API_QUI'` nel codice? + +### I film non si vedono +- Apri la Console (F12) +- Cerca errori di rete (tab Network) +- Verifica che l'URL sia corretto +- Testa l'URL direttamente nel browser + +### localStorage non funziona +- Controlla in DevTools → Application → Local Storage +- Verifica di usare JSON.stringify() quando salvi +- Verifica di usare JSON.parse() quando recuperi + +### I preferiti non si vedono +- Controlla che la chiave sia `'preferiti'` in entrambi i file +- Verifica che `caricaPreferiti()` sia chiamata all'avvio +- Usa console.log() per vedere cosa c'è in localStorage + + +## Risorse Utili + +- [OMDb API Documentation](http://www.omdbapi.com/) +- [MDN - localStorage](https://developer.mozilla.org/it/docs/Web/API/Window/localStorage) +- [MDN - Fetch API](https://developer.mozilla.org/it/docs/Web/API/Fetch_API) +- [MDN - Array Methods](https://developer.mozilla.org/it/docs/Web/JavaScript/Reference/Global_Objects/Array) diff --git a/javascript/12_Progetti/film/index.html b/javascript/12_Progetti/film/index.html new file mode 100644 index 0000000..9191ada --- /dev/null +++ b/javascript/12_Progetti/film/index.html @@ -0,0 +1,51 @@ + + + + + + Database Film + + + +
+
+

🎬 Database Film

+

Cerca e salva i tuoi film preferiti

+ +
+ + +
+ + +
+ + +
+

Risultati della Ricerca

+ + + + + + + + + + + + + +
PosterTitoloAnnoTipoAzioni
+
+ + +
+
+ + + + diff --git a/javascript/12_Progetti/film/index.js b/javascript/12_Progetti/film/index.js new file mode 100644 index 0000000..61f1af4 --- /dev/null +++ b/javascript/12_Progetti/film/index.js @@ -0,0 +1,67 @@ +/** + * Progetto JS - Database Film con OMDb API + * + * ======================================== + * 🔑 COME OTTENERE LA CHIAVE API OMDb + * ======================================== + * + * OMDb API è GRATUITA e molto semplice da usare, ma richiede una chiave + * API per funzionare. Segui i passaggi qui sotto per ottenere la tua chiave. + * + * PASSAGGI: + * 1. Vai su: http://www.omdbapi.com/apikey.aspx + * 2. Seleziona "FREE! (1,000 daily limit)" + * 3. Compila il form con: + * - Email (vera, dato che vi deve arrivare la chiave) + * - First Name (puoi mettere il tuo nome o un nickname) + * - Last Name (puoi mettere il tuo cognome o un nickname) + * - Use ("Testing" va benissimo o "For School Project" se preferisci) + * 4. Clicca su "Submit" + * 5. Controlla la tua email e clicca sul link di attivazione (altrimenti la chiave non funzionerà) + * 6. Copia la tua API Key (dalla mail) e incollala nel codice + * + * NOTA: La chiave gratuita permette al massimo 1000 richieste al giorno (più che sufficienti) + * + * ======================================== + * URL API: + * http://www.omdbapi.com/?apikey={TUA_CHIAVE}&s={TERMINE_DI_RICERCA} + * + * Nota la struttura della query: + * - apikey: la tua chiave API + * - s: termine di ricerca (es. "Matrix") + * ======================================== + * + * Risposta (esempio): + * { + * "Search": [ + * { "Title": "The Matrix", "Year": "1999", "imdbID": "tt0133093", "Type": "movie", "Poster": "url" } + * ], + * "Response": "True" + * } + * + * ======================================== + * FUNZIONALITÀ DA IMPLEMENTARE: + * ======================================== + * + * 1. Creare una variabile per la chiave API (dove mettere la tua chiave) e l'URL base + * 2. Recuperare gli elementi del DOM (input ricerca, bottone, tabella, ecc.) + * 3. Creare una funzione per cercare film dall'API OMDb (usa fetch) + * 4. Creare una funzione per mostrare i risultati in una tabella (spezzala in più funzioni se vuoi) + * 5. Creare una funzione per gestire i preferiti in localStorage (aggiungere i film se non sono già presenti) + * 6. Aggiungere pulsante "Aggiungi ai Preferiti" per ogni film + * 7. Disabilitare il pulsante se il film è già nei preferiti + * + * Suggerimenti per l'implementazione: + * - Usa fetch() per chiamare l'API con il termine di ricerca + * - Usa data.Search per ottenere l'array di film + * - Crea le righe della tabella dinamicamente con innerHTML o createElement) + * - Usa localStorage.setItem() e localStorage.getItem() per i preferiti + * - Salva i preferiti come JSON: JSON.stringify() e JSON.parse() + * - Salva almeno questi dati dei film (titolo, anno, imdbID, tipo, poster) + * - Controlla se un film non è già nei preferiti prima di aggiungerlo (controlla con l'imdbID) + * - Aggiungi event listener al pulsante di ricerca e all'input (per Enter) + * + * Bonus: + * - Gestisci il caso in cui la chiave API non è stata inserita e mostra un messaggio di errore + * - Gestisci il caso in cui non ci sono risultati per la ricerca e mostra un messaggio "Nessun film trovato" + */ diff --git a/javascript/12_Progetti/film/preferiti.html b/javascript/12_Progetti/film/preferiti.html new file mode 100644 index 0000000..15ecaa0 --- /dev/null +++ b/javascript/12_Progetti/film/preferiti.html @@ -0,0 +1,44 @@ + + + + + + I Miei Preferiti + + + +
+
+

⭐ I Miei Preferiti

+

La tua collezione personale di film

+ +
+ + +
+ + + + + + + + + + + + + +
PosterTitoloAnnoTipoAzioni
+
+ + +
+
+ + + + diff --git a/javascript/12_Progetti/film/preferiti.js b/javascript/12_Progetti/film/preferiti.js new file mode 100644 index 0000000..e459dc0 --- /dev/null +++ b/javascript/12_Progetti/film/preferiti.js @@ -0,0 +1,29 @@ +/** + * Pagina Preferiti - Gestione dei Film Preferiti + * + * FUNZIONALITÀ DA IMPLEMENTARE: + * 1. Caricare i film preferiti da localStorage + * 2. Mostrare i film in una tabella con poster, titolo, anno, tipo + * 3. Aggiungere un pulsante "Rimuovi" per ogni film + * 4. Gestire lo stato vuoto (mostrare un messaggio quando non ci sono preferiti) + * + * Suggerimenti per l'implementazione: + * - Recupera gli elementi del DOM (tabella, corpo tabella, messaggio) + * - Crea una funzione per recuperare i preferiti da localStorage (chiave: 'preferiti') + * - Crea una funzione per salvare i preferiti in localStorage + * - Crea una funzione per caricare i preferiti dal localStorage + * - Crea una funzione per visualizzare tutta la tabella dei preferiti (usa un ciclo per creare le righe della tabella) + * - Crea una funzione per rimuovere un film dai preferiti e aggiornare la visualizzazione (usa array.splice con l'indice dell'elemento da rimuovere) + * - Al caricamento della pagina, chiama la funzione per mostrare i preferiti + * - Se non ci sono preferiti, mostra un messaggio del tipo "Nessun film nei preferiti. Vai alla ricerca!" + * + * Bonus: + * - Mostra il numero totale di film preferiti + * - Aggiungi un pulsante "Rimuovi Tutti" per svuotare la lista dei preferiti + */ + + + +// Esempio di caricamento dei preferiti da localStorage e visualizzazione nella tabella +// caricaPreferiti(); +// mostraPreferiti(); diff --git a/javascript/12_Progetti/film/style.css b/javascript/12_Progetti/film/style.css new file mode 100644 index 0000000..46ee054 --- /dev/null +++ b/javascript/12_Progetti/film/style.css @@ -0,0 +1,647 @@ +/* Reset e Base */ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + min-height: 100vh; + padding: 20px; +} + +.container { + max-width: 1200px; + margin: 0 auto; + background: white; + border-radius: 12px; + padding: 30px; + box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2); +} + +/* Header */ +header { + text-align: center; + margin-bottom: 30px; + padding-bottom: 20px; + border-bottom: 2px solid #f0f0f0; +} + +header h1 { + font-size: 2.5rem; + margin-bottom: 10px; + color: #333; +} + +.subtitle { + font-size: 1.1rem; + color: #666; + margin-bottom: 20px; +} + +/* Navigation */ +.navigation { + display: flex; + justify-content: center; + gap: 15px; + margin-top: 20px; +} + +.nav-link { + text-decoration: none; + padding: 10px 20px; + border-radius: 6px; + background: #f5f5f5; + color: #333; + font-weight: 500; + transition: all 0.3s; +} + +.nav-link:hover { + background: #667eea; + color: white; +} + +.nav-link.active { + background: #667eea; + color: white; +} + +/* Search Section */ +.search-section { + display: flex; + gap: 10px; + margin-bottom: 30px; +} + +.search-bar { + flex: 1; + padding: 15px 20px; + border: 2px solid #ddd; + border-radius: 8px; + font-size: 1rem; + transition: border-color 0.3s; +} + +.search-bar:focus { + outline: none; + border-color: #667eea; +} + +.search-btn { + padding: 15px 30px; + background: #667eea; + color: white; + border: none; + border-radius: 8px; + font-size: 1rem; + font-weight: 600; + cursor: pointer; + transition: background 0.3s; +} + +.search-btn:hover { + background: #5568d3; +} + +/* Results Section */ +.results-section { + margin-top: 30px; +} + +.results-section h2 { + color: #333; + margin-bottom: 20px; + font-size: 1.5rem; +} + +/* Table */ +table { + width: 100%; + border-collapse: collapse; + background: white; + border-radius: 8px; + overflow: hidden; + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); +} + +thead { + background: #667eea; + color: white; +} + +th { + padding: 15px; + text-align: left; + font-weight: 600; +} + +td { + padding: 15px; + border-bottom: 1px solid #f0f0f0; +} + +tbody tr:hover { + background: #f9f9f9; +} + +tbody tr:last-child td { + border-bottom: none; +} + +/* Poster */ +.movie-poster { + width: 60px; + height: 90px; + object-fit: cover; + border-radius: 4px; +} + +/* Buttons */ +.btn { + padding: 8px 16px; + border: none; + border-radius: 6px; + font-size: 0.9rem; + font-weight: 600; + cursor: pointer; + transition: all 0.3s; +} + +.btn-add { + background: #28a745; + color: white; +} + +.btn-add:hover { + background: #218838; +} + +.btn-add:disabled { + background: #ccc; + cursor: not-allowed; +} + +.btn-remove { + background: #dc3545; + color: white; +} + +.btn-remove:hover { + background: #c82333; +} + +/* Message */ +.message { + padding: 15px 20px; + border-radius: 8px; + margin-top: 20px; + font-weight: 500; +} + +.message.success { + background: #d4edda; + color: #155724; + border: 1px solid #c3e6cb; +} + +.message.error { + background: #f8d7da; + color: #721c24; + border: 1px solid #f5c6cb; +} + +.message.info { + background: #d1ecf1; + color: #0c5460; + border: 1px solid #bee5eb; +} + +.nascosto { + display: none !important; +} + +/* Empty State */ +.empty-state { + text-align: center; + padding: 60px 20px; + color: #666; +} + +.empty-state-icon { + font-size: 4rem; + margin-bottom: 20px; +} + +.empty-state h3 { + font-size: 1.5rem; + margin-bottom: 10px; + color: #333; +} + +.empty-state p { + font-size: 1rem; + color: #666; +} + +/* Responsive */ +@media (max-width: 768px) { + .container { + padding: 20px; + } + + header h1 { + font-size: 2rem; + } + + .navigation { + flex-direction: column; + } + + .search-section { + flex-direction: column; + } + + table { + font-size: 0.9rem; + } + + th, td { + padding: 10px; + } + + .movie-poster { + width: 40px; + height: 60px; + } +} + + +.container { + max-width: 1400px; + margin: 0 auto; +} + +/* Header */ +header { + text-align: center; + margin-bottom: 40px; +} + +header h1 { + font-size: 3.5rem; + margin-bottom: 10px; + background: linear-gradient(45deg, #f093fb 0%, #f5576c 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; +} + +.subtitle { + font-size: 1.2rem; + color: #8b949e; +} + +/* Filtri */ +.filters { + display: flex; + gap: 15px; + margin-bottom: 30px; + flex-wrap: wrap; + align-items: center; +} + +.search-bar { + flex: 1; + min-width: 250px; + padding: 15px 20px; + border: 2px solid #30363d; + border-radius: 8px; + font-size: 1rem; + background: #161b22; + color: #c9d1d9; + transition: border-color 0.3s; +} + +.search-bar:focus { + outline: none; + border-color: #58a6ff; +} + +.genre-filter { + padding: 15px 20px; + border: 2px solid #30363d; + border-radius: 8px; + font-size: 1rem; + cursor: pointer; + background: #161b22; + color: #c9d1d9; +} + +.rating-filter { + display: flex; + align-items: center; + gap: 10px; +} + +.rating-filter label { + color: #8b949e; + font-size: 0.95rem; +} + +.rating-filter input { + padding: 10px 15px; + border: 2px solid #30363d; + border-radius: 8px; + font-size: 1rem; + background: #161b22; + color: #c9d1d9; + width: 80px; +} + +.rating-filter input:focus { + outline: none; + border-color: #58a6ff; +} + +/* Griglia Film */ +.movies-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); + gap: 25px; + margin-bottom: 40px; +} + +/* Card Film */ +.movie-card { + background: #161b22; + border: 1px solid #30363d; + border-radius: 12px; + overflow: hidden; + transition: transform 0.3s, box-shadow 0.3s; + cursor: pointer; +} + +.movie-card:hover { + transform: translateY(-5px); + box-shadow: 0 8px 30px rgba(88, 166, 255, 0.3); + border-color: #58a6ff; +} + +.movie-poster { + width: 100%; + height: 375px; + object-fit: cover; + background: #0d1117; +} + +.movie-info { + padding: 20px; +} + +.movie-info h3 { + color: #c9d1d9; + margin-bottom: 10px; + font-size: 1.2rem; + min-height: 50px; +} + +.movie-meta { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 10px; +} + +.movie-year { + color: #8b949e; + font-size: 0.9rem; +} + +.movie-rating { + display: flex; + align-items: center; + gap: 5px; + font-weight: bold; +} + +.movie-rating.high { + color: #3fb950; +} + +.movie-rating.medium { + color: #d29922; +} + +.movie-rating.low { + color: #f85149; +} + +.star { + color: #d29922; +} + +/* Loader */ +.loader { + text-align: center; + padding: 40px; +} + +.spinner { + border: 4px solid #30363d; + border-top: 4px solid #58a6ff; + border-radius: 50%; + width: 50px; + height: 50px; + animation: spin 1s linear infinite; + margin: 0 auto 20px; +} + +@keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} + +.nascosto { + display: none !important; +} + +/* Sezione Dettagli */ +.details-section { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(0, 0, 0, 0.85); + display: flex; + justify-content: center; + align-items: center; + z-index: 1000; + animation: fadeIn 0.3s; + overflow-y: auto; + padding: 20px; +} + +@keyframes fadeIn { + from { + opacity: 0; + } + to { + opacity: 1; + } +} + +.details-content { + background: #161b22; + border: 1px solid #30363d; + border-radius: 15px; + padding: 40px; + max-width: 900px; + width: 100%; + max-height: 90vh; + overflow-y: auto; + position: relative; + animation: slideUp 0.3s; +} + +@keyframes slideUp { + from { + transform: translateY(50px); + opacity: 0; + } + to { + transform: translateY(0); + opacity: 1; + } +} + +.close-btn { + position: absolute; + top: 15px; + right: 20px; + font-size: 2.5rem; + background: none; + border: none; + cursor: pointer; + color: #8b949e; + transition: color 0.3s; + line-height: 1; + padding: 0; + z-index: 10; +} + +.close-btn:hover { + color: #c9d1d9; +} + +.details-header { + display: flex; + gap: 30px; + margin-bottom: 30px; +} + +.details-poster { + width: 300px; + border-radius: 10px; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5); +} + +.details-info { + flex: 1; +} + +.details-info h2 { + color: #c9d1d9; + margin-bottom: 10px; + font-size: 2.5rem; +} + +.details-info p { + margin: 12px 0; + line-height: 1.8; + color: #8b949e; + font-size: 1.05rem; +} + +.details-info strong { + color: #c9d1d9; + font-weight: 600; +} + +.genre-tag { + display: inline-block; + padding: 6px 14px; + background: #21262d; + border: 1px solid #30363d; + color: #58a6ff; + border-radius: 20px; + font-size: 0.9rem; + margin-right: 8px; + margin-top: 5px; +} + +.rating-badge { + display: inline-flex; + align-items: center; + gap: 5px; + padding: 8px 16px; + background: #21262d; + border: 1px solid #30363d; + border-radius: 8px; + font-size: 1.2rem; + font-weight: bold; + margin-top: 10px; +} + +.overview-section { + margin-top: 30px; +} + +.overview-section h3 { + color: #c9d1d9; + margin-bottom: 15px; + font-size: 1.5rem; +} + +.overview-section p { + line-height: 1.8; + color: #8b949e; +} + +/* Responsive */ +@media (max-width: 768px) { + header h1 { + font-size: 2.5rem; + } + + .movies-grid { + grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); + } + + .details-header { + flex-direction: column; + } + + .details-poster { + width: 100%; + max-width: 300px; + margin: 0 auto; + } + + .details-content { + padding: 25px; + } + + .filters { + flex-direction: column; + } + + .search-bar, + .genre-filter, + .rating-filter { + width: 100%; + } +}