···
48
-
border-collapse: collapse;
background: var(--background);
border: 2px solid var(--secondary);
56
+
transition: border-color 0.2s;
56
-
background: var(--primary);
57
-
color: var(--white);
59
+
.recording-card:hover {
60
+
border-color: var(--primary);
65
+
justify-content: space-between;
66
+
align-items: flex-start;
67
+
margin-bottom: 1rem;
68
-
border-top: 1px solid var(--secondary);
75
+
font-size: 1.125rem;
78
+
margin-bottom: 0.5rem;
73
-
background: color-mix(in srgb, var(--primary) 5%, transparent);
85
+
margin-bottom: 1rem;
90
+
flex-direction: column;
97
+
text-transform: uppercase;
98
+
color: var(--paynes-gray);
99
+
letter-spacing: 0.05em;
103
+
font-size: 0.875rem;
104
+
color: var(--text);
···
130
+
font-size: 0.875rem;
···
···
155
+
.audio-player audio {
background: var(--accent);
124
-
padding: 0.5rem 1rem;
170
+
padding: 0.75rem 1.5rem;
transition: opacity 0.2s;
.approve-btn:hover:not(:disabled) {
···
border: 2px solid #dc2626;
150
-
padding: 0.5rem 1rem;
192
+
padding: 0.75rem 1.5rem;
···
330
-
<th>Meeting Time</th>
331
-
<th>Uploaded By</th>
332
-
<th>Uploaded At</th>
337
-
${this.recordings.map(
338
-
(recording) => html`
340
-
<td>${recording.original_filename}</td>
342
-
<div class="class-info">
343
-
<span class="course-code">${recording.course_code}</span>
344
-
<span class="class-name">${recording.class_name}</span>
367
+
<div class="recordings-grid">
368
+
${this.recordings.map(
369
+
(recording) => html`
370
+
<div class="recording-card">
371
+
<div class="card-header">
372
+
<div class="file-info">
373
+
<div class="filename">${recording.original_filename}</div>
377
+
<div class="meta-row">
378
+
<div class="meta-item">
379
+
<div class="meta-label">Class</div>
380
+
<div class="meta-value">
381
+
<div class="class-info">
382
+
<span class="course-code">${recording.course_code}</span>
383
+
<span class="class-name">${recording.class_name}</span>
349
-
recording.meeting_label
350
-
? html`<span class="meeting-label">${recording.meeting_label}</span>`
351
-
: html`<span style="color: var(--paynes-gray); font-style: italic;">Not specified</span>`
355
-
<div class="user-info">
357
-
src="https://hostedboringavatars.vercel.app/api/marble?size=32&name=${recording.user_id}&colors=2d3142ff,4f5d75ff,bfc0c0ff,ef8354ff"
359
-
class="user-avatar"
361
-
<span>${recording.user_name || recording.user_email}</span>
388
+
<div class="meta-item">
389
+
<div class="meta-label">Meeting Time</div>
390
+
<div class="meta-value">
392
+
recording.meeting_label
393
+
? html`<span class="meeting-label">${recording.meeting_label}</span>`
394
+
: html`<span style="color: var(--paynes-gray); font-style: italic;">Not specified</span>`
364
-
<td class="timestamp">${this.formatTimestamp(recording.created_at)}</td>
366
-
<div class="actions">
367
-
<button class="approve-btn" @click=${() => this.handleApprove(recording.id)}>
368
-
✓ Approve & Transcribe
370
-
<button class="delete-btn" @click=${() => this.handleDelete(recording.id)}>
399
+
<div class="meta-item">
400
+
<div class="meta-label">Uploaded By</div>
401
+
<div class="meta-value">
402
+
<div class="user-info">
404
+
src="https://hostedboringavatars.vercel.app/api/marble?size=24&name=${recording.user_id}&colors=2d3142ff,4f5d75ff,bfc0c0ff,ef8354ff"
406
+
class="user-avatar"
408
+
<span>${recording.user_name || recording.user_email}</span>
413
+
<div class="meta-item">
414
+
<div class="meta-label">Uploaded At</div>
415
+
<div class="meta-value timestamp">
416
+
${this.formatTimestamp(recording.created_at)}
421
+
<div class="audio-player">
422
+
<audio controls preload="metadata" src="/api/transcriptions/${recording.id}/audio"></audio>
425
+
<div class="actions">
426
+
<button class="approve-btn" @click=${() => this.handleApprove(recording.id)}>
427
+
✓ Approve & Transcribe
429
+
<button class="delete-btn" @click=${() => this.handleDelete(recording.id)}>