Skip to main content

max / makenotwork

8.7 KB · 415 lines History Blame Raw
1 /* In the `components` cascade layer, declared in _head_assets.html.
2 This sheet loads after style.css and shares its layer, so a tie still
3 resolves in this file's favour by source order, exactly as when both
4 were unlayered. The creator theme block stays unlayered and outranks
5 both. */
6 @layer components {
7 /* Unified media player styles, shared by audio and video player pages. */
8
9 /* Media container. The 680px measure lives in style.css as the shared
10 reading column, alongside the three other long-form wrappers that used
11 to carry their own copy of it. Only descendants are styled here. */
12
13 /* Author header */
14 .author-header {
15 display: flex;
16 align-items: center;
17 gap: var(--gap-section);
18 margin-bottom: var(--gap-page);
19 }
20
21 .author-avatar {
22 width: 48px;
23 height: 48px;
24 background: var(--surface-sunken);
25 border-radius: var(--radius-round);
26 display: flex;
27 align-items: center;
28 justify-content: center;
29 font-family: var(--font-display);
30 font-size: var(--text-subhead);
31 color: var(--content);
32 }
33
34 .author-info {
35 flex: 1;
36 }
37
38 .author-name {
39 font-family: var(--font-mono);
40 font-size: var(--text-body);
41 color: var(--content);
42 }
43
44 .author-name a {
45 color: inherit;
46 text-decoration: none;
47 }
48
49 .author-name a:hover {
50 text-decoration: underline;
51 }
52
53 .media-meta {
54 font-family: var(--font-mono);
55 font-size: var(--text-note);
56 color: var(--content-muted);
57 }
58
59 /* Title */
60 .media-title {
61 font-family: var(--font-display);
62 font-size: var(--text-display);
63 font-weight: normal;
64 line-height: 1.2;
65 margin-bottom: var(--gap-section);
66 color: var(--content);
67 text-align: left;
68 }
69
70 /* Series name */
71 .media-series {
72 font-family: var(--font-mono);
73 font-size: var(--text-note);
74 color: var(--content-muted);
75 margin-bottom: var(--gap-page);
76 }
77
78 .media-series a {
79 color: var(--action);
80 text-decoration: none;
81 }
82
83 .media-series a:hover {
84 text-decoration: underline;
85 }
86
87 /* Cover art (audio) */
88 .cover-art {
89 background: var(--surface-sunken);
90 aspect-ratio: 1;
91 max-width: 400px;
92 margin: 0 auto var(--gap-page);
93 display: flex;
94 align-items: center;
95 justify-content: center;
96 color: var(--content-muted);
97 font-family: var(--font-mono);
98 }
99
100 .cover-art img {
101 width: 100%;
102 height: 100%;
103 object-fit: cover;
104 }
105
106 /* Video display */
107 .video-display {
108 max-width: 100%;
109 margin: 0 auto var(--gap-page);
110 background: var(--content);
111 }
112
113 .video-display video {
114 width: 100%;
115 display: block;
116 }
117
118 /* Only the active element is shown; the standby preloads the next segment
119 off-screen so pre/mid/post-roll transitions are gapless. */
120 .video-display video.is-standby {
121 display: none;
122 }
123
124 /* Player controls */
125 .media-player {
126 background: var(--surface-overlay);
127 padding: var(--gap-pane);
128 margin-bottom: var(--gap-page);
129 }
130
131 .player-controls {
132 display: flex;
133 align-items: center;
134 gap: var(--gap-section);
135 margin-bottom: var(--gap-section);
136 }
137
138 .play-button {
139 width: 56px;
140 height: 56px;
141 background: var(--primary-dark);
142 color: var(--primary-light);
143 border: none;
144 border-radius: var(--radius-round);
145 cursor: pointer;
146 display: flex;
147 align-items: center;
148 justify-content: center;
149 font-size: var(--text-head);
150 transition: opacity 0.2s ease;
151 flex-shrink: 0;
152 }
153
154 .play-button:hover {
155 opacity: 0.8;
156 }
157
158 .progress-container {
159 flex: 1;
160 }
161
162 .progress-bar {
163 height: 6px;
164 background: var(--surface-sunken);
165 border-radius: var(--radius-control);
166 overflow: hidden;
167 cursor: pointer;
168 margin-bottom: var(--gap-peer);
169 position: relative;
170 }
171
172 .progress-fill {
173 height: 100%;
174 /* respec-ok: name collision, not a contest. layout.css styles
175 `.progress > .progress-fill`, and this one is inside .progress-bar, the
176 media scrubber, which is not the generated primitive and never matches
177 that selector. Worth knowing before anything here adopts .progress: the
178 two would then collide for real. */
179 background: var(--action);
180 width: 0%;
181 border-radius: var(--radius-control);
182 transition: width 0.1s linear;
183 }
184
185 .time-display {
186 display: flex;
187 justify-content: space-between;
188 font-family: var(--font-mono);
189 font-size: var(--text-fine);
190 color: var(--content-muted);
191 }
192
193 .player-secondary {
194 display: flex;
195 justify-content: space-between;
196 align-items: center;
197 padding-top: var(--gap-section);
198 border-top: 1px solid var(--border);
199 }
200
201 .speed-control {
202 font-family: var(--font-mono);
203 font-size: var(--text-note);
204 display: flex;
205 align-items: center;
206 gap: var(--gap-peer);
207 }
208
209 .speed-button {
210 background: var(--surface-sunken);
211 border: none;
212 padding: var(--gap-peer) var(--gap-section);
213 font-family: var(--font-mono);
214 font-size: var(--text-fine);
215 cursor: pointer;
216 color: var(--content);
217 }
218
219 .speed-button:hover {
220 background: var(--border);
221 }
222
223 .speed-button.is-selected {
224 background: var(--primary-dark);
225 color: var(--primary-light);
226 }
227
228 .volume-control {
229 display: flex;
230 align-items: center;
231 gap: var(--gap-peer);
232 }
233
234 .volume-icon {
235 color: var(--content-muted);
236 }
237
238 .volume-slider {
239 width: 80px;
240 height: 4px;
241 background: var(--surface-sunken);
242 border-radius: var(--radius-fine);
243 appearance: none;
244 cursor: pointer;
245 }
246
247 .volume-slider::-webkit-slider-thumb {
248 appearance: none;
249 width: 12px;
250 height: 12px;
251 background: var(--content);
252 border-radius: var(--radius-round);
253 cursor: pointer;
254 }
255
256 .volume-slider::-moz-range-thumb {
257 width: 12px;
258 height: 12px;
259 background: var(--content);
260 border-radius: var(--radius-round);
261 cursor: pointer;
262 border: none;
263 }
264
265 /* Description */
266 .media-description {
267 font-family: var(--font-sans);
268 font-size: var(--text-lead);
269 line-height: 1.9;
270 margin-bottom: var(--gap-page);
271 }
272
273 .media-description p {
274 margin-bottom: var(--gap-pane);
275 }
276
277 /* Chapters */
278 .chapters {
279 background: var(--surface-overlay);
280 padding: var(--gap-pane);
281 margin-bottom: var(--gap-page);
282 }
283
284 .chapters h3 {
285 font-family: var(--font-mono);
286 font-size: var(--text-body);
287 font-weight: normal;
288 margin-bottom: var(--gap-section);
289 color: var(--content);
290 }
291
292 .chapter-list {
293 list-style: none;
294 }
295
296 .chapter-item {
297 display: flex;
298 justify-content: space-between;
299 padding: var(--gap-section) 0;
300 border-bottom: 1px solid var(--border);
301 cursor: pointer;
302 transition: background 0.2s ease;
303 }
304
305 .chapter-item:last-child {
306 border-bottom: none;
307 }
308
309 .chapter-item:hover {
310 background: var(--surface-sunken);
311 /* The bleed and the inset must stay equal or the row shifts on hover,
312 so both sides read the same token. */
313 margin: 0 calc(var(--gap-pane) * -1);
314 padding-left: var(--gap-pane);
315 padding-right: var(--gap-pane);
316 }
317
318 .chapter-title {
319 font-family: var(--font-sans);
320 color: var(--content);
321 }
322
323 .chapter-time {
324 font-family: var(--font-mono);
325 font-size: var(--text-note);
326 color: var(--content-muted);
327 }
328
329 /* Tags */
330 .media-tags {
331 display: flex;
332 gap: var(--gap-peer);
333 flex-wrap: wrap;
334 margin-top: var(--gap-page);
335 padding-top: var(--gap-page);
336 border-top: 1px solid var(--border);
337 }
338
339 .tag {
340 font-family: var(--font-mono);
341 background: var(--surface-sunken);
342 color: var(--content);
343 padding: var(--gap-peer) var(--gap-section);
344 font-size: var(--text-fine);
345 }
346
347 /* Footer */
348 .media-player-footer {
349 font-family: var(--font-mono);
350 text-align: center;
351 padding: var(--gap-page);
352 font-size: var(--text-note);
353 color: var(--content-muted);
354 border-top: 1px solid var(--border);
355 }
356
357 .media-player-footer a {
358 color: var(--content);
359 text-decoration: none;
360 }
361
362 .media-player-footer a:hover {
363 text-decoration: underline;
364 }
365
366 /* Hidden media elements */
367 audio {
368 display: none;
369 }
370
371 /* Skip button for insertion segments */
372 .skip-insertion {
373 font-family: var(--font-mono);
374 font-size: var(--text-fine);
375 background: var(--surface-sunken);
376 border: 1px solid var(--border);
377 padding: var(--gap-peer) var(--gap-section);
378 cursor: pointer;
379 color: var(--content);
380 display: none;
381 margin-top: var(--gap-peer);
382 }
383
384 .skip-insertion:hover {
385 background: var(--border);
386 }
387
388 /* Insertion label shown during playback */
389 .insertion-label {
390 font-family: var(--font-mono);
391 font-size: var(--text-fine);
392 color: var(--content-muted);
393 font-style: italic;
394 display: none;
395 margin-top: var(--gap-bound);
396 }
397
398 /* Responsive */
399 @media (max-width: 599px) {
400 .media-title {
401 font-size: var(--text-title);
402 }
403
404 .cover-art {
405 max-width: 100%;
406 }
407
408 .player-secondary {
409 flex-direction: column;
410 gap: var(--gap-section);
411 align-items: flex-start;
412 }
413 }
414 }
415