|
68 | 68 | .filter-options input[type="checkbox"] { margin-top: 2px; accent-color: var(--primary); flex-shrink: 0; } |
69 | 69 | .filter-options .count { color: var(--text-muted); font-size: .78rem; margin-left: auto; white-space: nowrap; } |
70 | 70 |
|
71 | | -/* Cards grid */ |
72 | | -.cards { flex: 1; display: grid; grid-template-columns: repeat(auto-fill, minmax(340px, 1fr)); gap: 18px; } |
73 | | -.card { background: var(--card-bg); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow); overflow: hidden; display: flex; flex-direction: column; transition: box-shadow .2s, transform .15s; } |
74 | | -.card:hover { box-shadow: var(--shadow-lg); transform: translateY(-2px); } |
75 | | -.card-thumb { width: 100%; height: auto; background: #e2e6ea; display: block; } |
76 | | -.card-body { padding: 14px 16px 16px; flex: 1; display: flex; flex-direction: column; } |
77 | | -.card-title { font-size: 1rem; font-weight: 700; color: var(--primary); text-decoration: none; line-height: 1.3; display: block; margin-bottom: 4px; } |
| 71 | +/* Cards list */ |
| 72 | +.cards { flex: 1; display: flex; flex-direction: column; gap: 14px; } |
| 73 | +.card { background: var(--card-bg); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow); overflow: hidden; display: flex; flex-direction: row; transition: box-shadow .2s; } |
| 74 | +.card:hover { box-shadow: var(--shadow-lg); } |
| 75 | +.card-thumb-wrap { width: 220px; min-width: 220px; display: flex; align-items: flex-start; justify-content: center; background: #e2e6ea; overflow: hidden; } |
| 76 | +.card-thumb { width: 100%; height: auto; display: block; } |
| 77 | +.card-body { padding: 14px 18px 14px; flex: 1; display: flex; flex-direction: column; min-width: 0; } |
| 78 | +.card-header { display: flex; align-items: baseline; gap: 10px; margin-bottom: 6px; flex-wrap: wrap; } |
| 79 | +.card-title { font-size: 1.05rem; font-weight: 700; color: var(--primary); text-decoration: none; line-height: 1.3; } |
78 | 80 | .card-title:hover { text-decoration: underline; } |
79 | | -.card-id { font-size: .76rem; color: var(--text-muted); margin-bottom: 8px; } |
80 | | -.card-row { margin-bottom: 6px; } |
81 | | -.card-label { font-size: .74rem; font-weight: 600; text-transform: uppercase; color: var(--text-muted); letter-spacing: .3px; margin-bottom: 2px; } |
| 81 | +.card-id { font-size: .76rem; color: var(--text-muted); white-space: nowrap; } |
| 82 | +.card-tags-area { display: flex; flex-wrap: wrap; gap: 5px 16px; margin-top: 2px; } |
| 83 | +.card-row { display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; } |
| 84 | +.card-label { font-size: .73rem; font-weight: 600; text-transform: uppercase; color: var(--text-muted); letter-spacing: .3px; white-space: nowrap; } |
82 | 85 | .tags { display: flex; flex-wrap: wrap; gap: 4px; } |
83 | | -.tag { display: inline-block; padding: 2px 8px; border-radius: 12px; font-size: .75rem; line-height: 1.5; white-space: nowrap; } |
| 86 | +.tag { display: inline-block; padding: 2px 8px; border-radius: 12px; font-size: .74rem; line-height: 1.45; white-space: nowrap; } |
84 | 87 | .tag-trend { background: #e0f2fe; color: #0369a1; } |
85 | 88 | .tag-platform { background: #fef3c7; color: #92400e; } |
86 | 89 | .tag-product { background: #ede9fe; color: #6d28d9; } |
|
92 | 95 | .difficulty-badge.beginner { background: var(--beginner); } |
93 | 96 | .difficulty-badge.intermediate { background: var(--intermediate); } |
94 | 97 | .difficulty-badge.advanced { background: var(--advanced); } |
95 | | -.card-meta { margin-top: auto; padding-top: 8px; display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 6px; } |
| 98 | +.card-meta { margin-top: auto; padding-top: 6px; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; } |
96 | 99 | .hw-badge { font-size: .76rem; color: var(--text-muted); } |
97 | 100 |
|
98 | 101 | /* No results */ |
99 | | -.no-results { grid-column: 1 / -1; text-align: center; padding: 60px 20px; color: var(--text-muted); } |
| 102 | +.no-results { text-align: center; padding: 60px 20px; color: var(--text-muted); } |
100 | 103 | .no-results h3 { font-size: 1.1rem; margin-bottom: 6px; } |
101 | 104 |
|
| 105 | +@media (max-width: 700px) { |
| 106 | + .card { flex-direction: column; } |
| 107 | + .card-thumb-wrap { width: 100%; min-width: 0; max-height: 180px; } |
| 108 | +} |
| 109 | + |
102 | 110 | /* Loading / Error */ |
103 | 111 | .status-msg { text-align: center; padding: 80px 20px; color: var(--text-muted); font-size: 1rem; } |
104 | 112 |
|
@@ -316,43 +324,39 @@ <h1>Browse Challenge Projects</h1> |
316 | 324 | } |
317 | 325 |
|
318 | 326 | function cardHTML(p) { |
319 | | - const thumb = p.thumbnail |
320 | | - ? `<img class="card-thumb" src="${escAttr(p.thumbnail)}" alt="" loading="lazy" onerror="this.style.display='none'">` |
321 | | - : `<div class="card-thumb" style="display:flex;align-items:center;justify-content:center;color:#aaa;font-size:.9rem;">No image</div>`; |
| 327 | + const thumbInner = p.thumbnail |
| 328 | + ? `<img class="card-thumb" src="${escAttr(p.thumbnail)}" alt="" loading="lazy" onerror="this.parentElement.style.display='none'">` |
| 329 | + : ``; |
322 | 330 |
|
323 | 331 | const diffClass = p.difficulty.toLowerCase(); |
324 | 332 |
|
325 | 333 | let partnerHTML = ""; |
326 | 334 | if (p.has_partner && p.partners.length) { |
327 | | - partnerHTML = `<div class="card-row"><div class="card-label">Partner</div><div class="tags">${p.partners.map(v => `<span class="tag tag-partner">${esc(v)}</span>`).join("")}</div></div>`; |
| 335 | + partnerHTML = `<div class="card-row"><span class="card-label">Partner:</span><div class="tags">${p.partners.map(v => `<span class="tag tag-partner">${esc(v)}</span>`).join("")}</div></div>`; |
328 | 336 | } |
329 | 337 |
|
330 | 338 | return `<article class="card"> |
331 | | - ${thumb} |
| 339 | + ${p.thumbnail ? `<div class="card-thumb-wrap">${thumbInner}</div>` : ""} |
332 | 340 | <div class="card-body"> |
333 | | - <a class="card-title" href="${escAttr(p.project_url)}" target="_blank" rel="noopener">${esc(p.title)}</a> |
334 | | - <div class="card-id">Project #${esc(p.id)}</div> |
335 | | -
|
336 | | - <div class="card-row"><div class="card-label">Technology Trends</div> |
337 | | - <div class="tags">${p.technology_trends.map(v => `<span class="tag tag-trend">${esc(v)}</span>`).join("")}</div></div> |
338 | | -
|
339 | | - <div class="card-row"><div class="card-label">Platforms</div> |
340 | | - <div class="tags">${p.mathworks_platforms.map(v => `<span class="tag tag-platform">${esc(v)}</span>`).join("")}</div></div> |
341 | | -
|
342 | | - ${p.mathworks_products.length ? `<div class="card-row"><div class="card-label">Products</div> |
343 | | - <div class="tags">${p.mathworks_products.map(v => `<span class="tag tag-product">${esc(v)}</span>`).join("")}</div></div>` : ""} |
344 | | -
|
345 | | - <div class="card-row"><div class="card-label">Application Areas</div> |
346 | | - <div class="tags">${p.application_areas.map(v => `<span class="tag tag-area">${esc(v)}</span>`).join("")}</div></div> |
347 | | -
|
348 | | - <div class="card-row"><div class="card-label">Project Type</div> |
349 | | - <div class="tags">${p.project_type.map(v => `<span class="tag tag-type">${esc(v)}</span>`).join("")}</div></div> |
350 | | -
|
351 | | - ${p.hardware_tags.length ? `<div class="card-row"><div class="card-label">Hardware</div> |
352 | | - <div class="tags">${p.hardware_tags.map(v => `<span class="tag tag-hw">${esc(v)}</span>`).join("")}</div></div>` : ""} |
353 | | -
|
354 | | - ${partnerHTML} |
355 | | -
|
| 341 | + <div class="card-header"> |
| 342 | + <a class="card-title" href="${escAttr(p.project_url)}" target="_blank" rel="noopener">${esc(p.title)}</a> |
| 343 | + <span class="card-id">#${esc(p.id)}</span> |
| 344 | + </div> |
| 345 | + <div class="card-tags-area"> |
| 346 | + <div class="card-row"><span class="card-label">Trends:</span> |
| 347 | + <div class="tags">${p.technology_trends.map(v => `<span class="tag tag-trend">${esc(v)}</span>`).join("")}</div></div> |
| 348 | + <div class="card-row"><span class="card-label">Platforms:</span> |
| 349 | + <div class="tags">${p.mathworks_platforms.map(v => `<span class="tag tag-platform">${esc(v)}</span>`).join("")}</div></div> |
| 350 | + ${p.mathworks_products.length ? `<div class="card-row"><span class="card-label">Products:</span> |
| 351 | + <div class="tags">${p.mathworks_products.map(v => `<span class="tag tag-product">${esc(v)}</span>`).join("")}</div></div>` : ""} |
| 352 | + <div class="card-row"><span class="card-label">Areas:</span> |
| 353 | + <div class="tags">${p.application_areas.map(v => `<span class="tag tag-area">${esc(v)}</span>`).join("")}</div></div> |
| 354 | + <div class="card-row"><span class="card-label">Type:</span> |
| 355 | + <div class="tags">${p.project_type.map(v => `<span class="tag tag-type">${esc(v)}</span>`).join("")}</div></div> |
| 356 | + ${p.hardware_tags.length ? `<div class="card-row"><span class="card-label">Hardware:</span> |
| 357 | + <div class="tags">${p.hardware_tags.map(v => `<span class="tag tag-hw">${esc(v)}</span>`).join("")}</div></div>` : ""} |
| 358 | + ${partnerHTML} |
| 359 | + </div> |
356 | 360 | <div class="card-meta"> |
357 | 361 | <span class="difficulty-badge ${diffClass}">${esc(p.difficulty)}</span> |
358 | 362 | <span class="hw-badge">HW: ${esc(p.hardware_required)}</span> |
|
0 commit comments