Spaces:
Running
Running
Hardik commited on
Commit ·
fa77ac9
1
Parent(s): 21ebebb
Add Featured Screenings section with sample reviews
Browse files- frontend/app.js +85 -0
- frontend/index.html +10 -0
- frontend/style.css +180 -0
frontend/app.js
CHANGED
|
@@ -74,6 +74,91 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
| 74 |
}
|
| 75 |
});
|
| 76 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 77 |
function deduplicateKeywords(words) {
|
| 78 |
if (!words) return [];
|
| 79 |
const sorted = [...words].sort((a, b) => b.length - a.length);
|
|
|
|
| 74 |
}
|
| 75 |
});
|
| 76 |
|
| 77 |
+
// Featured Screenings Data
|
| 78 |
+
const featuredReviews = [
|
| 79 |
+
{
|
| 80 |
+
text: "The film's cinematography was breathtaking and the performances were stellar, but the plot had more holes than a slice of Swiss cheese.",
|
| 81 |
+
category: "Mixed",
|
| 82 |
+
difficulty: "medium"
|
| 83 |
+
},
|
| 84 |
+
{
|
| 85 |
+
text: "I cannot recommend this movie enough. It was absolutely fantastic from start to finish!",
|
| 86 |
+
category: "Positive",
|
| 87 |
+
difficulty: "easy"
|
| 88 |
+
},
|
| 89 |
+
{
|
| 90 |
+
text: "This was hands down the worst movie I have ever seen. A complete waste of two hours.",
|
| 91 |
+
category: "Negative",
|
| 92 |
+
difficulty: "easy"
|
| 93 |
+
},
|
| 94 |
+
{
|
| 95 |
+
text: "Sure, because what the world really needed was another superhero reboot with a gritty, dark twist. Bravo, truly groundbreaking.",
|
| 96 |
+
category: "Sarcasm",
|
| 97 |
+
difficulty: "hard"
|
| 98 |
+
},
|
| 99 |
+
{
|
| 100 |
+
text: "The movie wasn't bad, but it wasn't good either. I can't say I disliked it, but I also can't say I liked it.",
|
| 101 |
+
category: "Negation",
|
| 102 |
+
difficulty: "medium"
|
| 103 |
+
},
|
| 104 |
+
{
|
| 105 |
+
text: "A masterpiece that somehow manages to be both profound and profoundly boring at the same time. I think I loved it? Or maybe I hated it?",
|
| 106 |
+
category: "Complex Context",
|
| 107 |
+
difficulty: "hard"
|
| 108 |
+
},
|
| 109 |
+
{
|
| 110 |
+
text: "The acting was phenomenal and the soundtrack was incredible. A truly unforgettable experience.",
|
| 111 |
+
category: "Positive",
|
| 112 |
+
difficulty: "easy"
|
| 113 |
+
},
|
| 114 |
+
{
|
| 115 |
+
text: "Predictable plot, wooden acting, and special effects that looked like they were from 1995. Skip this one.",
|
| 116 |
+
category: "Negative",
|
| 117 |
+
difficulty: "easy"
|
| 118 |
+
}
|
| 119 |
+
];
|
| 120 |
+
|
| 121 |
+
const difficultyBadges = { easy: '🟢 Easy', medium: '🟡 Medium', hard: '🔴 Hard' };
|
| 122 |
+
|
| 123 |
+
function renderFeaturedCards() {
|
| 124 |
+
const grid = document.getElementById('featuredGrid');
|
| 125 |
+
grid.innerHTML = '';
|
| 126 |
+
featuredReviews.forEach((review, index) => {
|
| 127 |
+
const catClass = review.category.toLowerCase().replace(/\s+/g, '-');
|
| 128 |
+
const card = document.createElement('div');
|
| 129 |
+
card.className = 'review-card';
|
| 130 |
+
card.innerHTML = `
|
| 131 |
+
<div class="review-card-top">
|
| 132 |
+
<span class="card-stub">SCREENING ${index + 1}</span>
|
| 133 |
+
</div>
|
| 134 |
+
<div class="review-card-body">
|
| 135 |
+
<p class="review-text">${review.text}</p>
|
| 136 |
+
</div>
|
| 137 |
+
<div class="review-card-footer">
|
| 138 |
+
<span class="category-badge ${catClass}">${review.category}</span>
|
| 139 |
+
<span class="difficulty-badge">${difficultyBadges[review.difficulty]}</span>
|
| 140 |
+
<button class="use-btn" data-index="${index}">Use This Review</button>
|
| 141 |
+
</div>
|
| 142 |
+
`;
|
| 143 |
+
grid.appendChild(card);
|
| 144 |
+
});
|
| 145 |
+
|
| 146 |
+
// Delegate click for "Use This Review" buttons
|
| 147 |
+
grid.addEventListener('click', (e) => {
|
| 148 |
+
const btn = e.target.closest('.use-btn');
|
| 149 |
+
if (!btn) return;
|
| 150 |
+
const idx = parseInt(btn.dataset.index, 10);
|
| 151 |
+
reviewInput.value = featuredReviews[idx].text;
|
| 152 |
+
reviewInput.focus();
|
| 153 |
+
resultsSection.classList.add('hidden');
|
| 154 |
+
errorMessage.textContent = '';
|
| 155 |
+
// Scroll to the input section
|
| 156 |
+
document.querySelector('.input-section').scrollIntoView({ behavior: 'smooth', block: 'center' });
|
| 157 |
+
});
|
| 158 |
+
}
|
| 159 |
+
|
| 160 |
+
renderFeaturedCards();
|
| 161 |
+
|
| 162 |
function deduplicateKeywords(words) {
|
| 163 |
if (!words) return [];
|
| 164 |
const sorted = [...words].sort((a, b) => b.length - a.length);
|
frontend/index.html
CHANGED
|
@@ -51,6 +51,16 @@
|
|
| 51 |
</div>
|
| 52 |
</section>
|
| 53 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 54 |
<section class="results-section hidden" id="resultsSection">
|
| 55 |
<div class="verdict-banner" id="verdictBanner">
|
| 56 |
<div class="verdict-divider"><span class="verdict-divider-icon">✦</span></div>
|
|
|
|
| 51 |
</div>
|
| 52 |
</section>
|
| 53 |
|
| 54 |
+
<section class="featured-section" id="featuredSection">
|
| 55 |
+
<div class="featured-header">
|
| 56 |
+
<h2>Featured Screenings</h2>
|
| 57 |
+
<p class="featured-subtitle">Try one of these sample reviews</p>
|
| 58 |
+
</div>
|
| 59 |
+
<div class="featured-grid" id="featuredGrid">
|
| 60 |
+
<!-- Cards injected by JS -->
|
| 61 |
+
</div>
|
| 62 |
+
</section>
|
| 63 |
+
|
| 64 |
<section class="results-section hidden" id="resultsSection">
|
| 65 |
<div class="verdict-banner" id="verdictBanner">
|
| 66 |
<div class="verdict-divider"><span class="verdict-divider-icon">✦</span></div>
|
frontend/style.css
CHANGED
|
@@ -1168,6 +1168,186 @@ textarea:focus {
|
|
| 1168 |
opacity: 0.8;
|
| 1169 |
}
|
| 1170 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1171 |
@keyframes fadeIn {
|
| 1172 |
from { opacity: 0; transform: translateY(10px); }
|
| 1173 |
to { opacity: 1; transform: translateY(0); }
|
|
|
|
| 1168 |
opacity: 0.8;
|
| 1169 |
}
|
| 1170 |
|
| 1171 |
+
/* ==========================================================================
|
| 1172 |
+
FEATURED SCREENINGS
|
| 1173 |
+
========================================================================== */
|
| 1174 |
+
.featured-section {
|
| 1175 |
+
max-width: 1000px;
|
| 1176 |
+
margin: 0 auto 4rem auto;
|
| 1177 |
+
}
|
| 1178 |
+
|
| 1179 |
+
.featured-header {
|
| 1180 |
+
text-align: center;
|
| 1181 |
+
margin-bottom: 2rem;
|
| 1182 |
+
}
|
| 1183 |
+
|
| 1184 |
+
.featured-header h2 {
|
| 1185 |
+
font-family: 'Playfair Display', serif;
|
| 1186 |
+
color: var(--gold);
|
| 1187 |
+
font-size: 2rem;
|
| 1188 |
+
text-shadow: 0 0 10px var(--gold-glow);
|
| 1189 |
+
margin-bottom: 0.5rem;
|
| 1190 |
+
}
|
| 1191 |
+
|
| 1192 |
+
.featured-subtitle {
|
| 1193 |
+
color: var(--text-muted);
|
| 1194 |
+
font-style: italic;
|
| 1195 |
+
font-size: 1rem;
|
| 1196 |
+
}
|
| 1197 |
+
|
| 1198 |
+
.featured-grid {
|
| 1199 |
+
display: grid;
|
| 1200 |
+
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
| 1201 |
+
gap: 1.5rem;
|
| 1202 |
+
}
|
| 1203 |
+
|
| 1204 |
+
.review-card {
|
| 1205 |
+
background-color: var(--ticket-bg);
|
| 1206 |
+
color: var(--ticket-text);
|
| 1207 |
+
border-radius: var(--border-radius);
|
| 1208 |
+
position: relative;
|
| 1209 |
+
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.4);
|
| 1210 |
+
overflow: hidden;
|
| 1211 |
+
display: flex;
|
| 1212 |
+
flex-direction: column;
|
| 1213 |
+
transition: var(--transition);
|
| 1214 |
+
}
|
| 1215 |
+
|
| 1216 |
+
.review-card:hover {
|
| 1217 |
+
transform: translateY(-4px);
|
| 1218 |
+
box-shadow: 0 12px 30px rgba(0, 0, 0, 0.5);
|
| 1219 |
+
}
|
| 1220 |
+
|
| 1221 |
+
.review-card::before,
|
| 1222 |
+
.review-card::after {
|
| 1223 |
+
content: '';
|
| 1224 |
+
position: absolute;
|
| 1225 |
+
width: 24px;
|
| 1226 |
+
height: 24px;
|
| 1227 |
+
background-color: var(--bg-dark);
|
| 1228 |
+
border-radius: 50%;
|
| 1229 |
+
top: 50px;
|
| 1230 |
+
z-index: 1;
|
| 1231 |
+
}
|
| 1232 |
+
|
| 1233 |
+
.review-card::before { left: -12px; }
|
| 1234 |
+
.review-card::after { right: -12px; }
|
| 1235 |
+
|
| 1236 |
+
.review-card-top {
|
| 1237 |
+
background-color: var(--gold);
|
| 1238 |
+
padding: 0.75rem 1.25rem;
|
| 1239 |
+
display: flex;
|
| 1240 |
+
justify-content: space-between;
|
| 1241 |
+
align-items: center;
|
| 1242 |
+
border-bottom: 2px dashed rgba(0,0,0,0.15);
|
| 1243 |
+
}
|
| 1244 |
+
|
| 1245 |
+
.review-card-top .card-stub {
|
| 1246 |
+
font-family: monospace;
|
| 1247 |
+
font-weight: bold;
|
| 1248 |
+
font-size: 0.7rem;
|
| 1249 |
+
letter-spacing: 1px;
|
| 1250 |
+
border: 1.5px solid var(--ticket-text);
|
| 1251 |
+
padding: 0.15rem 0.4rem;
|
| 1252 |
+
transform: rotate(-3deg);
|
| 1253 |
+
opacity: 0.7;
|
| 1254 |
+
}
|
| 1255 |
+
|
| 1256 |
+
.review-card-body {
|
| 1257 |
+
padding: 1rem 1.25rem;
|
| 1258 |
+
flex-grow: 1;
|
| 1259 |
+
display: flex;
|
| 1260 |
+
flex-direction: column;
|
| 1261 |
+
}
|
| 1262 |
+
|
| 1263 |
+
.review-text {
|
| 1264 |
+
font-size: 0.85rem;
|
| 1265 |
+
line-height: 1.5;
|
| 1266 |
+
margin-bottom: 1rem;
|
| 1267 |
+
flex-grow: 1;
|
| 1268 |
+
display: -webkit-box;
|
| 1269 |
+
-webkit-line-clamp: 4;
|
| 1270 |
+
-webkit-box-orient: vertical;
|
| 1271 |
+
overflow: hidden;
|
| 1272 |
+
}
|
| 1273 |
+
|
| 1274 |
+
.review-card-footer {
|
| 1275 |
+
padding: 0.75rem 1.25rem 1rem;
|
| 1276 |
+
border-top: 1px dashed rgba(0,0,0,0.1);
|
| 1277 |
+
display: flex;
|
| 1278 |
+
align-items: center;
|
| 1279 |
+
gap: 0.5rem;
|
| 1280 |
+
flex-wrap: wrap;
|
| 1281 |
+
}
|
| 1282 |
+
|
| 1283 |
+
.category-badge {
|
| 1284 |
+
font-size: 0.7rem;
|
| 1285 |
+
font-weight: 600;
|
| 1286 |
+
text-transform: uppercase;
|
| 1287 |
+
letter-spacing: 0.5px;
|
| 1288 |
+
padding: 0.2rem 0.6rem;
|
| 1289 |
+
border-radius: 10px;
|
| 1290 |
+
}
|
| 1291 |
+
|
| 1292 |
+
.category-badge.positive {
|
| 1293 |
+
background: rgba(74, 222, 128, 0.2);
|
| 1294 |
+
color: #166534;
|
| 1295 |
+
}
|
| 1296 |
+
|
| 1297 |
+
.category-badge.negative {
|
| 1298 |
+
background: rgba(248, 113, 113, 0.2);
|
| 1299 |
+
color: #991b1b;
|
| 1300 |
+
}
|
| 1301 |
+
|
| 1302 |
+
.category-badge.mixed,
|
| 1303 |
+
.category-badge.complex {
|
| 1304 |
+
background: rgba(251, 191, 36, 0.2);
|
| 1305 |
+
color: #92400e;
|
| 1306 |
+
}
|
| 1307 |
+
|
| 1308 |
+
.category-badge.sarcasm {
|
| 1309 |
+
background: rgba(167, 139, 250, 0.2);
|
| 1310 |
+
color: #5b21b6;
|
| 1311 |
+
}
|
| 1312 |
+
|
| 1313 |
+
.category-badge.negation {
|
| 1314 |
+
background: rgba(96, 165, 250, 0.2);
|
| 1315 |
+
color: #1e40af;
|
| 1316 |
+
}
|
| 1317 |
+
|
| 1318 |
+
.difficulty-badge {
|
| 1319 |
+
font-size: 0.75rem;
|
| 1320 |
+
padding: 0.1rem 0.4rem;
|
| 1321 |
+
border-radius: 8px;
|
| 1322 |
+
opacity: 0.8;
|
| 1323 |
+
}
|
| 1324 |
+
|
| 1325 |
+
.use-btn {
|
| 1326 |
+
margin-left: auto;
|
| 1327 |
+
background: var(--ticket-text);
|
| 1328 |
+
color: var(--ticket-bg);
|
| 1329 |
+
border: none;
|
| 1330 |
+
padding: 0.3rem 0.85rem;
|
| 1331 |
+
font-size: 0.75rem;
|
| 1332 |
+
font-weight: 600;
|
| 1333 |
+
border-radius: 4px;
|
| 1334 |
+
cursor: pointer;
|
| 1335 |
+
font-family: 'Inter', sans-serif;
|
| 1336 |
+
text-transform: uppercase;
|
| 1337 |
+
letter-spacing: 0.5px;
|
| 1338 |
+
transition: var(--transition);
|
| 1339 |
+
}
|
| 1340 |
+
|
| 1341 |
+
.use-btn:hover {
|
| 1342 |
+
background: var(--gold);
|
| 1343 |
+
color: var(--ticket-text);
|
| 1344 |
+
transform: scale(1.05);
|
| 1345 |
+
}
|
| 1346 |
+
|
| 1347 |
+
.use-btn:active {
|
| 1348 |
+
transform: scale(0.95);
|
| 1349 |
+
}
|
| 1350 |
+
|
| 1351 |
@keyframes fadeIn {
|
| 1352 |
from { opacity: 0; transform: translateY(10px); }
|
| 1353 |
to { opacity: 1; transform: translateY(0); }
|