|
1 | 1 | <script setup> |
2 | 2 | import decks from './decks' |
3 | | -import { ref } from 'vue' |
4 | | -
|
5 | | -const active = ref(null) |
6 | 3 | </script> |
7 | 4 |
|
8 | 5 | <template> |
9 | 6 | <main class="container"> |
10 | | - <h1>EduSlides Gallery</h1> |
| 7 | + <header class="header"> |
| 8 | + <h1>Slides Gallery</h1> |
| 9 | + <p class="subtitle">Browse and open available slide decks</p> |
| 10 | + </header> |
11 | 11 |
|
12 | 12 | <div class="grid"> |
13 | | - <div |
| 13 | + <a |
14 | 14 | v-for="deck in decks" |
15 | 15 | :key="deck.id" |
| 16 | + :href="deck.url" |
16 | 17 | class="card" |
17 | | - @click="active = deck" |
18 | 18 | > |
19 | | - <img :src="deck.thumbnail" /> |
20 | | - <h2>{{ deck.title }}</h2> |
21 | | - <p>{{ deck.description }}</p> |
22 | | - </div> |
23 | | - </div> |
| 19 | + <div class="card-body"> |
| 20 | + <h2>{{ deck.title }}</h2> |
| 21 | + <p>{{ deck.description }}</p> |
| 22 | + </div> |
24 | 23 |
|
25 | | - <div v-if="active" class="modal" @click.self="active = null"> |
26 | | - <iframe |
27 | | - :src="active.url" |
28 | | - class="deck-frame" |
29 | | - sandbox="allow-scripts allow-same-origin allow-forms allow-pointer-lock allow-popups" |
30 | | - referrerpolicy="no-referrer" |
31 | | - /> |
| 24 | + <div class="meta"> |
| 25 | + <span class="author">{{ deck.author }}</span> |
| 26 | + <span class="date">{{ deck.date }}</span> |
| 27 | + </div> |
| 28 | + </a> |
32 | 29 | </div> |
33 | 30 | </main> |
34 | 31 | </template> |
35 | 32 |
|
36 | 33 | <style> |
| 34 | +/* Layout */ |
37 | 35 | .container { |
38 | | - max-width: 1200px; |
| 36 | + max-width: 1400px; |
39 | 37 | margin: auto; |
40 | | - padding: 2rem; |
41 | | - font-family: system-ui; |
| 38 | + padding: 3rem 2rem; |
| 39 | + font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", |
| 40 | + Roboto, "Helvetica Neue", Arial, sans-serif; |
| 41 | +} |
| 42 | +
|
| 43 | +/* Header */ |
| 44 | +.header { |
| 45 | + margin-bottom: 2.5rem; |
| 46 | +} |
| 47 | +
|
| 48 | +.header h1 { |
| 49 | + font-size: 2.4rem; |
| 50 | + margin: 0; |
42 | 51 | } |
43 | 52 |
|
| 53 | +.subtitle { |
| 54 | + opacity: 0.6; |
| 55 | + margin-top: 0.4rem; |
| 56 | +} |
| 57 | +
|
| 58 | +/* Responsive grid */ |
44 | 59 | .grid { |
45 | 60 | display: grid; |
46 | | - grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); |
47 | | - gap: 1.5rem; |
| 61 | + gap: 1.8rem; |
| 62 | + grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); |
48 | 63 | } |
49 | 64 |
|
| 65 | +/* Card */ |
50 | 66 | .card { |
51 | | - cursor: pointer; |
52 | | - border-radius: 12px; |
53 | | - overflow: hidden; |
54 | | - box-shadow: 0 10px 30px rgba(0,0,0,.1); |
55 | | - transition: transform .2s; |
56 | | - background: white; |
| 67 | + display: flex; |
| 68 | + flex-direction: column; |
| 69 | + justify-content: space-between; |
| 70 | + text-decoration: none; |
| 71 | + color: inherit; |
| 72 | + background: linear-gradient(180deg, #ffffff, #fafafa); |
| 73 | + border-radius: 16px; |
| 74 | + padding: 1.6rem 1.6rem 1.2rem; |
| 75 | + box-shadow: 0 10px 30px rgba(0, 0, 0, 0.08); |
| 76 | + transition: transform 0.2s ease, box-shadow 0.2s ease; |
| 77 | + min-height: 180px; |
57 | 78 | } |
58 | 79 |
|
59 | 80 | .card:hover { |
60 | | - transform: scale(1.03); |
| 81 | + transform: translateY(-6px); |
| 82 | + box-shadow: 0 20px 50px rgba(0, 0, 0, 0.15); |
61 | 83 | } |
62 | 84 |
|
63 | | -.card img { |
64 | | - width: 100%; |
65 | | - height: 160px; |
66 | | - object-fit: cover; |
| 85 | +/* Content */ |
| 86 | +.card h2 { |
| 87 | + font-size: 1.2rem; |
| 88 | + margin: 0 0 0.4rem; |
| 89 | + line-height: 1.3; |
67 | 90 | } |
68 | 91 |
|
69 | | -.modal { |
70 | | - position: fixed; |
71 | | - inset: 0; |
72 | | - background: rgba(0,0,0,.8); |
73 | | - display: flex; |
74 | | - padding: 2rem; |
| 92 | +.card p { |
| 93 | + font-size: 0.95rem; |
| 94 | + opacity: 0.75; |
| 95 | + line-height: 1.4; |
75 | 96 | } |
76 | 97 |
|
77 | | -.modal iframe { |
78 | | - flex: 1; |
79 | | - border-radius: 12px; |
80 | | - background: white; |
| 98 | +/* Metadata */ |
| 99 | +.meta { |
| 100 | + display: flex; |
| 101 | + justify-content: space-between; |
| 102 | + align-items: center; |
| 103 | + margin-top: 1.2rem; |
| 104 | + font-size: 0.8rem; |
| 105 | + opacity: 0.65; |
| 106 | + border-top: 1px solid rgba(0, 0, 0, 0.05); |
| 107 | + padding-top: 0.8rem; |
81 | 108 | } |
82 | 109 |
|
83 | | -.deck-frame { |
84 | | - width: 100%; |
85 | | - height: 100%; |
86 | | - border: none; |
87 | | - background: white; |
| 110 | +.author { |
| 111 | + font-weight: 500; |
88 | 112 | } |
89 | 113 |
|
| 114 | +.date { |
| 115 | + font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, |
| 116 | + "Liberation Mono", monospace; |
| 117 | +} |
90 | 118 | </style> |
0 commit comments