source: Klonkt/src/assets/css/style.css@ 58cad21

main
Last change on this file since 58cad21 was 8c91ed3, checked in by Robin <roboburr@…>, 3 weeks ago

Covers in de leesweergave

Een bericht in de leesstroom begon met kale tekst: de cover ontbrak,
terwijl hij op de berichtpagina, in de tijdlijn en in Grid gewoon staat.
Nu staat hij er ook, boven de titel, in dezelfde volgorde als post.ejs.

Twee dingen komen van post-card en niet van post.ejs. De SLUIER: op de
berichtpagina hangt de NSFW-waarschuwing als banner boven de pagina,
want daar staat een bericht -- in een stroom kan dat niet, want de buren
rollen voorbij en dan is het beeld onderweg al te zien. En thumb(), want
hier staan er meerdere onder elkaar in een stroom die dooraanvult.

De hoogte is begrensd op 45svh. Een paneel is min-height:100svh en snapt;
een staande foto op volle breedte zou titel en eerste alinea onder de
vouw duwen, en dan begint elk bericht met een plaat waar je langs moet
scrollen om te zien wat het is.

Nagekeken en niet aangenomen: beide voedingen van readerItems() halen
SELECT p.* op, dus cover_image_url, cover_video_url, cover_alt, nsfw en
content_warning komen mee. Een versmalde kolommenlijst zou hier niets
opleveren zonder ergens te klagen.

Co-Authored-By: Claude Opus 5 <noreply@…>

  • Property mode set to 100644
File size: 154.4 KB
Line 
1/* ============================================================
2 LOKALE FONTS — SIL OFL 1.1 licensed, self-hosted
3 Geen third-party requests, geen privacy-leak naar Google.
4 Variable WOFF2 bestanden onder /assets/fonts/
5 Licenses in /assets/fonts/licenses/
6 ============================================================ */
7@font-face {
8 font-family: 'Fraunces';
9 font-style: normal;
10 font-display: swap;
11 font-weight: 100 900;
12 src: url('/assets/fonts/fraunces-latin-full-normal.woff2') format('woff2-variations');
13 unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
14}
15@font-face {
16 font-family: 'Fraunces';
17 font-style: italic;
18 font-display: swap;
19 font-weight: 100 900;
20 src: url('/assets/fonts/fraunces-latin-full-italic.woff2') format('woff2-variations');
21 unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
22}
23@font-face {
24 font-family: 'Literata';
25 font-style: normal;
26 font-display: swap;
27 font-weight: 400 700;
28 src: url('/assets/fonts/literata-latin-opsz-normal.woff2') format('woff2-variations');
29 unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
30}
31@font-face {
32 font-family: 'Literata';
33 font-style: italic;
34 font-display: swap;
35 font-weight: 400 700;
36 src: url('/assets/fonts/literata-latin-opsz-italic.woff2') format('woff2-variations');
37 unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
38}
39@font-face {
40 font-family: 'Plus Jakarta Sans';
41 font-style: normal;
42 font-display: swap;
43 font-weight: 400 700;
44 src: url('/assets/fonts/plus-jakarta-sans-latin-wght-normal.woff2') format('woff2-variations');
45 unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
46}
47@font-face {
48 font-family: 'Plus Jakarta Sans';
49 font-style: italic;
50 font-display: swap;
51 font-weight: 400 700;
52 src: url('/assets/fonts/plus-jakarta-sans-latin-wght-italic.woff2') format('woff2-variations');
53 unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
54}
55
56/* Klonkt publieke stijl — editorial-ish, geen emoji-UI */
57
58:root {
59 --font-display: 'Fraunces', Georgia, serif;
60 --font-body: 'Literata', Georgia, serif;
61 --font-ui: 'Plus Jakarta Sans', system-ui, sans-serif;
62 --font-mono: ui-monospace, Menlo, Consolas, monospace;
63 --radius: 8px; --transition: 180ms cubic-bezier(.4,0,.2,1);
64 --safe-top: env(safe-area-inset-top, 0); --safe-bot: env(safe-area-inset-bottom, 0);
65 /* iOS top inset: starts from env(), but a tiny boot script overrides it with a
66 real/measured value (env() resolves to 0 in some iOS standalone states). */
67 --ios-safe-top: env(safe-area-inset-top, 0px);
68 color-scheme: light dark;
69}
70
71/* Native controls (datum/tijd-picker, scrollbars) het SITE-thema laten volgen i.p.v.
72 de OS-voorkeur, en de datum/tijd-velden de site-accentkleur geven. Zo staat de
73 ingebouwde kalender-popup in dark + accent (de popup zelf is een browser-widget,
74 dus fonts/randen blijven van de browser). */
75[data-theme="dark"] { color-scheme: dark; }
76[data-theme="light"] { color-scheme: light; }
77input[type="date"], input[type="time"], input[type="datetime-local"] { accent-color: var(--accent, #6b8f71); }
78input[type="date"]::-webkit-calendar-picker-indicator,
79input[type="time"]::-webkit-calendar-picker-indicator,
80input[type="datetime-local"]::-webkit-calendar-picker-indicator { cursor: pointer; opacity: .7; }
81input[type="date"]:hover::-webkit-calendar-picker-indicator,
82input[type="time"]:hover::-webkit-calendar-picker-indicator,
83input[type="datetime-local"]:hover::-webkit-calendar-picker-indicator { opacity: 1; }
84
85/* ============================================================
86 PALETTES — elk palette definieert alleen bg/tekst/rand shades.
87 --accent wordt LOS ingesteld via de accent-kleur config (inline in template).
88 Palette-selector: <html data-palette="forest"> en optioneel data-theme="dark"|"light".
89 Als geen data-palette = Sage default.
90 ============================================================ */
91
92/* ── SAGE (default) ── warme crème ── */
93:root,
94[data-palette="sage"] {
95 --paper: #faf8f3; --paper-2: #f2ede0;
96 --ink: #1a1a1a; --ink-soft: #3d3833; --ink-muted: #6b6560; --ink-faint: #a8a29e;
97 --rule: #e8e2d5; --rule-2: #d4ccb8;
98}
99@media (prefers-color-scheme: dark) {
100 :root:not([data-theme="light"]):not([data-palette]),
101 [data-palette="sage"]:not([data-theme="light"]) {
102 --paper: #1c1a17; --paper-2: #252220;
103 --ink: #f4ede0; --ink-soft: #d4ccb8; --ink-muted: #a8a29e; --ink-faint: #6b6560;
104 --rule: #3d3833; --rule-2: #4d4740;
105 }
106}
107[data-theme="dark"]:not([data-palette]),
108[data-theme="dark"][data-palette="sage"] {
109 --paper: #1c1a17; --paper-2: #252220;
110 --ink: #f4ede0; --ink-soft: #d4ccb8; --ink-muted: #a8a29e; --ink-faint: #6b6560;
111 --rule: #3d3833; --rule-2: #4d4740;
112}
113
114/* ── KLONKT ── merk-standaard: clean wit → bijna-zwart (neutraal, gouden accent) ── */
115[data-palette="klonkt"] {
116 --paper: #ffffff; --paper-2: #f4f4f5;
117 --ink: #09090b; --ink-soft: #27272a; --ink-muted: #52525b; --ink-faint: #a1a1aa;
118 --rule: #e4e4e7; --rule-2: #d4d4d8;
119}
120@media (prefers-color-scheme: dark) {
121 [data-palette="klonkt"]:not([data-theme="light"]) {
122 --paper: #0a0a0a; --paper-2: #18181b;
123 --ink: #fafafa; --ink-soft: #d4d4d8; --ink-muted: #a1a1aa; --ink-faint: #71717a;
124 --rule: #27272a; --rule-2: #3f3f46;
125 }
126}
127[data-theme="dark"][data-palette="klonkt"] {
128 --paper: #0a0a0a; --paper-2: #18181b;
129 --ink: #fafafa; --ink-soft: #d4d4d8; --ink-muted: #a1a1aa; --ink-faint: #71717a;
130 --rule: #27272a; --rule-2: #3f3f46;
131}
132
133/* ── PAPER ── minimalistisch wit → zwart ── */
134[data-palette="paper"] {
135 --paper: #ffffff; --paper-2: #f4f4f5;
136 --ink: #09090b; --ink-soft: #27272a; --ink-muted: #52525b; --ink-faint: #a1a1aa;
137 --rule: #e4e4e7; --rule-2: #d4d4d8;
138}
139@media (prefers-color-scheme: dark) {
140 [data-palette="paper"]:not([data-theme="light"]) {
141 --paper: #0a0a0a; --paper-2: #18181b;
142 --ink: #fafafa; --ink-soft: #d4d4d8; --ink-muted: #a1a1aa; --ink-faint: #71717a;
143 --rule: #27272a; --rule-2: #3f3f46;
144 }
145}
146[data-theme="dark"][data-palette="paper"] {
147 --paper: #0a0a0a; --paper-2: #18181b;
148 --ink: #fafafa; --ink-soft: #d4d4d8; --ink-muted: #a1a1aa; --ink-faint: #71717a;
149 --rule: #27272a; --rule-2: #3f3f46;
150}
151
152
153/* ── FOREST ── olijfgroen → donker bos ── */
154[data-palette="forest"] {
155 --paper: #f2f6ed; --paper-2: #e1ead6;
156 --ink: #1a2e15; --ink-soft: #2d4a26; --ink-muted: #5a6f52; --ink-faint: #8aa080;
157 --rule: #ccddbd; --rule-2: #adc396;
158}
159@media (prefers-color-scheme: dark) {
160 [data-palette="forest"]:not([data-theme="light"]) {
161 --paper: #0d1f12; --paper-2: #1a331e;
162 --ink: #dcf2d0; --ink-soft: #b8d8a8; --ink-muted: #8aad7c; --ink-faint: #5a7a50;
163 --rule: #2d4a30; --rule-2: #3d5e42;
164 }
165}
166[data-theme="dark"][data-palette="forest"] {
167 --paper: #0d1f12; --paper-2: #1a331e;
168 --ink: #dcf2d0; --ink-soft: #b8d8a8; --ink-muted: #8aad7c; --ink-faint: #5a7a50;
169 --rule: #2d4a30; --rule-2: #3d5e42;
170}
171
172/* ── STONE ── beige bruin → koffie ── */
173[data-palette="stone"] {
174 --paper: #f5f0e8; --paper-2: #e7ddce;
175 --ink: #2b2218; --ink-soft: #4a3a2a; --ink-muted: #78614a; --ink-faint: #a8927b;
176 --rule: #d6c6ac; --rule-2: #bda98a;
177}
178@media (prefers-color-scheme: dark) {
179 [data-palette="stone"]:not([data-theme="light"]) {
180 --paper: #1a130b; --paper-2: #2d2416;
181 --ink: #f5e9d5; --ink-soft: #d4c0a3; --ink-muted: #a8927b; --ink-faint: #786452;
182 --rule: #3d2f1e; --rule-2: #534029;
183 }
184}
185[data-theme="dark"][data-palette="stone"] {
186 --paper: #1a130b; --paper-2: #2d2416;
187 --ink: #f5e9d5; --ink-soft: #d4c0a3; --ink-muted: #a8927b; --ink-faint: #786452;
188 --rule: #3d2f1e; --rule-2: #534029;
189}
190
191/* ── MIDNIGHT ── lavendel → donker paars ── */
192[data-palette="midnight"] {
193 --paper: #f3f1f8; --paper-2: #e3ddf0;
194 --ink: #1e1a2e; --ink-soft: #332c4d; --ink-muted: #5e5478; --ink-faint: #9288a8;
195 --rule: #d4cae3; --rule-2: #b8a9cc;
196}
197@media (prefers-color-scheme: dark) {
198 [data-palette="midnight"]:not([data-theme="light"]) {
199 --paper: #0f0a1f; --paper-2: #1c1432;
200 --ink: #e9def7; --ink-soft: #c4b5d9; --ink-muted: #9d88b8; --ink-faint: #6b5a85;
201 --rule: #2d1f4a; --rule-2: #3d2b5e;
202 }
203}
204[data-theme="dark"][data-palette="midnight"] {
205 --paper: #0f0a1f; --paper-2: #1c1432;
206 --ink: #e9def7; --ink-soft: #c4b5d9; --ink-muted: #9d88b8; --ink-faint: #6b5a85;
207 --rule: #2d1f4a; --rule-2: #3d2b5e;
208}
209
210/* ── SUNSET ── roze crème → diep paars-roze ── */
211[data-palette="sunset"] {
212 --paper: #fdf4f3; --paper-2: #f7e1dc;
213 --ink: #2e1618; --ink-soft: #4d282b; --ink-muted: #7a4a4e; --ink-faint: #b08589;
214 --rule: #ebcac3; --rule-2: #d9a8a0;
215}
216@media (prefers-color-scheme: dark) {
217 [data-palette="sunset"]:not([data-theme="light"]) {
218 --paper: #1f0a14; --paper-2: #321525;
219 --ink: #fce7f3; --ink-soft: #f0c5d3; --ink-muted: #c896a8; --ink-faint: #8a6878;
220 --rule: #4a1f35; --rule-2: #5e2d43;
221 }
222}
223[data-theme="dark"][data-palette="sunset"] {
224 --paper: #1f0a14; --paper-2: #321525;
225 --ink: #fce7f3; --ink-soft: #f0c5d3; --ink-muted: #c896a8; --ink-faint: #8a6878;
226 --rule: #4a1f35; --rule-2: #5e2d43;
227}
228
229/* ── SAND ── warm papier (subtiel, niet fel geel) → warm donker ── (key blijft 'cream') */
230[data-palette="cream"] {
231 --paper: #f7f3ec; --paper-2: #ece5d8;
232 --ink: #232019; --ink-soft: #43392c; --ink-muted: #6f6149; --ink-faint: #a3957c;
233 --rule: #ddd3c0; --rule-2: #c9bca3;
234}
235@media (prefers-color-scheme: dark) {
236 [data-palette="cream"]:not([data-theme="light"]) {
237 --paper: #14120d; --paper-2: #221e15;
238 --ink: #efe9dd; --ink-soft: #d0c6b2; --ink-muted: #a3957c; --ink-faint: #6f6149;
239 --rule: #322c20; --rule-2: #463d2c;
240 }
241}
242[data-theme="dark"][data-palette="cream"] {
243 --paper: #14120d; --paper-2: #221e15;
244 --ink: #efe9dd; --ink-soft: #d0c6b2; --ink-muted: #a3957c; --ink-faint: #6f6149;
245 --rule: #322c20; --rule-2: #463d2c;
246}
247
248/* ── OCEAN ── helder blauw → diep oceaanblauw ── */
249[data-palette="ocean"] {
250 --paper: #eef4fb; --paper-2: #d8e6f7;
251 --ink: #0f2942; --ink-soft: #1d4368; --ink-muted: #4a6e90; --ink-faint: #87a3c0;
252 --rule: #c2d8ee; --rule-2: #a3c2e0;
253}
254@media (prefers-color-scheme: dark) {
255 [data-palette="ocean"]:not([data-theme="light"]) {
256 --paper: #081726; --paper-2: #102a42;
257 --ink: #d6e8fb; --ink-soft: #aecbe8; --ink-muted: #7e9fc0; --ink-faint: #547390;
258 --rule: #1d3a56; --rule-2: #2a4d6e;
259 }
260}
261[data-theme="dark"][data-palette="ocean"] {
262 --paper: #081726; --paper-2: #102a42;
263 --ink: #d6e8fb; --ink-soft: #aecbe8; --ink-muted: #7e9fc0; --ink-faint: #547390;
264 --rule: #1d3a56; --rule-2: #2a4d6e;
265}
266
267/* ── TEAL ── mint-turquoise → diep teal ── */
268[data-palette="teal"] {
269 --paper: #ecf7f5; --paper-2: #cfe9e4;
270 --ink: #0c2e2a; --ink-soft: #194a44; --ink-muted: #467168; --ink-faint: #84aaa2;
271 --rule: #bce0d9; --rule-2: #9bcbc1;
272}
273@media (prefers-color-scheme: dark) {
274 [data-palette="teal"]:not([data-theme="light"]) {
275 --paper: #06201d; --paper-2: #0e332e;
276 --ink: #d4f2ec; --ink-soft: #aad9d0; --ink-muted: #7aaaa0; --ink-faint: #517a72;
277 --rule: #1a4a42; --rule-2: #275e54;
278 }
279}
280[data-theme="dark"][data-palette="teal"] {
281 --paper: #06201d; --paper-2: #0e332e;
282 --ink: #d4f2ec; --ink-soft: #aad9d0; --ink-muted: #7aaaa0; --ink-faint: #517a72;
283 --rule: #1a4a42; --rule-2: #275e54;
284}
285
286/* ── CANDY ── zacht roze-rood → diep kersenrood ── */
287[data-palette="candy"] {
288 --paper: #fdf1f3; --paper-2: #f8d8de;
289 --ink: #3a1018; --ink-soft: #5e1f2a; --ink-muted: #8e4450; --ink-faint: #c2868f;
290 --rule: #f0c5cd; --rule-2: #e3a0ab;
291}
292@media (prefers-color-scheme: dark) {
293 [data-palette="candy"]:not([data-theme="light"]) {
294 --paper: #220810; --paper-2: #3a121d;
295 --ink: #fde0e6; --ink-soft: #f5b8c4; --ink-muted: #cd8b98; --ink-faint: #8e5f6a;
296 --rule: #4d1a28; --rule-2: #632536;
297 }
298}
299[data-theme="dark"][data-palette="candy"] {
300 --paper: #220810; --paper-2: #3a121d;
301 --ink: #fde0e6; --ink-soft: #f5b8c4; --ink-muted: #cd8b98; --ink-faint: #8e5f6a;
302 --rule: #4d1a28; --rule-2: #632536;
303}
304
305/* ── AMBER ── warm honing → diep amber ── */
306[data-palette="amber"] {
307 --paper: #fdf6e9; --paper-2: #f7e6c2;
308 --ink: #3a2a0c; --ink-soft: #5e451a; --ink-muted: #8e7340; --ink-faint: #c2a877;
309 --rule: #f0dca8; --rule-2: #e3c581;
310}
311@media (prefers-color-scheme: dark) {
312 [data-palette="amber"]:not([data-theme="light"]) {
313 --paper: #221a08; --paper-2: #3a2c12;
314 --ink: #fdeecb; --ink-soft: #f0d49a; --ink-muted: #c2a877; --ink-faint: #8e7340;
315 --rule: #4d3a16; --rule-2: #634d20;
316 }
317}
318[data-theme="dark"][data-palette="amber"] {
319 --paper: #221a08; --paper-2: #3a2c12;
320 --ink: #fdeecb; --ink-soft: #f0d49a; --ink-muted: #c2a877; --ink-faint: #8e7340;
321 --rule: #4d3a16; --rule-2: #634d20;
322}
323
324/* ── ROSE ── zacht roze → wijnrood ── */
325[data-palette="rose"] {
326 --paper: #fdf2f4; --paper-2: #f8dde3;
327 --ink: #2e1419; --ink-soft: #4d242c; --ink-muted: #7a4651; --ink-faint: #b3838d;
328 --rule: #f0c9d1; --rule-2: #e0a3af;
329}
330@media (prefers-color-scheme: dark) {
331 [data-palette="rose"]:not([data-theme="light"]) {
332 --paper: #1f0a0f; --paper-2: #33141c;
333 --ink: #fce4ea; --ink-soft: #f0bcc8; --ink-muted: #c98f9d; --ink-faint: #8a6470;
334 --rule: #4a1f2c; --rule-2: #5e2d3a;
335 }
336}
337[data-theme="dark"][data-palette="rose"] {
338 --paper: #1f0a0f; --paper-2: #33141c;
339 --ink: #fce4ea; --ink-soft: #f0bcc8; --ink-muted: #c98f9d; --ink-faint: #8a6470;
340 --rule: #4a1f2c; --rule-2: #5e2d3a;
341}
342
343
344/* ── TERRACOTTA ── warme klei → diep brick ── (key blijft 'mint' voor DB-compat) */
345[data-palette="mint"] {
346 --paper: #faf2ee; --paper-2: #f2ddd0;
347 --ink: #2e1a12; --ink-soft: #4a2c1e; --ink-muted: #7a5544; --ink-faint: #b3917e;
348 --rule: #eccdbb; --rule-2: #ddb49d;
349}
350@media (prefers-color-scheme: dark) {
351 [data-palette="mint"]:not([data-theme="light"]) {
352 --paper: #1f120c; --paper-2: #2e1c13;
353 --ink: #f7e6da; --ink-soft: #e0c3b0; --ink-muted: #b3917c; --ink-faint: #7a5544;
354 --rule: #4a2c1e; --rule-2: #5e3a28;
355 }
356}
357[data-theme="dark"][data-palette="mint"] {
358 --paper: #1f120c; --paper-2: #2e1c13;
359 --ink: #f7e6da; --ink-soft: #e0c3b0; --ink-muted: #b3917c; --ink-faint: #7a5544;
360 --rule: #4a2c1e; --rule-2: #5e3a28;
361}
362
363/* ── LILAC ── zacht lila → donker violet ── */
364[data-palette="lilac"] {
365 --paper: #faf4fb; --paper-2: #f0e0f3;
366 --ink: #2a1830; --ink-soft: #46294f; --ink-muted: #7a5685; --ink-faint: #b393bd;
367 --rule: #e6cdec; --rule-2: #d4abdd;
368}
369@media (prefers-color-scheme: dark) {
370 [data-palette="lilac"]:not([data-theme="light"]) {
371 --paper: #170a1c; --paper-2: #281433;
372 --ink: #f3e2f7; --ink-soft: #dabce4; --ink-muted: #b088c0; --ink-faint: #7a5a88;
373 --rule: #3d1f4a; --rule-2: #4f2b5e;
374 }
375}
376[data-theme="dark"][data-palette="lilac"] {
377 --paper: #170a1c; --paper-2: #281433;
378 --ink: #f3e2f7; --ink-soft: #dabce4; --ink-muted: #b088c0; --ink-faint: #7a5a88;
379 --rule: #3d1f4a; --rule-2: #4f2b5e;
380}
381
382/* Accent-tint wordt berekend uit --accent, zodat hij meegaat bij elke accent-keuze.
383 Wordt in template inline gezet; hier alleen een fallback. */
384:root { --accent: #c2410c; --accent-soft: #ea580c; --accent-tint: #fef2e8; }
385
386* { box-sizing: border-box; }
387html {
388 -webkit-text-size-adjust: 100%; -webkit-tap-highlight-color: transparent;
389 overscroll-behavior-y: none;
390 /* Horizontaal clippen op ROOT-niveau: dit propageert naar de viewport (geen
391 horizontale scroll) ZONDER position:fixed te breken — html is sowieso de
392 document-scroller. De body mag GEEN overflow-x krijgen, want dan zou die een
393 tweede scroll-container worden en zou de fixed bottom-tab meeschuiven. */
394 overflow-x: hidden;
395}
396body {
397 margin: 0;
398}
399
400/* ── Thema-scrollbar: slank, afgerond, subtiel — vervangt de standaard chunky
401 browser-scrollbar (met pijltjes) die niet bij het donkere thema past.
402 Werkt op de pagina én op interne scrollers (queue, chat-thread, dropdowns). ── */
403* {
404 scrollbar-width: thin;
405 scrollbar-color: color-mix(in srgb, var(--ink) 28%, transparent) transparent;
406}
407::-webkit-scrollbar { width: 10px; height: 10px; }
408::-webkit-scrollbar-track { background: transparent; }
409::-webkit-scrollbar-thumb {
410 background-color: color-mix(in srgb, var(--ink) 24%, transparent);
411 border-radius: 999px;
412 border: 2px solid transparent; /* transparante rand → optisch slanker (≈6px) */
413 background-clip: content-box;
414}
415::-webkit-scrollbar-thumb:hover {
416 background-color: color-mix(in srgb, var(--accent) 60%, var(--ink));
417}
418::-webkit-scrollbar-corner { background: transparent; }
419
420/* Login/auth = focus-scherm. Bij htmx-navigatie naar login blijft de bottom-tab
421 uit de vorige pagina in de DOM staan → hier verbergen zodat het login-scherm
422 net zo "kaal" is als bij een full-load (waar de tab niet eens gerenderd wordt). */
423body.on-auth .bottom-tab { display: none; }
424body:not(.admin) {
425 min-height: 100dvh;
426 background: var(--paper); color: var(--ink);
427 font-family: var(--font-body); font-size: 1.0625rem; line-height: 1.65;
428 font-feature-settings: "liga" 1, "kern" 1, "onum" 1;
429 -webkit-font-smoothing: antialiased;
430 /* v9.4 — Sticky footer: body als flex-kolom, main groeit, footer onderaan */
431 display: flex;
432 flex-direction: column;
433}
434body:not(.admin) #pcms-main { flex: 1 0 auto; }
435body:not(.admin) .site-footer { flex-shrink: 0; }
436body:not(.admin)::before {
437 content: ""; position: fixed; inset: 0; z-index: -1; pointer-events: none;
438 /* Per-palette achtergrond-gradient: opgebouwd uit de palette's EIGEN --paper/--paper-2
439 (diagonale verloop) + een zachte accent-glow erbovenop. Werkt automatisch voor elk
440 palet, light én dark — geen per-palette regels nodig. */
441 background: radial-gradient(ellipse at top, color-mix(in srgb, var(--accent) 6%, transparent), transparent 60%),
442 radial-gradient(ellipse at bottom right, color-mix(in srgb, var(--accent) 7%, transparent), transparent 55%),
443 linear-gradient(160deg, var(--paper) 0%, var(--paper-2) 100%);
444}
445/* Klonkt-palet gebruikt nu (net als de andere paletten) de generieke accent-glow
446 hierboven → de achtergrond-gradient volgt de gekozen accentkleur. */
447::selection { background: var(--accent-tint); color: var(--accent); }
448
449h1, h2, h3, h4 { font-family: var(--font-display); font-weight: 450; line-height: 1.15; letter-spacing: -0.015em; margin: 0; text-wrap: balance; font-variation-settings: "opsz" 144, "SOFT" 50; }
450h1 { font-size: clamp(2rem, 4vw + 1rem, 3.5rem); letter-spacing: -0.022em; }
451h2 { font-size: clamp(1.5rem, 2vw + 1rem, 2.25rem); margin: 1.5rem 0 .4rem; }
452h3 { font-size: 1.375rem; margin: 1.25rem 0 .3rem; }
453p { margin: 0 0 .85em; text-wrap: pretty; hyphens: auto; }
454a { color: var(--ink); text-decoration: underline; text-decoration-color: var(--rule-2); text-underline-offset: 3px; transition: color var(--transition), text-decoration-color var(--transition); }
455a:hover { color: var(--accent); text-decoration-color: var(--accent); }
456/* Knop-ankers houden hun eigen tekstkleur bij hover. Zonder dit overschrijft de
457 globale a:hover{color:accent} de knop-tekst → die wordt dezelfde kleur als de
458 accent-achtergrond en valt weg (vooral op sites met een felle accent). */
459a.btn:hover, a.epk-btn:hover { color: var(--ink); }
460a.btn-primary:hover, a.btn-danger:hover, a.btn-success:hover, a.button:hover,
461a.epk-btn-primary:hover, a.dls-btn:hover, a.sh-tix:hover, a.dl-go:hover { color: #fff; text-decoration-color: currentColor; }
462a:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 2px; text-decoration: none; }
463blockquote { margin: 2em 0; padding: .25em 0 .25em 1.25em; border-left: 2px solid var(--accent); font-family: var(--font-display); font-style: italic; font-size: 1.15em; color: var(--ink-soft); }
464code { font-family: var(--font-mono); font-size: .9em; padding: .15em .4em; background: var(--paper-2); border: 1px solid var(--rule); border-radius: 4px; }
465pre { font-family: var(--font-mono); font-size: .85rem; padding: 1.25em 1.5em; background: var(--paper-2); border: 1px solid var(--rule); border-radius: var(--radius); overflow-x: auto; line-height: 1.5; }
466pre code { padding: 0; background: none; border: none; }
467hr { border: 0; border-top: 1px solid var(--rule); margin: 3em auto; max-width: 4rem; }
468
469/* Container — schaalt mee met schermgrootte.
470 42rem default (optimale leesbreedte voor tekst),
471 breder op HD/2.5K/4K waar je meer ademruimte hebt.
472 Grid-view heeft z'n eigen bredere variant (zie .feed-grid). */
473/* Container max-width schaalt per schermformaat.
474 42rem is optimale leesbreedte voor tekst. Op grotere schermen
475 ademruimte geven zonder uitwaaieren. Grid apart geregeld. */
476.container { max-width: 42rem; margin-inline: auto; padding-inline: clamp(1.25rem, 4vw, 2rem); }
477
478/* Post-/leesbreedte. Globaal + hogere specificity (.container.post-page) zodat 'ie
479 de responsive .container-breakpoints (56/72rem) overal overrult — posts én de
480 downloads-pagina krijgen zo exact dezelfde 720px-breedte. */
481.container.post-page { max-width: 720px; margin: 0.5rem auto 2rem; padding: 0 1rem; }
482
483/* Laptop / Full HD — 1440px viewport of groter */
484@media (min-width: 1440px) {
485 .container { max-width: 56rem; }
486}
487/* Desktop / QHD 2.5K — 1920px viewport of groter */
488@media (min-width: 1920px) {
489 .container { max-width: 72rem; }
490}
491/* 4K UHD — 2560px viewport of groter */
492@media (min-width: 2560px) {
493 .container { max-width: 88rem; }
494}
495
496/* Grid-view tiles: Instagram-feel. Max-width schaalt met gekozen kolommen zodat
497 tegels niet te groot of te klein worden. */
498@media (min-width: 1200px) {
499 body[data-grid-cols="4"] .feed-grid.container { max-width: 80rem; }
500 body[data-grid-cols="3"] .feed-grid.container { max-width: 64rem; }
501 body[data-grid-cols="2"] .feed-grid.container { max-width: 48rem; }
502}
503@media (min-width: 1920px) {
504 body[data-grid-cols="4"] .feed-grid.container { max-width: 96rem; }
505}
506
507.icon { width: 1.125em; height: 1.125em; flex-shrink: 0; vertical-align: -0.15em; stroke: currentColor; fill: none; display: inline-block; }
508
509/* Masthead */
510.masthead {
511 border-bottom: 1px solid var(--rule);
512 padding: calc(1rem + var(--ios-safe-top, 0px)) 0 1rem;
513 /* GEEN backdrop-filter hier: een voorouder met backdrop-filter blokkeert de
514 frosted blur van het user-menu-dropdown eronder. Masthead is toch bijna
515 dekkend, dus solide bg i.p.v. blur. */
516 background: color-mix(in srgb, var(--paper) 94%, transparent);
517 position: sticky; top: 0; z-index: 20;
518}
519.masthead-inner { display: flex; align-items: center; justify-content: flex-end; gap: 1.5rem; }
520.masthead-brand { min-width: 0; flex: 1 1 auto; overflow: hidden; }
521.site-title { font-family: var(--font-display); font-size: 1.5rem; font-weight: 500; font-variation-settings: "opsz" 72, "SOFT" 100; letter-spacing: -0.015em; text-decoration: none; color: var(--ink); line-height: 1; display: inline-block; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: bottom; }
522.site-title:hover { color: var(--accent); }
523/* v9.0 — nav-home icon (replaces site-title text in nav) */
524.nav-home {
525 display: inline-flex; align-items: center; justify-content: center;
526 width: 2.25rem; height: 2.25rem;
527 color: var(--ink-soft); text-decoration: none;
528 border-radius: 6px; border: 1px solid transparent;
529 transition: all var(--transition);
530}
531.nav-home:hover { color: var(--ink); background: var(--paper-2); border-color: var(--rule); }
532.nav-home .icon { width: 1.15rem; height: 1.15rem; }
533.top-nav { display: flex; align-items: center; gap: .25rem; flex-shrink: 0; }
534.nav-link, .nav-btn {
535 font-family: var(--font-ui); font-size: .875rem; font-weight: 500;
536 color: var(--ink-soft); text-decoration: none;
537 padding: .5rem .85rem; border-radius: 6px;
538 background: transparent; border: 1px solid transparent;
539 cursor: pointer;
540 display: inline-flex; align-items: center; gap: .4rem;
541 min-height: 2.25rem;
542 transition: all var(--transition);
543}
544.nav-link:hover, .nav-btn:hover { color: var(--ink); background: var(--paper-2); border-color: var(--rule); }
545.nav-link-muted { color: var(--ink-muted); }
546.nav-label { display: none; }
547@media (min-width: 560px) { .nav-label { display: inline; } }
548
549/* Article */
550main { padding-top: 2rem; }
551.page { padding-block: 2rem 3rem; }
552page-container { display: block; font-size: 1.125rem; line-height: 1.75; }
553page-container h1 { font-size: clamp(2rem, 5vw + 1rem, 3.75rem); margin-bottom: 1rem; letter-spacing: -0.025em; }
554page-container img, page-container iframe, page-container video { max-width: 100%; height: auto; display: block; margin: 2rem auto; border-radius: var(--radius); }
555page-container audio { width: 100%; margin: 1.5rem 0; }
556page-container figure { margin: 2rem 0; }
557page-container figcaption { font-family: var(--font-ui); font-size: .85rem; color: var(--ink-muted); text-align: center; margin-top: .5rem; }
558page-container[contenteditable="true"] { outline: 2px dashed var(--accent); outline-offset: .5rem; border-radius: var(--radius); }
559
560.empty { text-align: center; padding: 4rem 1rem; }
561/* Moved account (FEP-7628 slice 3): the signpost above the feed. Loud on
562 purpose — a visitor must not read a stale timeline thinking it is current. */
563.moved-banner {
564 text-align: center;
565 margin: 1.5rem 0 2rem;
566 padding: 1.75rem 1.25rem;
567 border: 2px solid var(--accent, #e8b04b);
568 border-radius: var(--radius, 10px);
569 background: color-mix(in srgb, var(--accent, #e8b04b) 10%, var(--paper-2, var(--paper)));
570}
571.moved-banner-lead { margin: 0 0 .5rem; font-size: 1rem; opacity: .85; }
572.moved-banner-link {
573 display: inline-block;
574 font-family: var(--font-display);
575 font-size: clamp(1.5rem, 5vw, 2.4rem);
576 font-weight: 700;
577 line-height: 1.15;
578 overflow-wrap: anywhere;
579}
580.moved-banner-hint { margin: .75rem 0 0; font-size: .85rem; color: var(--ink-soft); }
581.empty h1 { font-size: 2rem; }
582.empty p { color: var(--ink-muted); }
583
584/* Embeds */
585.pcms-embed, .folio-embed { margin: 2rem 0; }
586.pcms-embed iframe, .pcms-embed video, .pcms-embed audio,
587.folio-embed iframe, .folio-embed video, .folio-embed audio { width: 100%; display: block; border: 0; border-radius: var(--radius); }
588
589/* Article footer */
590.article-footer { display: flex; justify-content: center; padding-top: 2rem; margin-top: 2rem; border-top: 1px solid var(--rule); }
591
592/* Buttons */
593.button {
594 font-family: var(--font-ui); font-size: .875rem; font-weight: 500;
595 padding: .6rem 1.1rem; min-height: 2.5rem;
596 display: inline-flex; align-items: center; gap: .5rem;
597 background: var(--ink); color: var(--paper);
598 border: 1px solid var(--ink);
599 border-radius: 6px;
600 text-decoration: none; cursor: pointer;
601 transition: all var(--transition);
602}
603.button:hover { background: var(--accent); border-color: var(--accent); color: #fff; }
604.button-ghost { background: transparent; color: var(--ink); border-color: var(--rule-2); }
605.button-ghost:hover { background: var(--paper-2); border-color: var(--accent); color: var(--accent); }
606
607/* Pagination */
608.pagination {
609 display: grid;
610 grid-template-columns: 1fr 1fr;
611 gap: 1rem;
612 padding-block: 2rem 4rem;
613 margin-top: 2rem;
614 border-top: 1px solid var(--rule);
615}
616a.pagination-item {
617 display: flex; align-items: center; gap: 1rem; padding: 1rem 1.25rem;
618 border: 2px solid var(--rule-2, var(--rule));
619 border-radius: var(--radius);
620 text-decoration: none; transition: all .15s ease; font-size: .9rem;
621 background: var(--paper-2);
622 min-height: 5rem;
623 min-width: 0;
624 overflow: hidden;
625 cursor: pointer;
626 box-shadow: 0 1px 0 rgba(0,0,0,.02);
627 -webkit-tap-highlight-color: color-mix(in srgb, var(--accent) 30%, transparent);
628 position: relative;
629}
630.pagination-item:not(a) {
631 display: flex; align-items: center; gap: 1rem; padding: 1rem 1.25rem;
632 border: 1px dashed var(--rule); border-radius: var(--radius);
633 font-size: .9rem; background: transparent; min-height: 5rem;
634 min-width: 0; overflow: hidden;
635}
636.pagination-next { flex-direction: row-reverse; text-align: right; }
637a.pagination-item:hover {
638 border-color: var(--accent);
639 background: color-mix(in srgb, var(--accent) 5%, var(--paper-2));
640 transform: translateY(-2px);
641 box-shadow: 0 4px 12px rgba(0,0,0,.08);
642}
643a.pagination-item:active {
644 transform: translateY(0);
645 transition-duration: .05s;
646}
647.pagination-disabled { opacity: .5; cursor: default; font-style: italic; }
648.pagination-body { display: flex; flex-direction: column; gap: .15rem; min-width: 0; flex: 1; }
649.pagination-label {
650 display: block; font-family: var(--font-ui); font-size: .7rem; font-weight: 700;
651 letter-spacing: .08em; text-transform: uppercase; color: var(--accent);
652 margin-bottom: .15rem;
653}
654.pagination-slug {
655 display: block; font-size: .72rem; color: var(--ink-muted);
656 opacity: .75; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
657 font-style: italic;
658}
659.pagination-title {
660 display: block; font-family: var(--font-display); font-weight: 600; color: var(--ink);
661 font-variation-settings: "opsz" 72; font-style: normal;
662 line-height: 1.25; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
663 font-size: 1.05rem;
664 text-decoration: underline;
665 text-decoration-color: var(--rule-2, var(--rule));
666 text-decoration-thickness: 1px;
667 text-underline-offset: 3px;
668 transition: text-decoration-color .15s;
669}
670a.pagination-item:hover .pagination-title {
671 text-decoration-color: var(--accent);
672}
673.pagination .icon {
674 width: 1.75em; height: 1.75em; flex-shrink: 0;
675 color: var(--accent);
676 transition: transform .15s;
677}
678a.pagination-prev:hover .icon { transform: translateX(-4px); }
679a.pagination-next:hover .icon { transform: translateX(4px); }
680
681/* Pinned-targets → accent-tint en dikkere rand voor duidelijkheid */
682.pagination-item.is-pinned {
683 background: color-mix(in srgb, var(--accent) 8%, var(--paper-2));
684 border-color: color-mix(in srgb, var(--accent) 45%, var(--rule));
685}
686a.pagination-item.is-pinned:hover {
687 background: color-mix(in srgb, var(--accent) 15%, var(--paper-2));
688 border-color: var(--accent);
689}
690
691@media (max-width: 800px) { .pagination { grid-template-columns: 1fr; } }
692
693/* Footer */
694.site-footer { padding: 2rem 0 calc(2rem + env(safe-area-inset-bottom, 0px)); border-top: 1px solid var(--rule); margin-top: 4rem; font-family: var(--font-ui); font-size: .85rem; color: var(--ink-muted); }
695.site-footer-inner { display: flex; justify-content: space-between; flex-wrap: wrap; gap: 1rem; align-items: center; }
696.site-footer a { color: var(--ink-muted); text-decoration-color: var(--rule); }
697.site-footer a:hover { color: var(--accent); }
698.site-footer-links { display: flex; gap: 1rem; }
699.sep { color: var(--ink-faint); margin: 0 .5rem; }
700.footer-tagline { font-style: italic; opacity: .8; }
701
702@media print {
703 .masthead, .pagination, .site-footer, .article-footer, .top-nav { display: none; }
704 body { background: #fff; color: #000; }
705}
706@media (prefers-reduced-motion: reduce) { *, *::before, *::after { transition: none !important; animation: none !important; } }
707
708/* ============================================================
709 V7 ADDITIONS — post metadata UI + audio player + post-images
710 ============================================================ */
711
712/* Post header */
713.post-header { margin: 0 0 2rem; }
714.post-cover {
715 margin: 0 0 1.5rem;
716 border-radius: 8px;
717 overflow: hidden;
718 background: color-mix(in srgb, var(--fg) 4%, transparent);
719}
720.post-cover img {
721 display: block;
722 width: 100%;
723 height: auto; /* volledige (niet-bijgesneden) hoogte */
724 /* geen max-height/object-fit: cover meer → de hele afbeelding toont,
725 volle containerbreedte, zijkanten gerespecteerd. */
726}
727.post-title { font-size: clamp(1.6rem, 4vw, 2.6rem); line-height: 1.15; margin: 0 0 .5rem; letter-spacing: -.02em; }
728
729/* Pin banner — duidelijk zichtbaar dat een post gepind is */
730.post-pin-banner {
731 display: inline-flex;
732 align-items: center;
733 gap: .5rem;
734 background: color-mix(in srgb, var(--accent) 14%, transparent);
735 border: 1px solid color-mix(in srgb, var(--accent) 40%, transparent);
736 color: var(--accent);
737 padding: .4rem .8rem;
738 border-radius: 999px;
739 font-size: .75rem;
740 font-weight: 600;
741 text-transform: uppercase;
742 letter-spacing: .08em;
743 margin: 0 0 .85rem;
744 line-height: 1;
745}
746.post-pin-banner-icon { font-size: 1rem; line-height: 1; }
747.post-pin-banner-sep { opacity: .5; }
748.post-pin-banner-pos { opacity: .85; }
749.post-date {
750 color: var(--fg-muted, #888);
751 font-size: .85rem;
752 letter-spacing: .05em;
753 text-transform: uppercase;
754 margin: 0 0 1.5rem;
755}
756
757/* Post-images in content (resize + align) */
758.post-image {
759 margin: 1.5rem 0;
760}
761.post-image img {
762 display: block;
763 height: auto;
764 border-radius: 6px;
765 max-width: 100%;
766}
767.post-image figcaption {
768 font-size: .85rem;
769 color: var(--fg-muted, #888);
770 margin-top: .5rem;
771 font-style: italic;
772 text-align: center;
773}
774.post-image--small img { max-width: 240px; }
775.post-image--medium img { max-width: 440px; }
776.post-image--large img { max-width: 720px; }
777.post-image--full img { width: 100%; max-width: 100%; }
778.post-image--left { text-align: left; }
779.post-image--left img { margin-left: 0; margin-right: auto; }
780.post-image--center { text-align: center; }
781.post-image--center img { margin-left: auto; margin-right: auto; }
782.post-image--right { text-align: right; }
783.post-image--right img { margin-left: auto; margin-right: 0; }
784
785/* Afbeeldingen in de post-tekst vullen ALTIJD de containerbreedte en houden hun
786 natuurlijke (niet-bijgesneden) hoogte — geen vaste hoogte / geen crop. */
787.post-content img {
788 display: block;
789 width: 100%;
790 max-width: 100%;
791 height: auto;
792 border-radius: 6px;
793 margin: 1.4em auto;
794}
795
796/* Video in de post-tekst (C2S-uploads uit Shaer): dezelfde maatvoering als
797 afbeeldingen, plus een plafond. Zonder deze regel rendert een <video> op
798 zijn natuurlijke maat en duwt een portret-video de hele kolom vol; met
799 object-fit blijft het beeld heel binnen het kader. Geldt ook voor de
800 Krant/Berichten (tl-content), waar dezelfde content langskomt. */
801.post-content video, .tl-content video {
802 display: block;
803 width: 100%;
804 max-width: 100%;
805 max-height: min(70vh, 540px);
806 height: auto;
807 object-fit: contain;
808 background: #000;
809 border-radius: 6px;
810 margin: 1.4em auto;
811}
812.post-content audio, .tl-content audio { width: 100%; display: block; margin: 1em auto; }
813
814/* Mini-player + bottom-tab clearance: applied to .pcms-main so the footer
815 is NOT pushed below the viewport bottom. The bars are position:fixed so
816 they overlap whatever they sit on top of; the padding ensures the last
817 content row isn't covered. Footer naturally follows main and now sits
818 exactly at viewport-bottom on short pages (sticky footer flex). */
819.pcms-main { padding-bottom: 5.5rem; }
820body.has-audio-player .pcms-main { padding-bottom: 5.5rem; }
821
822/* Mobiel toetsenbord open (body.kb-open, gezet via visualViewport in shell.ejs):
823 verberg de vaste onderbalken — anders zweven de bottom-tab + mini-speler boven
824 het toetsenbord of overlappen ze het invoerveld. Ze komen terug zodra het
825 toetsenbord sluit. De extra clearance onderaan is dan ook niet meer nodig. */
826body.kb-open .bottom-tab,
827body.kb-open .audio-player { display: none !important; }
828body.kb-open .pcms-main { padding-bottom: 1rem; }
829
830/* Mobiel & tablet (touch): scrollbalken verbergen — scrollen blijft werken, alleen
831 de balk-UI is weg (geen verwarrende/dubbele balken). */
832@media (pointer: coarse) {
833 * { scrollbar-width: none; -ms-overflow-style: none; }
834 *::-webkit-scrollbar { width: 0; height: 0; display: none; }
835}
836
837/* Afbeeldingen lastiger op te slaan (frictie, geen echte beveiliging): geen
838 sleep-naar-bureaublad, geen iOS long-press-bewaarmenu. Rechtsklik wordt in JS
839 geblokkeerd (zie shell.ejs). Covers/hero zijn al CSS-achtergronden = niet via
840 "afbeelding opslaan" te pakken. */
841img { -webkit-user-drag: none; -khtml-user-drag: none; -moz-user-drag: none; user-drag: none; -webkit-touch-callout: none; }
842
843/* ============================================================
844 AUDIO PLAYER v7.1 — SVG iconen, thema-aware, geen emoji
845 ============================================================ */
846.audio-player {
847 position: fixed;
848 left: 0; right: 0; bottom: 0;
849 background: color-mix(in srgb, var(--paper, #fff) 96%, var(--ink, #000));
850 border-top: 1px solid var(--rule, rgba(0,0,0,.1));
851 color: var(--ink, #222);
852 z-index: 1000;
853 backdrop-filter: blur(12px);
854 -webkit-backdrop-filter: blur(12px);
855 box-shadow: 0 -4px 20px rgba(0,0,0,.04);
856}
857[data-theme="dark"] .audio-player {
858 background: color-mix(in srgb, var(--paper, #1a1a1a) 92%, #fff);
859 box-shadow: 0 -4px 20px rgba(0,0,0,.3);
860}
861.audio-player-inner {
862 display: grid;
863 grid-template-columns: minmax(0, 1.6fr) auto minmax(180px, 2fr) auto;
864 gap: 1rem;
865 align-items: center;
866 padding: .65rem 1.25rem;
867 max-width: 1400px;
868 margin: 0 auto;
869}
870
871/* v9.0 — Clickable trigger dat cover + meta combineert zodat klikken erop sheet opent */
872.audio-player-expand-trigger {
873 display: flex;
874 align-items: center;
875 gap: .65rem;
876 min-width: 0;
877 background: none;
878 border: none;
879 padding: 0;
880 margin: 0;
881 cursor: pointer;
882 color: inherit;
883 text-align: left;
884 font: inherit;
885 border-radius: 6px;
886 transition: background .15s;
887}
888.audio-player-expand-trigger:hover {
889 background: color-mix(in srgb, var(--ink, #000) 6%, transparent);
890}
891
892/* Cover art */
893.audio-player-cover {
894 width: 48px; height: 48px;
895 border-radius: 4px;
896 background: linear-gradient(135deg,
897 var(--accent, #c2410c),
898 color-mix(in srgb, var(--accent, #c2410c) 55%, #000));
899 background-size: cover;
900 background-position: center;
901 flex-shrink: 0;
902 position: relative;
903}
904.audio-player-cover.has-image {
905 background-blend-mode: normal;
906}
907
908/* Meta — titel + artiest */
909.audio-player-meta {
910 min-width: 0;
911 display: flex;
912 flex-direction: column;
913 gap: 2px;
914}
915.audio-player-title-wrap {
916 overflow: hidden;
917 white-space: nowrap;
918 position: relative;
919}
920.audio-player-title {
921 display: inline-block;
922 font-family: var(--font-ui, inherit);
923 font-weight: 600;
924 font-size: .9rem;
925 line-height: 1.3;
926 letter-spacing: -.01em;
927 color: var(--ink, inherit);
928 white-space: nowrap;
929}
930.audio-player-title.is-overflowing {
931 animation: audio-title-marquee 6s ease-in-out infinite alternate;
932}
933@keyframes audio-title-marquee {
934 0%, 8% { transform: translateX(0); }
935 92%, 100% { transform: translateX(calc(-1 * var(--audio-shift, 0px))); }
936}
937.audio-player-artist {
938 font-family: var(--font-ui, inherit);
939 font-size: .74rem;
940 line-height: 1.3;
941 color: var(--ink-muted, rgba(0,0,0,.55));
942 white-space: nowrap;
943 overflow: hidden;
944 text-overflow: ellipsis;
945}
946
947/* Controls — prev / play / next */
948.audio-player-controls {
949 display: flex;
950 gap: .1rem;
951 align-items: center;
952}
953.audio-btn {
954 background: transparent;
955 border: none;
956 color: inherit;
957 cursor: pointer;
958 padding: .5rem;
959 border-radius: 50%;
960 transition: background .15s, color .15s, transform .08s;
961 display: inline-flex;
962 align-items: center;
963 justify-content: center;
964 position: relative;
965}
966.audio-btn svg {
967 width: 18px; height: 18px;
968 display: block;
969}
970.audio-btn:hover { background: color-mix(in srgb, var(--ink, #000) 8%, transparent); }
971.audio-btn:active { transform: scale(.94); }
972.audio-btn-play {
973 background: var(--accent, #c2410c);
974 color: #fff;
975 width: 38px; height: 38px;
976 padding: 0;
977}
978.audio-btn-play:hover {
979 background: color-mix(in srgb, var(--accent, #c2410c) 85%, #fff);
980}
981[data-theme="dark"] .audio-btn-play:hover {
982 background: color-mix(in srgb, var(--accent, #c2410c) 85%, #000);
983}
984.audio-btn-play svg { width: 16px; height: 16px; }
985.audio-btn-play .icon-pause { display: none; }
986.audio-player.is-playing .audio-btn-play .icon-play { display: none; }
987.audio-player.is-playing .audio-btn-play .icon-pause { display: block; }
988
989/* Progress bar */
990.audio-player-progress {
991 display: flex;
992 gap: .75rem;
993 align-items: center;
994 min-width: 0;
995}
996.audio-time {
997 font-size: .7rem;
998 color: var(--ink-muted, rgba(0,0,0,.55));
999 font-variant-numeric: tabular-nums;
1000 min-width: 2.7em;
1001 text-align: center;
1002}
1003.audio-seek {
1004 flex: 1;
1005 min-width: 0;
1006 cursor: pointer;
1007 padding: .5rem 0;
1008 position: relative;
1009}
1010.audio-seek-bar {
1011 height: 3px;
1012 background: color-mix(in srgb, var(--ink, #000) 12%, transparent);
1013 border-radius: 2px;
1014 overflow: hidden;
1015 transition: height .15s;
1016}
1017.audio-seek:hover .audio-seek-bar { height: 5px; }
1018.audio-seek-fill {
1019 height: 100%;
1020 background: var(--accent, #c2410c);
1021 width: 0%;
1022 transition: width .1s linear;
1023}
1024
1025/* Volume — popup on hover */
1026.audio-player-volume {
1027 position: relative;
1028 display: flex;
1029 align-items: center;
1030}
1031.audio-btn .icon-mute { display: none; }
1032.audio-player.is-muted .audio-btn .icon-vol { display: none; }
1033.audio-player.is-muted .audio-btn .icon-mute { display: block; }
1034.audio-volume-popup {
1035 position: absolute;
1036 bottom: calc(100% + 8px);
1037 left: 50%;
1038 transform: translateX(-50%) scale(.95);
1039 transform-origin: bottom center;
1040 background: var(--paper, #fff);
1041 border: 1px solid var(--rule, rgba(0,0,0,.1));
1042 border-radius: 8px;
1043 padding: .75rem .5rem;
1044 box-shadow: 0 4px 16px rgba(0,0,0,.15);
1045 opacity: 0;
1046 pointer-events: none;
1047 transition: opacity .15s, transform .15s, visibility .15s;
1048 height: 110px;
1049 visibility: hidden;
1050}
1051/* Invisible bridge tussen knop en popup zodat hover niet breekt */
1052.audio-volume-popup::after {
1053 content: '';
1054 position: absolute;
1055 bottom: -12px;
1056 left: -10px;
1057 right: -10px;
1058 height: 16px;
1059}
1060[data-theme="dark"] .audio-volume-popup {
1061 background: color-mix(in srgb, var(--paper, #111) 92%, #fff);
1062}
1063.audio-player-volume:hover .audio-volume-popup,
1064.audio-player-volume:focus-within .audio-volume-popup,
1065.audio-player-volume.is-open .audio-volume-popup {
1066 opacity: 1;
1067 visibility: visible;
1068 transform: translateX(-50%) scale(1);
1069 pointer-events: auto;
1070}
1071.audio-volume-popup input[type=range] {
1072 /* Standard vertical slider — replaces deprecated -webkit-appearance: slider-vertical. */
1073 writing-mode: vertical-lr;
1074 direction: rtl;
1075 width: 6px;
1076 height: 90px;
1077 accent-color: var(--accent, #c2410c);
1078 /* Grotere hit-area via pseudo-touch padding */
1079 padding: 0 12px;
1080 box-sizing: content-box;
1081 cursor: pointer;
1082}
1083
1084/* Mobile */
1085@media (max-width: 720px) {
1086 .audio-player-inner {
1087 /* v9.0 — 3 cols: expand-trigger (cover+meta) | controls | volume */
1088 grid-template-columns: minmax(0, 1fr) auto auto;
1089 gap: .5rem;
1090 padding: .5rem .8rem;
1091 }
1092 .audio-player-progress {
1093 display: none;
1094 }
1095 .audio-player-cover { width: 40px; height: 40px; }
1096 .audio-btn-play { width: 34px; height: 34px; }
1097 body.has-audio-player .pcms-main { padding-bottom: 4.2rem; }
1098 /* Verberg titel-artiest op bijzonder smal, verstop volume op mobile */
1099 .audio-player-volume { display: none; }
1100}
1101
1102/* Ultra-small schermen (iPhone 4 = 320px; iPhone SE 1st gen = 320px;
1103 iPhone mini ~360px). v9.3 — alles vanaf 320px moet werken; daaronder
1104 accepteren we wel/niet. */
1105@media (max-width: 380px) {
1106 .audio-player-inner {
1107 gap: .35rem;
1108 padding: .4rem .6rem;
1109 }
1110 .audio-player-expand-trigger {
1111 gap: .45rem;
1112 }
1113 .audio-player-cover { width: 36px; height: 36px; }
1114 .audio-player-title { font-size: .88rem; }
1115 .audio-player-artist { font-size: .72rem; }
1116 .audio-player-controls { gap: .15rem; }
1117 .audio-btn { width: 30px; height: 30px; }
1118 .audio-btn svg { width: 16px; height: 16px; }
1119 .audio-btn-play { width: 32px; height: 32px; }
1120 .audio-btn-play svg { width: 18px; height: 18px; }
1121
1122 /* v9.3 — Tracklist compact op smalle telefoons.
1123 Leader 28×28, kleinere gap, padding strakker. Tijd in monoscript blijft
1124 leesbaar; titel krijgt 5-10px meer ruimte. */
1125 .pat-row {
1126 grid-template-columns: 28px 1fr auto;
1127 gap: .5rem;
1128 padding: .45rem .65rem;
1129 }
1130 .pat-row .pat-num,
1131 .pat-row .pat-cover {
1132 width: 28px;
1133 height: 28px;
1134 }
1135 .pat-row::before {
1136 left: .65rem;
1137 width: 28px; height: 28px;
1138 -webkit-mask-size: 22px 22px;
1139 mask-size: 22px 22px;
1140 }
1141 .pat-row .pat-title { font-size: .92rem; }
1142 .pat-row .pat-artist { font-size: .74rem; }
1143 .pat-row .pat-duration { font-size: .74rem; }
1144
1145 /* v9.3 — Album binnen post: cover + tracks compacter */
1146 .post-album-cover {
1147 width: 90px;
1148 height: 90px;
1149 }
1150 .post-album-header {
1151 gap: .65rem;
1152 padding: .65rem;
1153 }
1154 .post-album-title { font-size: 1rem; }
1155
1156 /* v9.3 — Profile-header bovenin compacter */
1157 .profile-photo {
1158 width: 48px !important;
1159 height: 48px !important;
1160 }
1161 .profile-content {
1162 gap: .65rem;
1163 }
1164
1165 /* v9.3 — Install-app modal: minder padding, kleinere knoppen */
1166 .install-modal-inner {
1167 padding: 1rem;
1168 }
1169 .install-app-btn {
1170 padding: .55rem 1rem;
1171 font-size: .9rem;
1172 }
1173
1174 /* v9.3 — horizontaal clippen gebeurt nu globaal op html (zie de html-regel
1175 bovenaan). Hier bewust NIETS op body zetten: body als scroll-container zou
1176 de fixed bottom-tab op mobiel laten meeschuiven. */
1177}
1178
1179/* iPhone 4 / iPhone SE 1st gen / iPhone 5/5s (320px) — strakste niveau */
1180@media (max-width: 340px) {
1181 .audio-player-inner {
1182 padding: .35rem .5rem;
1183 }
1184 .audio-player-artist { display: none; }
1185 .audio-player-cover { width: 32px; height: 32px; }
1186 body.has-audio-player .pcms-main { padding-bottom: 3.6rem; }
1187 /* Expand-sheet wat strakker */
1188 .audio-sheet-panel {
1189 padding: .5rem 1rem 1.5rem;
1190 }
1191 .audio-sheet-title { font-size: 1.2rem; }
1192 .audio-sheet-artist { font-size: .9rem; }
1193 .audio-sheet-play { width: 60px; height: 60px; }
1194 .audio-sheet-play svg { width: 26px; height: 26px; }
1195 .audio-sheet-btn { width: 42px; height: 42px; }
1196 .audio-sheet-btn svg { width: 24px; height: 24px; }
1197 .audio-sheet-controls { gap: 1rem; }
1198
1199 /* v9.3 — Op iPhone 4 (320px): tracklist nog strakker */
1200 .pat-row {
1201 grid-template-columns: 26px 1fr auto;
1202 gap: .4rem;
1203 padding: .4rem .55rem;
1204 }
1205 .pat-row .pat-num,
1206 .pat-row .pat-cover {
1207 width: 26px;
1208 height: 26px;
1209 }
1210 .pat-row::before {
1211 left: .55rem;
1212 width: 26px; height: 26px;
1213 -webkit-mask-size: 20px 20px;
1214 mask-size: 20px 20px;
1215 }
1216 .pat-row .pat-artist {
1217 display: none; /* op extreem smal weglaten ten gunste van titel */
1218 }
1219 .pat-row .pat-title { font-size: .9rem; }
1220 .pat-row .pat-duration { font-size: .72rem; }
1221
1222 /* Container padding reduceren voor max content-breedte */
1223 .container {
1224 padding-inline: 1rem !important;
1225 }
1226
1227 /* Post-cover (de grote bovenste) krimpen */
1228 .post-cover {
1229 max-height: 200px;
1230 }
1231}
1232
1233/* ============================================================
1234 v9.0 — Audio player expand-sheet (Spotify-style "now playing")
1235 Slide-up half-screen met grote cover, track info, big controls
1236 ============================================================ */
1237.audio-sheet {
1238 position: fixed;
1239 inset: 0;
1240 z-index: 1100;
1241 pointer-events: none;
1242 opacity: 0;
1243 transition: opacity .25s ease;
1244}
1245.audio-sheet.is-open {
1246 pointer-events: auto;
1247 opacity: 1;
1248}
1249.audio-sheet-backdrop {
1250 position: absolute;
1251 inset: 0;
1252 /* v9.3 — Blur en overlay-dim allebei via CSS-variabele --pcms-sheet-progress
1253 (1 = volledig, 0 = weg). JS update tijdens drag; CSS-transition pakt
1254 open/close af. Sterke blur (24px) zodat 't effect goed zichtbaar is. */
1255 background: rgb(0 0 0 / calc(.4 * var(--pcms-sheet-progress, 1)));
1256 backdrop-filter: blur(calc(24px * var(--pcms-sheet-progress, 1)));
1257 -webkit-backdrop-filter: blur(calc(24px * var(--pcms-sheet-progress, 1)));
1258 transition: background .25s ease,
1259 backdrop-filter .25s ease,
1260 -webkit-backdrop-filter .25s ease;
1261 will-change: backdrop-filter, background;
1262}
1263/* Tijdens drag: instant updates vanuit JS, geen transition */
1264.audio-sheet-panel.is-dragging ~ .audio-sheet-backdrop,
1265.audio-sheet-backdrop.is-dragging {
1266 transition: none;
1267}
1268.audio-sheet-panel {
1269 position: absolute;
1270 left: 0; right: 0; bottom: 0;
1271 background: var(--paper, #fff);
1272 border-top-left-radius: 20px;
1273 border-top-right-radius: 20px;
1274 box-shadow: 0 -20px 60px rgba(0, 0, 0, .25);
1275 padding: .75rem 1.5rem 2rem;
1276 max-height: 85vh;
1277 overflow-y: auto;
1278 /* v9.2.1 — scroll blijft binnen panel, geen chaining naar body (iOS-proof) */
1279 overscroll-behavior: contain;
1280 touch-action: pan-y;
1281 /* Hide scrollbar but keep scrollable */
1282 scrollbar-width: none; /* Firefox */
1283 -ms-overflow-style: none; /* IE/Edge */
1284 transform: translateY(100%);
1285 transition: transform .3s cubic-bezier(.22, .9, .3, 1),
1286 opacity .3s cubic-bezier(.22, .9, .3, 1);
1287 display: flex;
1288 flex-direction: column;
1289 gap: 1rem;
1290 color: var(--ink);
1291}
1292.audio-sheet-panel::-webkit-scrollbar {
1293 display: none; /* Chrome/Safari */
1294}
1295/* Body scroll lock wanneer sheet open is */
1296body.audio-sheet-locked {
1297 overflow: hidden;
1298}
1299.audio-sheet.is-open .audio-sheet-panel {
1300 transform: translateY(0);
1301}
1302
1303/* v9.3 — Drag-zone: pill bovenaan + cover. Hele strook is touch-target voor
1304 swipe-down-to-close. Pull-to-refresh is uitgeschakeld op html-niveau dus
1305 geen interferentie. Onder de cover (info/progress/controls/queue) werkt
1306 normale touch — knoppen, scroll in queue, etc. */
1307.audio-sheet-drag-zone {
1308 flex-shrink: 0;
1309 display: flex;
1310 flex-direction: column;
1311 align-items: stretch;
1312 gap: 1rem;
1313 /* v9.3 — touch-action: pan-y staat verticale scroll toe (zodat queue
1314 eronder scrollt als gebruiker omhoog veegt over cover). Onze JS
1315 detecteert intent: alleen omlaag-swipe vanaf de top sluit de sheet,
1316 omhoog-swipe = scroll. */
1317 touch-action: pan-y;
1318 user-select: none;
1319 -webkit-user-select: none;
1320 cursor: grab;
1321 margin: -.75rem -1.5rem 0;
1322 padding: .75rem 1.5rem 0;
1323}
1324.audio-sheet-drag-zone:active { cursor: grabbing; }
1325
1326/* v9.4 — Drag alleen actief op touch-only apparaten (telefoons).
1327 Desktop met muis + tablets met muis-cursor → geen drag-grip,
1328 gebruiker sluit via × pill-knop bovenin of klik op backdrop. */
1329@media (hover: hover) and (pointer: fine) {
1330 .audio-sheet-drag-zone {
1331 touch-action: auto;
1332 cursor: default;
1333 pointer-events: none;
1334 }
1335 /* Pill blijft klikbaar als sluit-knop */
1336 .audio-sheet-drag-zone .audio-sheet-handle {
1337 pointer-events: auto;
1338 cursor: pointer;
1339 }
1340}
1341
1342/* Pill (handle) gecentreerd boven de cover */
1343.audio-sheet-drag-zone .audio-sheet-handle {
1344 margin: 0 auto .25rem;
1345}
1346
1347/* Tijdens dragging: panel volgt vinger realtime; geen transition */
1348.audio-sheet-panel.is-dragging {
1349 transition: none;
1350 will-change: transform;
1351}
1352[data-theme="dark"] .audio-sheet-panel {
1353 background: var(--paper, #1a1a1a);
1354 box-shadow: 0 -20px 60px rgba(0, 0, 0, .5);
1355}
1356/* Drag-handle + close button in één */
1357.audio-sheet-handle {
1358 display: block;
1359 width: 48px;
1360 height: 4px;
1361 border-radius: 2px;
1362 background: color-mix(in srgb, var(--ink, #000) 25%, transparent);
1363 border: none;
1364 margin: 0 auto .5rem;
1365 padding: 0;
1366 cursor: pointer;
1367 flex-shrink: 0;
1368 position: relative;
1369}
1370.audio-sheet-handle::before {
1371 content: "";
1372 position: absolute;
1373 /* v9.3 — Drag-strip wrapper neemt nu de hit-area-rol over. ::before
1374 blijft als kleine extra padding voor click-comfort. */
1375 inset: -10px -20px;
1376}
1377.audio-sheet-handle:hover {
1378 background: color-mix(in srgb, var(--ink, #000) 45%, transparent);
1379}
1380/* Grote cover */
1381.audio-sheet-cover {
1382 width: 100%;
1383 max-width: 360px;
1384 aspect-ratio: 1/1;
1385 margin: 0 auto;
1386 border-radius: 12px;
1387 background: linear-gradient(135deg,
1388 var(--accent, #c2410c),
1389 color-mix(in srgb, var(--accent, #c2410c) 55%, #000));
1390 background-size: cover;
1391 background-position: center;
1392 box-shadow: 0 20px 40px rgba(0, 0, 0, .15);
1393 flex-shrink: 0;
1394}
1395[data-theme="dark"] .audio-sheet-cover {
1396 box-shadow: 0 20px 40px rgba(0, 0, 0, .4);
1397}
1398.audio-sheet-info {
1399 text-align: center;
1400 padding: 0 1rem;
1401}
1402.audio-sheet-title {
1403 font-family: var(--font-display, inherit);
1404 font-size: 1.5rem;
1405 font-weight: 600;
1406 line-height: 1.2;
1407 margin: 0 0 .25rem;
1408 letter-spacing: -0.01em;
1409 color: var(--ink);
1410}
1411.audio-sheet-artist {
1412 font-size: 1rem;
1413 color: var(--ink-muted, var(--ink));
1414 opacity: .7;
1415}
1416.audio-sheet-album {
1417 margin-top: .35rem;
1418 font-size: .82rem;
1419 opacity: .5;
1420 text-transform: uppercase;
1421 letter-spacing: .05em;
1422}
1423.audio-sheet-album:empty { display: none; }
1424/* Progress + time */
1425.audio-sheet-progress {
1426 display: grid;
1427 grid-template-columns: auto 1fr auto;
1428 gap: .6rem;
1429 align-items: center;
1430 padding: 0 .5rem;
1431}
1432.audio-sheet-progress .audio-seek { width: 100%; }
1433.audio-sheet-progress .audio-time {
1434 font-size: .78rem;
1435 opacity: .55;
1436}
1437/* Grote controls */
1438.audio-sheet-controls {
1439 display: flex;
1440 align-items: center;
1441 justify-content: center;
1442 gap: 1.75rem;
1443}
1444.audio-sheet-btn {
1445 width: 48px;
1446 height: 48px;
1447 padding: 0;
1448}
1449.audio-sheet-btn svg { width: 28px; height: 28px; }
1450.audio-sheet-play {
1451 width: 72px;
1452 height: 72px;
1453 border-radius: 50%;
1454 background: var(--accent, #c2410c);
1455 color: var(--paper, #fff);
1456 border: none;
1457 cursor: pointer;
1458 display: inline-flex;
1459 align-items: center;
1460 justify-content: center;
1461 transition: transform .1s;
1462}
1463.audio-sheet-play:hover { transform: scale(1.05); }
1464.audio-sheet-play:active { transform: scale(.95); }
1465.audio-sheet-play svg { width: 30px; height: 30px; }
1466.audio-sheet-play .icon-pause { display: none; }
1467/* v9.2.1 — sheet staat nu als sibling van .audio-player buiten de balk,
1468 dus ancestor-selector .audio-player.is-playing werkt niet meer voor de
1469 sheet. JS zet is-playing ook rechtstreeks op sheet.play (regel 551 app.js). */
1470.audio-sheet-play.is-playing .icon-play { display: none; }
1471.audio-sheet-play.is-playing .icon-pause { display: block; }
1472/* v9.2.1 — fallback: als sheet buiten alle ancestors zit, tag body */
1473body.audio-is-playing .audio-sheet-play .icon-play { display: none; }
1474body.audio-is-playing .audio-sheet-play .icon-pause { display: block; }
1475
1476/* v9.3 — Loading state: roterende spiraal (het roboburr logo).
1477 Button-achtergrond wordt transparant, play/pause svgs verbergen, en de
1478 spiraal verschijnt als roterende background via ::after pseudo-element.
1479 Cool-effect: zachte hue-drift geeft de kleur een levend gevoel. */
1480.audio-player.is-loading .audio-btn-play,
1481.audio-player.is-loading .audio-sheet-play,
1482body.audio-is-loading .audio-sheet-play,
1483.pat-row.is-loading {
1484 pointer-events: none;
1485}
1486.audio-player.is-loading .audio-btn-play,
1487.audio-player.is-loading .audio-sheet-play,
1488body.audio-is-loading .audio-sheet-play {
1489 background: transparent;
1490 box-shadow: none;
1491}
1492
1493/* v9.3 — Play/pause-icons in de player-knoppen faden smooth uit/in tijdens
1494 loading. Pseudo-spiraal faded tegelijkertijd in (geen instant pop). */
1495.audio-btn-play > svg,
1496.audio-sheet-play > svg {
1497 transition: opacity .35s cubic-bezier(.4, 0, .2, 1),
1498 transform .35s cubic-bezier(.4, 0, .2, 1);
1499}
1500.audio-player.is-loading .audio-btn-play > svg,
1501.audio-player.is-loading .audio-sheet-play > svg,
1502body.audio-is-loading .audio-sheet-play > svg {
1503 opacity: 0;
1504 transform: scale(.7);
1505}
1506.pat-row.is-loading .pat-play-icon > svg,
1507.pat-row.is-loading .pat-num,
1508.pat-row.is-loading .pat-cover {
1509 opacity: 0;
1510}
1511
1512/* v9.3 — Spiraal als pseudo-element, ALTIJD aanwezig met opacity 0 default.
1513 Bij is-loading faden 'ie smooth in (opacity + scale-bounce), bij klaar
1514 faden 'ie weer uit. Pure accent-kleur, geen hue-drift. */
1515.audio-player .audio-btn-play,
1516.audio-player .audio-sheet-play,
1517.pat-row .pat-play-icon {
1518 position: relative;
1519}
1520.audio-btn-play::after,
1521.audio-sheet-play::after {
1522 content: "";
1523 position: absolute;
1524 inset: 0;
1525 background-color: var(--accent, #c2410c);
1526 -webkit-mask: url('/assets/spinner.svg') center/contain no-repeat;
1527 mask: url('/assets/spinner.svg') center/contain no-repeat;
1528 opacity: 0;
1529 transform: scale(.6);
1530 transition: opacity .4s cubic-bezier(.4, 0, .2, 1),
1531 transform .4s cubic-bezier(.34, 1.56, .64, 1);
1532 pointer-events: none;
1533 animation: pcms-spiral-spin 1.2s linear infinite paused;
1534 will-change: opacity, transform;
1535}
1536.audio-player.is-loading .audio-btn-play::after,
1537.audio-player.is-loading .audio-sheet-play::after,
1538body.audio-is-loading .audio-sheet-play::after {
1539 opacity: 1;
1540 transform: scale(1);
1541 animation-play-state: running;
1542}
1543/* Pat-row keeps its existing ::before spinner from earlier change.
1544 Voor backward-compat als oude HTML nog .pat-play-icon::after spinner had */
1545.pat-row.is-loading .pat-play-icon::after {
1546 content: "";
1547 position: absolute;
1548 inset: 0;
1549 background-color: var(--accent, #c2410c);
1550 -webkit-mask: url('/assets/spinner.svg') center/contain no-repeat;
1551 mask: url('/assets/spinner.svg') center/contain no-repeat;
1552 opacity: 1;
1553 animation: pcms-spiral-spin 1.2s linear infinite;
1554 pointer-events: none;
1555}
1556@keyframes pcms-spiral-spin {
1557 to { transform: scale(1) rotate(-360deg); }
1558}
1559/* Queue list */
1560.audio-sheet-queue {
1561 margin-top: .5rem;
1562 padding-top: 1rem;
1563 border-top: 1px solid var(--rule);
1564}
1565.audio-sheet-queue-label {
1566 font-size: .75rem;
1567 text-transform: uppercase;
1568 letter-spacing: .08em;
1569 opacity: .5;
1570 font-weight: 600;
1571 margin-bottom: .5rem;
1572 padding: 0 .5rem;
1573}
1574.audio-sheet-queue-list {
1575 list-style: none;
1576 padding: 0;
1577 margin: 0;
1578 display: flex;
1579 flex-direction: column;
1580 gap: 2px;
1581}
1582.audio-sheet-queue-item {
1583 display: flex;
1584 align-items: center;
1585 gap: .75rem;
1586 padding: .5rem .6rem;
1587 border-radius: 6px;
1588 cursor: pointer;
1589 transition: background .15s;
1590 background: none;
1591 border: none;
1592 width: 100%;
1593 color: inherit;
1594 font: inherit;
1595 text-align: left;
1596}
1597.audio-sheet-queue-item:hover {
1598 background: color-mix(in srgb, var(--ink, #000) 6%, transparent);
1599}
1600.audio-sheet-queue-item.is-current {
1601 background: color-mix(in srgb, var(--accent, #c2410c) 14%, transparent);
1602 color: var(--accent, #c2410c);
1603}
1604.audio-sheet-queue-cover {
1605 width: 36px;
1606 height: 36px;
1607 border-radius: 4px;
1608 background-size: cover;
1609 background-position: center;
1610 background-color: var(--rule);
1611 flex-shrink: 0;
1612}
1613.audio-sheet-queue-meta {
1614 flex: 1;
1615 min-width: 0;
1616 display: flex;
1617 flex-direction: column;
1618}
1619.audio-sheet-queue-title {
1620 font-size: .9rem;
1621 font-weight: 500;
1622 overflow: hidden;
1623 text-overflow: ellipsis;
1624 white-space: nowrap;
1625}
1626.audio-sheet-queue-artist {
1627 font-size: .75rem;
1628 opacity: .55;
1629 overflow: hidden;
1630 text-overflow: ellipsis;
1631 white-space: nowrap;
1632}
1633.audio-sheet-queue-duration {
1634 font-family: ui-monospace, monospace;
1635 font-size: .72rem;
1636 opacity: .5;
1637 flex-shrink: 0;
1638}
1639
1640/* Desktop: sheet is max 480px wide and centered for bigger screens */
1641@media (min-width: 720px) {
1642 .audio-sheet-panel {
1643 left: 50%;
1644 right: auto;
1645 width: 480px;
1646 transform: translate(-50%, 100%);
1647 border-top-left-radius: 20px;
1648 border-top-right-radius: 20px;
1649 }
1650 .audio-sheet.is-open .audio-sheet-panel {
1651 transform: translate(-50%, 0);
1652 }
1653}
1654
1655/* v9.2.1 — Mobiel: sheet is fullscreen, alleen te sluiten via handle-knop bovenin.
1656 Geen rounded corners, volledige viewport, safe-area voor notches/status bar. */
1657@media (max-width: 719.98px) {
1658 .audio-sheet-panel {
1659 inset: 0;
1660 max-height: none;
1661 border-top-left-radius: 0;
1662 border-top-right-radius: 0;
1663 box-shadow: none;
1664 padding-top: calc(.75rem + var(--ios-safe-top, 0px));
1665 padding-bottom: calc(2rem + env(safe-area-inset-bottom, 0px));
1666 }
1667 /* v9.3 — Backdrop blijft visible op mobile zodat drag-gesture de blur
1668 laat doorschemeren naar helder. */
1669}
1670
1671/* ============================================================
1672 Mobile masthead + pagination
1673 ============================================================ */
1674@media (max-width: 600px) {
1675 .masthead-inner { gap: .35rem; }
1676 .site-title { font-size: 1.2rem; }
1677 .site-subtitle { display: none; }
1678 .top-nav { gap: .1rem; }
1679 .nav-label { display: none; }
1680 .nav-btn, .nav-link {
1681 padding: .4rem .45rem;
1682 min-width: 38px;
1683 justify-content: center;
1684 }
1685 .pagination { flex-direction: column; gap: .5rem; }
1686 .pagination-item { width: 100%; }
1687}
1688
1689/* Taal-keuze in de header-nav (NL/EN/DE) — eigen gestylede dropdown. */
1690.lang-menu { position: relative; }
1691.lang-menu > summary {
1692 list-style: none; cursor: pointer;
1693 display: inline-flex; align-items: center; gap: .3rem;
1694 padding: .35rem .55rem; border-radius: 999px;
1695 border: 1px solid var(--rule); background: transparent; color: var(--ink);
1696}
1697.lang-menu > summary::-webkit-details-marker { display: none; }
1698.lang-menu > summary:hover { border-color: var(--accent); }
1699.lang-toggle .lang-code { font-size: .8rem; font-weight: 700; letter-spacing: .02em; }
1700.lang-toggle .icon { width: 16px; height: 16px; opacity: .8; }
1701.lang-caret { width: 12px; height: 12px; opacity: .7; transition: transform .15s; }
1702.lang-menu[open] .lang-caret { transform: rotate(180deg); }
1703.lang-dropdown {
1704 position: absolute; top: calc(100% + 8px); right: 0;
1705 min-width: 170px; z-index: 60;
1706 background: var(--paper); border: 1px solid var(--rule);
1707 border-radius: 12px; box-shadow: 0 10px 30px rgba(0,0,0,.22);
1708 padding: .35rem; display: flex; flex-direction: column;
1709}
1710.lang-item {
1711 display: flex; align-items: center; gap: .6rem;
1712 padding: .5rem .65rem; border-radius: 8px;
1713 color: var(--ink); text-decoration: none; font-size: .9rem;
1714}
1715.lang-item:hover { background: var(--paper-2); }
1716.lang-item.is-active { color: var(--accent); font-weight: 600; }
1717.lang-item-code {
1718 font-size: .7rem; font-weight: 700; opacity: .6;
1719 min-width: 1.6em;
1720}
1721@media (max-width: 400px) {
1722 .masthead { padding: calc(.5rem + var(--ios-safe-top, 0px)) 0 .5rem; }
1723 .masthead-inner { gap: .25rem; }
1724 .site-title { font-size: 1.05rem; }
1725 .nav-btn, .nav-link {
1726 padding: .35rem .3rem;
1727 min-width: 34px;
1728 }
1729 .nav-btn .icon, .nav-link .icon { width: 1rem; height: 1rem; }
1730 /* PWA-install knop verbergen op klein scherm — kan ook via menu */
1731 .nav-install-btn { display: none !important; }
1732}
1733@media (max-width: 340px) {
1734 .site-title { font-size: .95rem; }
1735 .nav-btn, .nav-link { padding: .3rem .25rem; min-width: 30px; }
1736 /* Theme-toggle verbergen op ultra-klein — kan via user-menu */
1737 [data-pcms-theme-toggle] { display: none; }
1738}
1739
1740.post-date-ago {
1741 margin-left: .5em;
1742 opacity: .6;
1743 font-size: .9em;
1744 font-style: italic;
1745 text-transform: none;
1746 letter-spacing: 0;
1747}
1748
1749/* HTMX loading indicator — subtle progress-bar aan de top van de content */
1750.pcms-loading {
1751 position: fixed;
1752 top: 0; left: 0;
1753 height: 2px;
1754 width: 0%;
1755 background: var(--accent, #c2410c);
1756 z-index: 9999;
1757 transition: width .3s ease, opacity .2s;
1758 opacity: 0;
1759 pointer-events: none;
1760}
1761.pcms-loading.htmx-request {
1762 opacity: 1;
1763 width: 80%;
1764 transition: width 6s cubic-bezier(.1,.9,.2,1), opacity .2s;
1765}
1766/* subtile fade wanneer content gewisseld wordt */
1767#pcms-main.htmx-swapping {
1768 opacity: .5;
1769 transition: opacity .15s;
1770}
1771
1772/* Masthead brand group (site-title + optional tagline) */
1773.masthead-brand { display: flex; flex-direction: column; gap: 2px; }
1774.site-subtitle {
1775 font-family: var(--font-ui, inherit);
1776 font-size: .75rem;
1777 color: var(--ink-muted, rgba(0,0,0,.55));
1778 letter-spacing: 0;
1779 line-height: 1.3;
1780}
1781
1782/* ============================================================
1783 v7.3 — TAGS, TYPE, ARCHIEF, ZOEK, RELATED, SPECIAL VIEWS
1784 ============================================================ */
1785
1786/* Post-meta row — datum + type-chip + tags samen onder de titel */
1787.post-meta {
1788 display: flex;
1789 flex-wrap: wrap;
1790 align-items: center;
1791 gap: .5rem .85rem;
1792 margin-top: .5rem;
1793}
1794.post-meta .post-date { margin: 0; }
1795
1796/* Type-chip (groter, als een label) */
1797.post-type-chip {
1798 display: inline-flex;
1799 align-items: center;
1800 padding: .2rem .6rem;
1801 background: color-mix(in srgb, var(--accent) 10%, transparent);
1802 color: var(--accent);
1803 border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent);
1804 border-radius: 999px;
1805 font-family: var(--font-ui);
1806 font-size: .72rem;
1807 font-weight: 600;
1808 text-decoration: none;
1809 letter-spacing: .04em;
1810 text-transform: uppercase;
1811 transition: background .15s;
1812}
1813.post-type-chip:hover { background: color-mix(in srgb, var(--accent) 20%, transparent); }
1814
1815/* Tag-chips — klein, subtiel, gelinkt */
1816.post-tags, .post-list-tags {
1817 display: inline-flex;
1818 flex-wrap: wrap;
1819 gap: .3rem;
1820}
1821.tag-chip {
1822 display: inline-block;
1823 padding: .15rem .55rem;
1824 background: color-mix(in srgb, var(--ink) 5%, transparent);
1825 color: var(--ink-muted);
1826 border-radius: 999px;
1827 font-family: var(--font-ui);
1828 font-size: .72rem;
1829 font-weight: 500;
1830 text-decoration: none;
1831 transition: background .15s, color .15s;
1832}
1833.tag-chip:hover {
1834 background: color-mix(in srgb, var(--accent) 12%, transparent);
1835 color: var(--accent);
1836}
1837
1838/* ============================================================
1839 SPECIAL PAGES (archief, tag, type, zoek)
1840 ============================================================ */
1841.special-page .post-header { margin-bottom: 2rem; }
1842.special-eyebrow {
1843 font-size: .72rem;
1844 color: var(--ink-muted);
1845 text-transform: uppercase;
1846 letter-spacing: .12em;
1847 margin: 0 0 .25rem;
1848}
1849
1850/* Archief: jaar-overzicht */
1851.archive-years {
1852 display: flex;
1853 flex-direction: column;
1854 gap: 2rem;
1855}
1856.archive-year h2 {
1857 font-family: var(--font-display);
1858 font-size: 1.75rem;
1859 margin: 0 0 .75rem;
1860}
1861.archive-year h2 a {
1862 color: var(--ink);
1863 text-decoration: none;
1864}
1865.archive-year h2 a:hover { color: var(--accent); }
1866.archive-year h2 .admin-muted { font-size: .9rem; font-weight: normal; color: var(--ink-muted); }
1867.archive-months {
1868 list-style: none;
1869 padding: 0; margin: 0;
1870 display: grid;
1871 grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
1872 gap: .5rem;
1873}
1874.archive-months li {
1875 display: flex;
1876 align-items: center;
1877 gap: .4rem;
1878 padding: .55rem .75rem;
1879 background: color-mix(in srgb, var(--ink) 3%, transparent);
1880 border-radius: var(--radius);
1881 transition: background .15s;
1882}
1883.archive-months li:hover { background: color-mix(in srgb, var(--accent) 8%, transparent); }
1884.archive-months a {
1885 color: var(--ink);
1886 text-decoration: none;
1887 font-weight: 500;
1888 font-size: .95rem;
1889}
1890.archive-months .admin-muted { font-size: .75rem; color: var(--ink-muted); margin-left: auto; }
1891
1892/* Archief: jaar drill-down */
1893.archive-month-list {
1894 display: flex;
1895 flex-direction: column;
1896 gap: 2rem;
1897}
1898.archive-month h2 {
1899 font-family: var(--font-display);
1900 font-size: 1.35rem;
1901 margin: 0 0 .5rem;
1902 padding-bottom: .35rem;
1903 border-bottom: 1px solid var(--rule);
1904}
1905.archive-month h2 a {
1906 color: var(--ink);
1907 text-decoration: none;
1908}
1909.archive-month h2 a:hover { color: var(--accent); }
1910
1911/* Compact post-list (gebruikt in archief drill-down per maand) */
1912.post-compact-list {
1913 list-style: none;
1914 padding: 0; margin: 0;
1915 display: flex;
1916 flex-direction: column;
1917}
1918.post-compact-list li {
1919 border-bottom: 1px solid var(--rule);
1920}
1921.post-compact-list li:last-child { border-bottom: none; }
1922.post-compact-list a {
1923 display: grid;
1924 grid-template-columns: 3em 1fr;
1925 gap: .75rem;
1926 padding: .6rem .2rem;
1927 text-decoration: none;
1928 color: var(--ink);
1929 transition: background .12s;
1930 border-radius: 4px;
1931}
1932.post-compact-list a:hover {
1933 background: color-mix(in srgb, var(--accent) 6%, transparent);
1934}
1935.post-compact-date {
1936 color: var(--ink-muted);
1937 font-size: .8rem;
1938 align-self: center;
1939}
1940.post-compact-title { font-weight: 500; font-size: 1rem; align-self: center; }
1941.post-compact-list.large a { grid-template-columns: 4em 1fr; padding: .8rem .3rem; }
1942.post-compact-list.large .post-compact-title { font-family: var(--font-display); font-size: 1.15rem; }
1943.post-compact-excerpt {
1944 grid-column: 2;
1945 color: var(--ink-muted);
1946 font-size: .88rem;
1947 line-height: 1.5;
1948}
1949
1950/* Post-list (gebruikt in tag / type / zoek pagina's) */
1951.post-list {
1952 list-style: none;
1953 padding: 0; margin: 0;
1954 display: flex;
1955 flex-direction: column;
1956 gap: 1.5rem;
1957}
1958.post-list-item {
1959 display: grid;
1960 grid-template-columns: 120px 1fr;
1961 gap: 1.25rem;
1962 padding-bottom: 1.5rem;
1963 border-bottom: 1px solid var(--rule);
1964}
1965.post-list-item:last-child { border-bottom: none; }
1966.post-list-item:has(> .post-list-cover + .post-list-body) { grid-template-columns: 120px 1fr; }
1967.post-list-item:not(:has(.post-list-cover)) { grid-template-columns: 1fr; }
1968.post-list-cover {
1969 display: block;
1970 aspect-ratio: 1;
1971 overflow: hidden;
1972 border-radius: var(--radius);
1973 /* Accent-gradient placeholder while the cover image loads (image fades in over it). */
1974 background-image: linear-gradient(135deg,
1975 color-mix(in srgb, var(--accent, #888) 22%, var(--paper-2, var(--paper))) 0%,
1976 color-mix(in srgb, var(--accent, #888) 6%, var(--paper-2, var(--paper))) 100%);
1977}
1978.post-list-cover img, .post-list-cover video {
1979 width: 100%; height: 100%;
1980 object-fit: cover; /* fill the square, keep aspect, crop the overflow, centered */
1981 object-position: center;
1982 display: block;
1983 background-color: #fff; /* transparent logos sit on white once loaded */
1984 transition: opacity .4s ease;
1985}
1986.post-list-cover img.is-loading { opacity: 0; }
1987.post-list-body { display: flex; flex-direction: column; gap: .35rem; }
1988.post-list-meta {
1989 color: var(--ink-muted);
1990 font-size: .75rem;
1991 display: flex; gap: .35rem; align-items: center;
1992}
1993.post-list-title {
1994 font-family: var(--font-display);
1995 font-size: 1.3rem;
1996 font-weight: 450;
1997 margin: 0;
1998 line-height: 1.2;
1999}
2000.post-list-title a {
2001 color: var(--ink);
2002 text-decoration: none;
2003}
2004.post-list-title a:hover { color: var(--accent); }
2005.post-list-excerpt {
2006 color: var(--ink-muted);
2007 font-size: .95rem;
2008 margin: 0;
2009 line-height: 1.5;
2010}
2011
2012/* Zoek-formulier binnen special view */
2013.search-form {
2014 display: flex;
2015 gap: .5rem;
2016 margin-bottom: 2rem;
2017}
2018.search-form input[type=search] {
2019 flex: 1;
2020 padding: .75rem 1rem;
2021 background: var(--paper-2);
2022 border: 1px solid var(--rule);
2023 border-radius: var(--radius);
2024 font: inherit;
2025 color: var(--ink);
2026}
2027.search-form input[type=search]:focus {
2028 outline: none;
2029 border-color: var(--accent);
2030 box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 20%, transparent);
2031}
2032
2033/* ============================================================
2034 SEARCH OVERLAY (masthead → full-screen zoekbalk)
2035 ============================================================ */
2036.search-overlay {
2037 position: fixed;
2038 inset: 0;
2039 background: color-mix(in srgb, var(--ink) 50%, transparent);
2040 z-index: 1500;
2041 display: flex;
2042 justify-content: center;
2043 align-items: flex-start;
2044 padding-top: 10vh;
2045 backdrop-filter: blur(6px);
2046 -webkit-backdrop-filter: blur(6px);
2047}
2048.search-overlay[hidden] { display: none; }
2049.search-overlay-form {
2050 width: min(90vw, 600px);
2051 background: var(--paper);
2052 border-radius: calc(var(--radius) * 1.5);
2053 padding: .75rem 1rem;
2054 display: flex;
2055 align-items: center;
2056 gap: .6rem;
2057 box-shadow: 0 20px 60px rgba(0,0,0,.3);
2058 border: 1px solid var(--rule);
2059}
2060.search-overlay-form .icon {
2061 width: 1.2rem; height: 1.2rem;
2062 color: var(--ink-muted);
2063 flex-shrink: 0;
2064}
2065.search-overlay-form input[type=search] {
2066 flex: 1;
2067 background: transparent;
2068 border: none;
2069 font-family: var(--font-body);
2070 font-size: 1.1rem;
2071 color: var(--ink);
2072 padding: .5rem 0;
2073}
2074.search-overlay-form input[type=search]:focus { outline: none; }
2075.search-overlay-form .nav-btn {
2076 background: transparent;
2077 border: none;
2078 color: var(--ink-muted);
2079 cursor: pointer;
2080 font-size: 1.25rem;
2081 line-height: 1;
2082 padding: .3rem .5rem;
2083}
2084.search-overlay-form .nav-btn:hover { color: var(--ink); }
2085body.search-open { overflow: hidden; }
2086
2087/* ============================================================
2088 RELATED POSTS (onder elke post-view)
2089 ============================================================ */
2090.related-posts {
2091 margin-top: 2.5rem;
2092 padding-top: 2rem;
2093 border-top: 1px solid var(--rule);
2094}
2095.related-title {
2096 font-family: var(--font-mono);
2097 font-size: .7rem;
2098 color: var(--ink-muted);
2099 text-transform: uppercase;
2100 letter-spacing: .12em;
2101 margin: 0 0 1rem;
2102}
2103.related-grid {
2104 list-style: none;
2105 padding: 0; margin: 0;
2106 display: grid;
2107 grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
2108 gap: 1rem;
2109}
2110.related-grid a {
2111 display: flex;
2112 flex-direction: column;
2113 gap: .5rem;
2114 text-decoration: none;
2115 color: var(--ink);
2116 border: 1px solid var(--rule);
2117 border-radius: var(--radius);
2118 overflow: hidden;
2119 transition: border-color .15s, transform .15s;
2120 height: 100%;
2121}
2122.related-grid a:hover {
2123 border-color: color-mix(in srgb, var(--accent) 50%, var(--rule));
2124 transform: translateY(-2px);
2125}
2126.related-cover {
2127 display: block;
2128 aspect-ratio: 16/10;
2129 background-size: cover;
2130 background-position: center;
2131 background-color: var(--paper-2);
2132}
2133
2134/* v9.4 — Wanneer related-cover ook .grid-tile-gradient class heeft (lege cover
2135 fallback), erft 'ie automatisch de hue/gradient/title styling van grid-tiles.
2136 Geen aparte related-cover-gradient meer nodig. */
2137.related-body {
2138 display: flex;
2139 flex-direction: column;
2140 gap: .25rem;
2141 padding: .6rem .75rem .9rem;
2142}
2143.related-meta { color: var(--ink-muted); font-size: .7rem; }
2144.related-name {
2145 font-family: var(--font-display);
2146 font-weight: 450;
2147 font-size: 1rem;
2148 line-height: 1.25;
2149}
2150
2151/* ============================================================
2152 MOBILE TWEAKS voor v7.3
2153 ============================================================ */
2154@media (max-width: 600px) {
2155 .post-list-item { grid-template-columns: 1fr; }
2156 .post-list-cover { aspect-ratio: 16/9; }
2157 .archive-months { grid-template-columns: repeat(2, 1fr); }
2158 .related-grid { grid-template-columns: 1fr; }
2159 .search-overlay { padding-top: 4vh; }
2160}
2161
2162/* ============================================================
2163 v7.4 — PROFILE HEADER + VIEW SWITCHER + GRID + POST-TYPE LAYOUTS
2164 MOBILE-FIRST — belangrijkste eis
2165 ============================================================ */
2166
2167/* -------- PROFILE HEADER (Optie C: full op home, compact op post/special) -------- */
2168
2169.profile-header {
2170 background: var(--paper-2, var(--paper));
2171 border-bottom: 1px solid var(--rule);
2172 transition: padding .25s ease, background .2s;
2173}
2174/* Mobiel default = full-mode padding */
2175.profile-header { padding: 1.25rem 0; }
2176.profile-header-inner {
2177 display: flex;
2178 gap: .9rem;
2179 align-items: flex-start;
2180}
2181
2182.profile-photo {
2183 flex-shrink: 0;
2184 width: 80px;
2185 height: 80px;
2186 border-radius: 50%;
2187 overflow: hidden;
2188 display: block;
2189 background: var(--paper);
2190 border: 2px solid var(--rule);
2191 transition: width .25s ease, height .25s ease, border-color .2s;
2192 text-decoration: none;
2193}
2194.profile-photo:hover { border-color: var(--accent); }
2195.profile-photo img {
2196 width: 100%; height: 100%;
2197 object-fit: cover;
2198 display: block;
2199}
2200.profile-photo-fallback {
2201 display: flex;
2202 align-items: center;
2203 justify-content: center;
2204 width: 100%; height: 100%;
2205 background: var(--accent);
2206 color: var(--paper);
2207 font-family: var(--font-display);
2208 font-weight: 700;
2209 font-size: 2.2rem;
2210 text-transform: uppercase;
2211 line-height: 1;
2212 transition: font-size .25s ease;
2213}
2214
2215.profile-info {
2216 flex: 1;
2217 min-width: 0;
2218 display: flex;
2219 flex-direction: column;
2220 gap: .3rem;
2221}
2222.profile-name {
2223 margin: 0;
2224 font-family: var(--font-display);
2225 font-size: 1.2rem;
2226 font-weight: 500;
2227 line-height: 1.15;
2228 transition: font-size .25s ease;
2229}
2230.profile-name a {
2231 color: var(--ink);
2232 text-decoration: none;
2233}
2234.profile-name a:hover { color: var(--accent); }
2235.profile-bio {
2236 margin: 0;
2237 color: var(--ink-muted);
2238 font-size: .92rem;
2239 line-height: 1.45;
2240 max-height: 200px;
2241 overflow: hidden;
2242 transition: max-height .25s ease, margin .25s ease, opacity .2s;
2243}
2244.profile-links {
2245 list-style: none;
2246 padding: 0;
2247 margin: .15rem 0 0;
2248 display: flex;
2249 flex-wrap: wrap;
2250 gap: .4rem;
2251 max-height: 50px;
2252 overflow: hidden;
2253 transition: max-height .25s ease, margin .25s ease, opacity .2s;
2254}
2255.profile-links li { margin: 0; }
2256.profile-links a,
2257.profile-links .profile-fedi-link {
2258 display: inline-flex;
2259 align-items: center;
2260 justify-content: center;
2261 width: 40px;
2262 height: 40px;
2263 border-radius: 50%;
2264 background: color-mix(in srgb, var(--ink) 5%, transparent);
2265 color: var(--ink-muted);
2266 text-decoration: none;
2267 transition: background .15s, color .15s;
2268}
2269.profile-links a:hover,
2270.profile-links .profile-fedi-link:hover {
2271 background: color-mix(in srgb, var(--accent) 15%, transparent);
2272 color: var(--accent);
2273}
2274.profile-links .icon { width: 1.1rem; height: 1.1rem; }
2275
2276/* -------- COMPACT MODE: op post + special pages -------- */
2277
2278.on-post .profile-header,
2279.on-special .profile-header {
2280 padding: .5rem 0;
2281}
2282.on-post .profile-photo,
2283.on-special .profile-photo {
2284 width: 36px;
2285 height: 36px;
2286 border-width: 1px;
2287}
2288.on-post .profile-photo-fallback,
2289.on-special .profile-photo-fallback {
2290 font-size: 1rem;
2291}
2292.on-post .profile-name,
2293.on-special .profile-name {
2294 font-size: 1rem;
2295 align-self: center;
2296}
2297.on-post .profile-bio,
2298.on-special .profile-bio,
2299.on-post .profile-links,
2300.on-special .profile-links {
2301 display: none;
2302}
2303.on-post .profile-header-inner,
2304.on-special .profile-header-inner {
2305 align-items: center;
2306 justify-content: flex-start;
2307 gap: .6rem;
2308}
2309.on-post .profile-info,
2310.on-special .profile-info {
2311 flex: 0 1 auto;
2312 min-width: 0;
2313}
2314.on-post .profile-name,
2315.on-special .profile-name {
2316 text-align: left;
2317}
2318
2319/* -------- DESKTOP: meer ruimte, grotere foto -------- */
2320@media (min-width: 768px) {
2321 .profile-header { padding: 2rem 0; }
2322 .profile-photo { width: 120px; height: 120px; }
2323 .profile-photo-fallback { font-size: 3.2rem; }
2324 .profile-name { font-size: 1.5rem; }
2325 .profile-bio { font-size: 1rem; }
2326 .profile-header-inner { gap: 1.5rem; }
2327 .on-post .profile-header,
2328 .on-special .profile-header { padding: .6rem 0; }
2329 .on-post .profile-photo,
2330 .on-special .profile-photo { width: 42px; height: 42px; }
2331 /* Compact mode: gap blijft klein, ook op desktop */
2332 .on-post .profile-header-inner,
2333 .on-special .profile-header-inner { gap: .75rem; }
2334 .on-post .profile-name,
2335 .on-special .profile-name { font-size: 1.1rem; }
2336}
2337
2338/* -------- VIEW SWITCHER -------- */
2339.view-switcher-wrap {
2340 border-bottom: 1px solid var(--rule);
2341 background: var(--paper);
2342 /* Bottom margin gives breathing room between the switcher bar and the
2343 first post. margin-top staat in shared-styles.ejs (de winnende inline
2344 <style>) — symmetrisch op 1.5rem. */
2345 margin-bottom: 1.5rem;
2346}
2347.view-switcher {
2348 display: flex;
2349 justify-content: center;
2350 gap: .35rem;
2351 /* Slimmer bar — was .6rem, now .35rem so the bar reads as a divider
2352 rather than a row of weight equal to the header. */
2353 padding: .35rem 0;
2354}
2355.view-switch-btn {
2356 display: inline-flex;
2357 align-items: center;
2358 gap: .4rem;
2359 padding: .35rem .85rem; /* was .55rem 1rem */
2360 min-height: 32px; /* was 44px */
2361 background: transparent;
2362 border: 1px solid var(--rule);
2363 border-radius: 999px;
2364 color: var(--ink-muted);
2365 font-family: var(--font-ui);
2366 font-size: .82rem; /* was .85rem */
2367 cursor: pointer;
2368 transition: all .15s;
2369}
2370.view-switch-btn:hover {
2371 color: var(--ink);
2372 border-color: var(--ink-muted);
2373}
2374/* Uitgeschakeld (Lezen in de cirkel) wint van :hover -- anders licht een knop
2375 op die je niet kunt indrukken, en dat is precies de verkeerde belofte. */
2376.view-switch-btn[disabled],
2377.view-switch-btn[disabled]:hover {
2378 opacity: .38;
2379 cursor: not-allowed;
2380 color: var(--ink-muted);
2381 border-color: var(--rule);
2382}
2383/* Actieve state: puur afgeleid van body[data-feed-view]. Geen .is-active class meer.
2384 Niet op de Archive-pagina: daar is geen "huidige" timeline/grid-keuze, dus beide
2385 knoppen blijven neutraal (grijs). */
2386/* Actieve Tijdlijn/Grid-state wordt nu gestuurd via [aria-selected="true"] (gezet
2387 door syncAria, die óók op htmx:afterSettle draait) i.p.v. body[data-feed-view].
2388 Reden: body-class/attribuut-CSS pakte niet betrouwbaar na een htmx-OOB-swap;
2389 een element-attribuut wel. De witte active-regel staat in shared-styles. */
2390.view-switch-btn .icon { width: 1rem; height: 1rem; }
2391
2392/* -------- FEED TOGGLE VIA BODY --------
2393 Grid-modus werkt op de feed (home, cirkel). Het ARCHIEF negeert de grid-keuze
2394 bewust: dat is altijd de chronologische jaar/maand-lijst (de switcher is daar
2395 grijs en springt bij klik terug naar de feed). Post-pagina's tonen de
2396 feed-timeline article sowieso altijd. Alle andere body-classes negeren
2397 data-feed-view en houden timeline visible. */
2398body.on-home[data-feed-view="grid"] .feed-timeline,
2399body.on-home[data-feed-view="grid"] .pagination,
2400body.on-home[data-feed-view="grid"] .related-posts,
2401body.on-home[data-feed-view="grid"] .article-footer,
2402body.on-cirkel[data-feed-view="grid"] .feed-timeline {
2403 display: none !important;
2404}
2405/* Grid-sectie alleen zichtbaar op de feed in grid-mode (NIET op archief) */
2406.feed-grid { display: none; }
2407body.on-home[data-feed-view="grid"] .feed-grid,
2408body.on-cirkel[data-feed-view="grid"] .feed-grid { display: block; }
2409
2410/* -------- LEESWEERGAVE (data-feed-view="reader") --------
2411 Dezelfde berichten als de tijdlijn, maar heel: één per scherm, grenzen door
2412 scroll-snapping. GEEN eigen route en geen eigen shell -- de balken blijven
2413 staan, want je bent nog op de feed en moet terug kunnen schakelen.
2414 Pagina's zonder .feed-reader (cirkel, archief, post) negeren de keuze en
2415 houden hun tijdlijn: er is hieronder simpelweg geen regel die die daar
2416 verbergt. Zo is Lezen nooit een leeg scherm. */
2417.feed-reader { display: none; }
2418body.on-home[data-feed-view="reader"] .feed-reader { display: block; }
2419/* :has(.feed-reader) is hier de LEGE STAAT, niet een truc. Zonder berichten
2420 rendert de leessectie niet, en dan mag de tijdlijn niet verborgen worden --
2421 want dáár staat "nog niets geschreven" met de knop om te beginnen. Zonder deze
2422 voorwaarde is Lezen op een verse site een wit scherm. Hetzelfde geldt voor
2423 feeds die (nog) geen leessectie hebben. */
2424body.on-home[data-feed-view="reader"]:has(.feed-reader) .feed-timeline,
2425body.on-home[data-feed-view="reader"]:has(.feed-reader) .feed-grid,
2426body.on-home[data-feed-view="reader"]:has(.feed-reader) .pagination,
2427body.on-home[data-feed-view="reader"]:has(.feed-reader) .related-posts,
2428body.on-home[data-feed-view="reader"]:has(.feed-reader) .article-footer {
2429 display: none !important;
2430}
2431
2432/* Snappen doet de SCROLLCONTAINER, en dat is het document -- niet .read-stream,
2433 die heeft overflow: visible en scrollt zelf niet. Proximity en geen mandatory:
2434 in een bericht dat langer is dan het scherm moet je rustig door kunnen lezen. */
2435html:has(body.on-home[data-feed-view="reader"]) { scroll-snap-type: y proximity; }
2436/* En de browser niet óók laten compenseren als Load more er berichten bij zet:
2437 Chrome en Firefox schuiven bij invoegen zelf mee (scroll anchoring), en dat
2438 vecht met het snappen. */
2439html:has(body.on-home[data-feed-view="reader"]),
2440.feed-reader .read-stream { overflow-anchor: none; }
2441
2442.feed-reader .read-post {
2443 scroll-snap-align: start;
2444 scroll-snap-stop: normal;
2445 min-height: 100svh;
2446 max-width: 46rem;
2447 margin: 0 auto;
2448 /* De onderrand loopt achter de vaste tabbalk door; deze padding houdt de
2449 TEKST erboven. */
2450 padding: 2rem 1.2rem 4rem;
2451 box-sizing: border-box;
2452}
2453/* Een lijn tussen twee berichten: zonder grens is een stroom een lange brij. */
2454.feed-reader .read-post + .read-post { border-top: 1px solid color-mix(in srgb, currentColor 12%, transparent); }
2455
2456/* De cover vult de leeskolom. Eigen regel, niet .post-cover hergebruikt: die
2457 heeft een marge van 2rem die hier tegen de scroll-snap aan duwt.
2458 De hoogtebegrenzing is er met opzet. Een paneel is min-height:100svh en snapt,
2459 dus een staande foto op volle breedte zou de titel en de eerste alinea onder
2460 de vouw duwen -- dan begint elk bericht met een plaat waar je langs moet
2461 scrollen om te zien wat het IS. */
2462.feed-reader .read-cover {
2463 margin: 0 0 1.2rem;
2464 border-radius: 10px;
2465 overflow: hidden;
2466}
2467.feed-reader .read-cover img,
2468.feed-reader .read-cover video {
2469 display: block;
2470 width: 100%;
2471 height: auto;
2472 max-height: 45svh;
2473 object-fit: cover;
2474}
2475
2476.feed-reader .read-head { padding-bottom: .5rem; }
2477.feed-reader .read-title { font-size: clamp(1.6rem, 4vw, 2.4rem); line-height: 1.15; margin: 0 0 .3rem; }
2478/* De titel is een link, maar mag er niet als een link uitzien: dit is een
2479 leesscherm, geen index. */
2480.feed-reader .read-title a { color: inherit; text-decoration: none; }
2481.feed-reader .read-title a:hover,
2482.feed-reader .read-title a:focus-visible { text-decoration: underline; }
2483.feed-reader .read-when { font-size: .85rem; opacity: .6; margin: 0; }
2484
2485.feed-reader .read-foot { margin-top: 2rem; }
2486.feed-reader .read-open {
2487 display: inline-block; font-size: .9rem; opacity: .75;
2488 text-decoration: none; border-bottom: 1px solid currentColor; padding-bottom: 1px;
2489}
2490.feed-reader .read-open:hover,
2491.feed-reader .read-open:focus-visible { opacity: 1; }
2492
2493@media (prefers-reduced-motion: reduce) {
2494 html:has(body.on-home[data-feed-view="reader"]) { scroll-snap-type: none; }
2495}
2496
2497/* -------- GRID VIEW TILES (Instagram-stijl) -------- */
2498.feed-grid {
2499 padding: 1rem 0 2rem;
2500}
2501.grid-tiles {
2502 display: grid;
2503 gap: 4px;
2504 grid-template-columns: repeat(2, 1fr);
2505}
2506.grid-tile {
2507 position: relative;
2508 display: block;
2509 aspect-ratio: 1;
2510 background-size: cover;
2511 background-position: center;
2512 background-color: var(--paper-2);
2513 overflow: hidden;
2514 text-decoration: none;
2515 color: var(--ink);
2516 transition: transform .2s;
2517 cursor: pointer;
2518 -webkit-tap-highlight-color: rgba(0,0,0,.1);
2519}
2520
2521/* Transparent covers (PNG logos etc.) sit on white so they don't blend into a dark
2522 theme. The white is on the IMG, so the tile's accent-gradient placeholder shows
2523 while the image is still loading. */
2524.post-cover img,
2525.post-list-cover img,
2526.grid-tile-img { background-color: #fff; }
2527/* Accent-gradient placeholder shown while the cover image loads (the image fades in
2528 over it), instead of a white flash on cover tiles. */
2529.grid-tile:not(.grid-tile-gradient) {
2530 background-image: linear-gradient(135deg,
2531 color-mix(in srgb, var(--accent, #888) 22%, var(--paper-2, var(--paper))) 0%,
2532 color-mix(in srgb, var(--accent, #888) 6%, var(--paper-2, var(--paper))) 100%);
2533}
2534/* Cover as a real <img> (not background-image): browsers downsample <img> with the
2535 high-quality image pipeline, so high-res line-art covers don't go jagged when shrunk.
2536 Fades in on load (.is-loading removed) so the placeholder shows meanwhile. */
2537.grid-tile-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: center; display: block; transition: opacity .4s ease; }
2538.grid-tile-img.is-loading { opacity: 0; }
2539/* Audio tile (Shaer, Robins vraag 30-7): the waveform PNG is white on
2540 transparent and floats OVER the tile's own hue gradient, so every audio
2541 post keeps its color and gets its shape. Wave and title each get their
2542 own band (wave upper, title lower): centering both stacked them right
2543 through each other (Robins schermafdruk). */
2544.grid-tile-img.grid-tile-wave {
2545 background-color: transparent;
2546 object-fit: contain;
2547 /* explicit box, not auto: an absolutely positioned img falls back to its
2548 intrinsic size when width/height are auto, collapsing the band */
2549 top: 8%; left: 8%; right: auto; bottom: auto;
2550 width: 84%; height: 46%;
2551 opacity: .85;
2552}
2553.grid-tile-audio .grid-tile-title { position: absolute; left: 10%; right: 10%; top: 60%; }
2554.grid-tile-audio .grid-tile-gradient-src { position: absolute; left: 10%; right: 10%; top: 76%; }
2555/* Cover videos are decorative, not players: let clicks + right-click pass through to the
2556 tile link so you get the normal link menu (not the browser's <video> menu/controls).
2557 Autoplay is independent of pointer-events, so the video still plays. */
2558video.grid-tile-img,
2559.post-list-cover video,
2560.post-cover video { pointer-events: none; }
2561.grid-tile:hover { transform: scale(0.98); }
2562.grid-tile-overlay {
2563 position: absolute;
2564 inset: 0;
2565 padding: .6rem;
2566 display: flex;
2567 flex-direction: column;
2568 justify-content: flex-end;
2569 align-items: flex-start;
2570 background: linear-gradient(to top, rgba(0,0,0,.65) 0%, rgba(0,0,0,0) 50%);
2571 opacity: 0;
2572 transition: opacity .2s;
2573 pointer-events: none; /* klik moet naar de <a> eronder gaan, niet naar de overlay */
2574}
2575/* Bron-site (cirkel-feed): toont bij hover "van <site>" onder de titel. */
2576/* Source label: small text that wraps to 2 lines if needed, with a big chain icon
2577 beside it (the text was 1.44rem — bigger than the title — and overflowed on mobile). */
2578.grid-tile-overlay-src {
2579 color: #fff; opacity: .85;
2580 font-size: .72rem; line-height: 1.2; margin-top: .25rem;
2581 display: flex; align-items: center; gap: .3rem; width: 100%;
2582}
2583.grid-tile-overlay-src::before { content: "⛓"; font-size: 1.3rem; line-height: 1; flex: 0 0 auto; }
2584.grid-tile-gradient-src {
2585 margin-top: .35rem; font-size: .72rem; line-height: 1.2; opacity: .85;
2586 color: var(--ink-soft);
2587 display: flex; align-items: center; gap: .3rem; width: 100%;
2588}
2589.grid-tile-gradient-src::before { content: "⛓"; font-size: 1.3rem; line-height: 1; flex: 0 0 auto; }
2590.grid-tile-overlay strong {
2591 color: #fff;
2592 font-family: var(--font-display);
2593 font-size: .9rem;
2594 font-weight: 500;
2595 line-height: 1.15;
2596 display: -webkit-box;
2597 -webkit-line-clamp: 3;
2598 -webkit-box-orient: vertical;
2599 overflow: hidden;
2600}
2601@media (hover: hover) {
2602 .grid-tile:hover .grid-tile-overlay { opacity: 1; }
2603}
2604@media (hover: none) {
2605 /* Op touch-devices altijd overlay tonen zodat titels zichtbaar zijn */
2606 .grid-tile-overlay { opacity: 1; background: linear-gradient(to top, rgba(0,0,0,.7) 0%, rgba(0,0,0,0) 70%); }
2607}
2608
2609.grid-tile-gradient {
2610 background-image: none;
2611 background-color: hsl(var(--tile-hue, 30), 40%, 85%);
2612 background-image: linear-gradient(135deg, hsl(var(--tile-hue, 30), 45%, 88%), hsl(calc(var(--tile-hue, 30) + 30), 35%, 75%));
2613 display: flex;
2614 flex-direction: column;
2615 align-items: center;
2616 justify-content: center;
2617 padding: 1rem;
2618 text-align: center;
2619}
2620[data-theme="dark"] .grid-tile-gradient,
2621.grid-tile-gradient[data-theme="dark"] {
2622 background-image: linear-gradient(135deg, hsl(var(--tile-hue, 30), 30%, 18%), hsl(calc(var(--tile-hue, 30) + 30), 25%, 12%));
2623}
2624.grid-tile-title {
2625 font-family: var(--font-display);
2626 font-size: 1rem;
2627 font-weight: 500;
2628 color: var(--ink);
2629 line-height: 1.2;
2630 display: -webkit-box;
2631 -webkit-line-clamp: 4;
2632 -webkit-box-orient: vertical;
2633 overflow: hidden;
2634 z-index: 1;
2635 /* Federated link posts can have a long bare URL as their title — break it so it wraps
2636 inside the tile and clamps cleanly instead of overflowing past both edges. */
2637 max-width: 100%;
2638 overflow-wrap: anywhere;
2639 word-break: break-word;
2640 hyphens: auto;
2641}
2642
2643.grid-tile-pin {
2644 position: absolute;
2645 top: .5rem;
2646 right: .5rem;
2647 display: inline-flex;
2648 align-items: center;
2649 gap: .25rem;
2650 padding: .2rem .55rem;
2651 background: var(--accent);
2652 color: #fff;
2653 border-radius: 999px;
2654 font-family: var(--font-ui);
2655 font-size: .65rem;
2656 font-weight: 700;
2657 text-transform: uppercase;
2658 letter-spacing: .06em;
2659 z-index: 3;
2660 box-shadow: 0 2px 6px rgba(0,0,0,.3);
2661 pointer-events: none;
2662}
2663.grid-tile-pin svg {
2664 width: .95em;
2665 height: .95em;
2666 margin-top: -1px;
2667}
2668/* Pinned/boosted tile: accent ring. An outline on the tile is painted UNDER the absolute
2669 cover <img>, so draw the ring as a pseudo-element overlay ABOVE the image (z-index above
2670 the img, below the corner badges + nsfw veil). */
2671.grid-tile.is-pinned { position: relative; z-index: 1; }
2672.grid-tile.is-pinned::after {
2673 content: '';
2674 position: absolute;
2675 inset: 0;
2676 border: 3px solid var(--accent);
2677 border-radius: inherit;
2678 pointer-events: none;
2679 z-index: 1;
2680}
2681.grid-tile-type {
2682 position: absolute;
2683 top: .4rem;
2684 left: .4rem;
2685 padding: .15rem .5rem;
2686 background: rgba(0,0,0,.55);
2687 color: #fff;
2688 border-radius: 999px;
2689 font-family: var(--font-ui);
2690 font-size: .6rem;
2691 font-weight: 600;
2692 text-transform: uppercase;
2693 letter-spacing: .05em;
2694 z-index: 2;
2695}
2696
2697@media (min-width: 600px) {
2698 .grid-tiles { grid-template-columns: repeat(3, 1fr); }
2699}
2700@media (min-width: 900px) {
2701 .grid-tiles { grid-template-columns: repeat(3, 1fr); gap: 8px; }
2702}
2703
2704/* -------- POST-TYPE SPECIFIEKE LAYOUTS -------- */
2705
2706/* Foto-post: beeld prominent, geen titel bovenaan, caption onder */
2707.feed-timeline[data-post-type="foto"] .post-title {
2708 font-size: 1.1rem;
2709 color: var(--ink-muted);
2710 font-weight: 400;
2711}
2712.feed-timeline[data-post-type="foto"] .post-cover {
2713 margin: 0 -1rem 1rem;
2714 border-radius: 0;
2715}
2716.feed-timeline[data-post-type="foto"] .post-cover img {
2717 width: 100%;
2718 border-radius: 0;
2719}
2720
2721/* Post-caption onder de cover */
2722.post-caption {
2723 font-family: var(--font-body);
2724 font-size: 1rem;
2725 color: var(--ink);
2726 line-height: 1.5;
2727 margin: 0 0 1.25rem;
2728 padding: 0 0 1rem;
2729 border-bottom: 1px solid var(--rule);
2730 white-space: pre-wrap;
2731}
2732.feed-timeline[data-post-type="foto"] .post-caption {
2733 font-size: 1.05rem;
2734 margin-top: -.5rem;
2735 padding-bottom: 1.25rem;
2736}
2737
2738/* Audio/video posts — type-chip helder, content eronder zoals normaal */
2739.feed-timeline[data-post-type="audio"] .post-title,
2740.feed-timeline[data-post-type="video"] .post-title {
2741 font-size: 1.5rem;
2742}
2743
2744@media (min-width: 768px) {
2745 .feed-timeline[data-post-type="foto"] .post-cover {
2746 margin: 0 0 1.5rem;
2747 border-radius: var(--radius);
2748 }
2749}
2750
2751/* -------- ADMIN EDIT-BUTTON op post-view (alleen zichtbaar voor ingelogde admin) -------- */
2752.post-edit-btn {
2753 position: absolute;
2754 top: 1rem;
2755 right: 1rem;
2756 display: inline-flex;
2757 align-items: center;
2758 justify-content: center;
2759 width: 44px;
2760 height: 44px;
2761 background: var(--paper);
2762 border: 1px solid var(--rule);
2763 border-radius: 50%;
2764 color: var(--ink-muted);
2765 text-decoration: none;
2766 box-shadow: 0 2px 8px rgba(0,0,0,.08);
2767 transition: background .15s, color .15s, transform .15s, border-color .15s;
2768 z-index: 10;
2769}
2770.post-edit-btn:hover {
2771 background: var(--accent);
2772 border-color: var(--accent);
2773 color: var(--paper);
2774 transform: scale(1.05);
2775}
2776.post-edit-btn .icon {
2777 width: 1.1rem;
2778 height: 1.1rem;
2779}
2780/* Zorg dat de article relative is zodat absolute positionering werkt */
2781.feed-timeline { position: relative; }
2782
2783@media (min-width: 768px) {
2784 .post-edit-btn {
2785 top: 1.5rem;
2786 right: 1.5rem;
2787 }
2788}
2789
2790/* ============================================================
2791 v8.0 — ACCENT SPAN + POST-TABLE (published posts)
2792 ============================================================ */
2793.post span.accent,
2794.post-content span.accent,
2795article span.accent,
2796page-container span.accent {
2797 color: var(--accent);
2798 font-weight: 500;
2799}
2800
2801.post-table,
2802article table.post-table {
2803 width: 100%;
2804 max-width: 100%;
2805 border-collapse: collapse;
2806 margin: 1.25rem 0;
2807 font-size: .95rem;
2808 display: block;
2809 overflow-x: auto;
2810 -webkit-overflow-scrolling: touch;
2811}
2812.post-table thead { background: color-mix(in srgb, var(--accent) 10%, transparent); }
2813.post-table th,
2814.post-table td {
2815 padding: .6rem .8rem;
2816 text-align: left;
2817 border: 1px solid var(--rule);
2818 vertical-align: top;
2819}
2820.post-table th {
2821 font-family: var(--font-ui);
2822 font-weight: 600;
2823 font-size: .88rem;
2824 color: var(--ink);
2825 letter-spacing: .02em;
2826}
2827.post-table tbody tr:nth-child(even) {
2828 background: color-mix(in srgb, var(--ink) 3%, transparent);
2829}
2830@media (min-width: 700px) {
2831 .post-table { display: table; overflow: visible; }
2832}
2833
2834/* ============================================================
2835 v8.0 fix — grid-cols picker (desktop only) + grid col overrides
2836 ============================================================ */
2837
2838/* Switcher-wrap bevat nu ook de cols-picker; layout side-by-side */
2839.view-switcher-wrap .container {
2840 display: flex;
2841 align-items: center;
2842 justify-content: center;
2843 gap: 1rem;
2844 flex-wrap: wrap;
2845}
2846
2847/* Solo / Cirkel scope-switcher (alleen in circle-modus) — segmented toggle, centraal.
2848 Hoge specificiteit (+ !important op tekst) zodat 'ie globale link-stijlen wint. */
2849.view-switcher-wrap .feed-scope {
2850 display: inline-flex;
2851 background: var(--paper-2);
2852 border: 1px solid var(--rule);
2853 border-radius: 999px;
2854 padding: 3px;
2855}
2856.view-switcher-wrap .feed-scope-btn {
2857 display: inline-flex;
2858 align-items: center;
2859 padding: .32rem .95rem;
2860 min-height: 30px;
2861 border: none !important;
2862 border-radius: 999px !important;
2863 background: transparent !important;
2864 color: var(--ink-muted) !important;
2865 font-family: var(--font-ui);
2866 font-size: .82rem;
2867 font-weight: 500 !important;
2868 text-decoration: none !important;
2869 cursor: pointer;
2870 transition: all .15s;
2871}
2872.view-switcher-wrap .feed-scope-btn:hover { color: var(--ink) !important; }
2873.view-switcher-wrap .feed-scope-btn.is-active {
2874 background: var(--ink) !important;
2875 color: var(--paper) !important;
2876}
2877
2878.grid-cols-picker {
2879 display: none; /* default hidden — desktop + grid-active maakt 'm zichtbaar */
2880 gap: 2px;
2881 padding: 0;
2882}
2883.grid-cols-btn {
2884 display: inline-flex;
2885 align-items: center;
2886 justify-content: center;
2887 min-width: 36px;
2888 height: 32px;
2889 padding: 0 .6rem;
2890 background: transparent;
2891 border: 1px solid var(--rule);
2892 color: var(--ink-muted);
2893 font-family: var(--font-ui);
2894 font-size: .85rem;
2895 font-weight: 500;
2896 cursor: pointer;
2897 transition: all .12s;
2898}
2899.grid-cols-btn:first-child { border-radius: 999px 0 0 999px; }
2900.grid-cols-btn:last-child { border-radius: 0 999px 999px 0; }
2901.grid-cols-btn:not(:first-child):not(:last-child) { border-left: none; border-right: none; }
2902.grid-cols-btn:hover { color: var(--ink); }
2903/* Active state puur via body[data-grid-cols] — geen is-active-class meer. */
2904body[data-grid-cols="2"] .grid-cols-btn[data-cols="2"],
2905body[data-grid-cols="3"] .grid-cols-btn[data-cols="3"],
2906body[data-grid-cols="4"] .grid-cols-btn[data-cols="4"] {
2907 background: var(--ink);
2908 color: var(--paper);
2909 border-color: var(--ink);
2910}
2911
2912/* Desktop + grid-view → toon cols-picker (op de home-feed; niet op archief) */
2913@media (min-width: 600px) {
2914 body.on-home[data-feed-view="grid"] .grid-cols-picker {
2915 display: inline-flex;
2916 }
2917}
2918
2919/* Kolom-overrides op desktop. Mobiel negeert dit (staat vast op 2). Geldt op ELKE
2920 feed met grid (home én cirkel/tag/type/user) — scope op .feed-grid .grid-tiles. */
2921@media (min-width: 600px) {
2922 body[data-grid-cols="2"] .feed-grid .grid-tiles { grid-template-columns: repeat(2, 1fr); }
2923 body[data-grid-cols="3"] .feed-grid .grid-tiles { grid-template-columns: repeat(3, 1fr); }
2924 body[data-grid-cols="4"] .feed-grid .grid-tiles { grid-template-columns: repeat(4, 1fr); }
2925}
2926
2927/* Gradient-tile: iets meer contrast voor light + dark mode zodat titel altijd leesbaar is */
2928.grid-tile-gradient {
2929 background-image: linear-gradient(135deg,
2930 hsl(var(--tile-hue, 30), 55%, 72%),
2931 hsl(calc(var(--tile-hue, 30) + 40), 45%, 60%));
2932}
2933[data-theme="dark"] .grid-tile-gradient {
2934 background-image: linear-gradient(135deg,
2935 hsl(var(--tile-hue, 30), 40%, 30%),
2936 hsl(calc(var(--tile-hue, 30) + 40), 30%, 18%));
2937}
2938.grid-tile-gradient .grid-tile-title {
2939 color: #fff;
2940 text-shadow: 0 1px 3px rgba(0,0,0,.25);
2941}
2942[data-theme="dark"] .grid-tile-gradient .grid-tile-title {
2943 color: #fff;
2944 text-shadow: 0 1px 2px rgba(0,0,0,.5);
2945}
2946
2947/* ============================================================
2948 v8.0.2 — COMPACT DESIGN OVERRIDES
2949 Tighter masthead, padding, margins overall. Profiel-header
2950 collapse/expand blijft zoals 'ie was.
2951 ============================================================ */
2952
2953/* Masthead: compacter */
2954.masthead { padding: calc(.55rem + var(--ios-safe-top, 0px)) 0 .55rem; }
2955.masthead-inner { gap: 1rem; }
2956.site-title { font-size: 1.25rem; }
2957.nav-link, .nav-btn { padding: .4rem .7rem; min-height: 2rem; font-size: .82rem; }
2958
2959/* Main content padding */
2960main { padding-top: 1rem; }
2961.page { padding-block: 1rem 1.75rem; }
2962
2963/* View switcher-bar strakker */
2964.view-switcher { padding: .4rem 0; gap: .3rem; }
2965.view-switch-btn { padding: .4rem .85rem; min-height: 38px; font-size: .8rem; }
2966.grid-cols-btn { min-width: 32px; height: 28px; padding: 0 .5rem; font-size: .8rem; }
2967
2968/* Post header spacing terug */
2969.post-header { margin: 0 0 1.25rem; }
2970.post-title { margin-bottom: .35rem; }
2971.post-meta { font-size: .78rem; }
2972.post-tags { margin-top: .6rem; gap: .3rem; }
2973.post-tag { font-size: .7rem; padding: .15rem .55rem; }
2974
2975/* Article footer + pagination compacter */
2976.article-footer { padding-top: 1.25rem; margin-top: 1.5rem; }
2977.pagination { padding-block: 1.25rem 2rem; margin-top: 1.5rem; }
2978.pagination-item { padding: .75rem .95rem; min-height: 4rem; }
2979.pagination-title { font-size: .95rem; }
2980
2981/* Site footer compacter */
2982.site-footer { padding: 1.25rem 0 calc(1.25rem + env(safe-area-inset-bottom, 0px)); margin-top: 2rem; font-size: .78rem; }
2983.site-footer-inner { gap: .75rem; }
2984
2985/* Profiel-header: full mode iets minder riant (compact mode blijft hetzelfde) */
2986.profile-header { padding: 1rem 0; }
2987.profile-photo { width: 72px; height: 72px; }
2988.profile-photo-fallback { font-size: 1.8rem; }
2989.profile-name { font-size: 1.2rem; }
2990.profile-bio { font-size: .85rem; margin-top: .15rem; }
2991.profile-links { margin-top: .5rem; gap: .4rem; }
2992.profile-links a,
2993.profile-links .profile-fedi-link { width: 32px; height: 32px; }
2994
2995@media (min-width: 768px) {
2996 .profile-header { padding: 1.35rem 0; }
2997 .profile-photo { width: 92px; height: 92px; }
2998 .profile-photo-fallback { font-size: 2.4rem; }
2999 .profile-name { font-size: 1.4rem; }
3000 .profile-bio { font-size: .95rem; }
3001 .profile-header-inner { gap: 1.1rem; }
3002 /* Compact-mode op desktop blijft klein zoals we hadden afgesproken */
3003 .on-post .profile-photo,
3004 .on-special .profile-photo { width: 42px; height: 42px; }
3005}
3006
3007/* Grid-tegels iets strakker gaten */
3008.grid-tiles { gap: 3px; }
3009
3010/* Post-cover margin */
3011.post-cover { margin: 0 0 1rem; }
3012
3013/* Audio player wat lichter */
3014#pcms-audio-bar { padding: .55rem 1rem; }
3015
3016/* v8.1 — pagination CTA + mobile tap target */
3017.pagination-cta {
3018 display: inline-block;
3019 font-family: var(--font-ui);
3020 font-size: .72rem;
3021 font-weight: 600;
3022 color: var(--accent);
3023 margin-top: .35rem;
3024 letter-spacing: .02em;
3025 opacity: .9;
3026}
3027a.pagination-item:hover .pagination-cta { opacity: 1; }
3028
3029/* Mobiel: nog meer tap-feedback + iets prominenter */
3030@media (max-width: 640px) {
3031 a.pagination-item {
3032 padding: 1.1rem 1rem;
3033 min-height: 5.5rem;
3034 border-width: 2px;
3035 }
3036 a.pagination-item:active {
3037 background: color-mix(in srgb, var(--accent) 10%, var(--paper-2));
3038 transform: scale(.98);
3039 }
3040 .pagination-title { font-size: 1rem; }
3041 .pagination-cta { font-size: .75rem; }
3042 .pagination .icon { width: 1.5em; height: 1.5em; }
3043}
3044
3045
3046
3047/* v8.3 / v9.4 — PWA install button (alleen zichtbaar als browser install ondersteunt) */
3048.nav-install-btn[hidden] { display: none; }
3049.nav-install-btn {
3050 position: relative;
3051 display: inline-flex;
3052 align-items: center;
3053 justify-content: center;
3054 gap: .35rem;
3055 background: linear-gradient(135deg,
3056 var(--accent),
3057 color-mix(in srgb, var(--accent) 80%, #000));
3058 color: #fff;
3059 border: none;
3060 border-radius: .65rem;
3061 padding: .45rem .85rem;
3062 font-size: .8rem;
3063 font-weight: 600;
3064 line-height: 1;
3065 cursor: pointer;
3066 overflow: hidden;
3067 isolation: isolate;
3068 box-shadow:
3069 0 1px 0 rgba(255,255,255,.15) inset,
3070 0 2px 6px color-mix(in srgb, var(--accent) 35%, transparent);
3071 transition:
3072 transform .15s cubic-bezier(.4, 0, .2, 1),
3073 box-shadow .2s ease,
3074 filter .15s ease;
3075}
3076.nav-install-btn::before {
3077 content: "";
3078 position: absolute;
3079 top: 0;
3080 left: -100%;
3081 width: 60%;
3082 height: 100%;
3083 background: linear-gradient(110deg,
3084 transparent 30%,
3085 rgba(255,255,255,.22) 50%,
3086 transparent 70%);
3087 z-index: -1;
3088 animation: pcmsInstallShimmer 4s ease-in-out infinite;
3089 pointer-events: none;
3090}
3091.nav-install-btn:hover {
3092 transform: translateY(-1px);
3093 filter: brightness(1.08);
3094 box-shadow:
3095 0 1px 0 rgba(255,255,255,.2) inset,
3096 0 4px 10px color-mix(in srgb, var(--accent) 50%, transparent);
3097}
3098.nav-install-btn:active { transform: translateY(0); }
3099.nav-install-btn .icon {
3100 flex-shrink: 0;
3101 transition: transform .25s cubic-bezier(.34, 1.56, .64, 1);
3102}
3103.nav-install-btn:hover .icon { transform: translateY(-1px); }
3104@media (prefers-reduced-motion: reduce) {
3105 .nav-install-btn::before { animation: none; left: -100%; }
3106 .nav-install-btn:hover { transform: none; }
3107 .nav-install-btn:hover .icon { transform: none; }
3108}
3109/* Als PWA al draait (standalone mode) — verberg install-prompt knop volledig */
3110@media all and (display-mode: standalone) {
3111 #pwa-install-btn { display: none !important; }
3112}
3113
3114/* ========== v8.9.9 — Privé-post indicators ========== */
3115.post-private-banner {
3116 display: flex;
3117 align-items: center;
3118 gap: .6rem;
3119 padding: .75rem 1rem;
3120 background: color-mix(in srgb, #eab308 12%, var(--paper, #fff));
3121 border: 1px solid color-mix(in srgb, #eab308 40%, transparent);
3122 border-radius: 8px;
3123 margin: 0 0 1rem;
3124 font-size: .88rem;
3125 color: var(--ink, #1a1a1a);
3126}
3127.post-private-banner strong {
3128 color: #b45309;
3129}
3130
3131.grid-tile-private {
3132 position: absolute;
3133 top: 8px;
3134 left: 8px;
3135 padding: 3px 8px;
3136 background: rgba(0,0,0,0.7);
3137 color: #fde68a;
3138 font-size: .7rem;
3139 font-weight: 700;
3140 border-radius: 999px;
3141 z-index: 3;
3142 backdrop-filter: blur(4px);
3143 -webkit-backdrop-filter: blur(4px);
3144}
3145
3146/* ========== v8.9.10 — Social chip (inline in post-body) ========== */
3147.social-chip {
3148 display: inline-flex;
3149 align-items: center;
3150 gap: .45rem;
3151 padding: .35rem .75rem;
3152 background: color-mix(in srgb, var(--accent) 10%, transparent);
3153 border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
3154 border-radius: 999px;
3155 color: var(--ink, #1a1a1a);
3156 text-decoration: none;
3157 font-family: var(--font-ui, system-ui);
3158 font-size: .85rem;
3159 font-weight: 600;
3160 line-height: 1.2;
3161 transition: all .15s;
3162 vertical-align: middle;
3163 margin: 0 .1rem;
3164}
3165.social-chip:hover {
3166 background: var(--accent);
3167 color: #fff;
3168 border-color: var(--accent);
3169 text-decoration: none;
3170 transform: translateY(-1px);
3171 box-shadow: 0 2px 8px color-mix(in srgb, var(--accent) 40%, transparent);
3172}
3173.social-chip .icon {
3174 width: 16px;
3175 height: 16px;
3176 flex-shrink: 0;
3177}
3178.social-chip-icon-only {
3179 width: 36px;
3180 height: 36px;
3181 padding: 0;
3182 justify-content: center;
3183 border-radius: 50%;
3184}
3185.social-chip-icon-only .icon {
3186 width: 18px;
3187 height: 18px;
3188}
3189
3190/* v8.9.34 — player hidden state + post audio blocks
3191 v9.3 — Hide-rules uitgeschakeld: mini-player blijft permanent zichtbaar
3192 zodat 'ie niet meer verdwijnt bij browser-back of navigatie. */
3193.audio-player.is-hidden {
3194 /* display: none !important; */
3195}
3196body:not(.has-audio-player) #pcms-audio-player.is-hidden {
3197 /* display: none !important; */
3198}
3199
3200/* Post audio track — single track row in een post */
3201/* Lokale audio-track — visueel consistent met .post-audio-external */
3202.post-audio-track {
3203 display: flex;
3204 align-items: center;
3205 gap: .75rem;
3206 padding: .65rem .85rem;
3207 background: var(--paper-2, color-mix(in srgb, var(--ink) 4%, transparent));
3208 border: 1px solid var(--rule, rgba(0,0,0,.08));
3209 border-radius: 10px;
3210 margin: .75rem 0;
3211 transition: background .15s, border-color .15s;
3212}
3213.post-audio-track:hover {
3214 border-color: var(--accent, #c2410c);
3215 background: color-mix(in srgb, var(--accent, #c2410c) 5%, var(--paper-2, transparent));
3216}
3217/* Korte highlight wanneer je via de mini-speler naar deze track springt. */
3218.post-audio-track.pat-flash,
3219.post-album-track-compact.pat-flash {
3220 animation: patFlash 1.6s ease-out;
3221 border-radius: 8px;
3222}
3223/* Blijvende highlight op de track die NU actief is in de speler. */
3224.post-audio-track.pat-playing,
3225.post-album-track-compact.pat-playing {
3226 background: color-mix(in srgb, var(--accent, #c2410c) 12%, var(--paper-2, transparent));
3227 box-shadow: inset 3px 0 0 0 var(--accent, #c2410c);
3228 border-radius: 8px;
3229}
3230@keyframes patFlash {
3231 0%, 30% { border-color: var(--accent, #c2410c); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent, #c2410c) 35%, transparent); }
3232 100% { box-shadow: 0 0 0 0 transparent; }
3233}
3234.post-audio-track .pat-play {
3235 flex-shrink: 0;
3236 width: 42px;
3237 height: 42px;
3238 border-radius: 8px; /* zelfde rounded-square als pae-icon */
3239 border: none;
3240 background: var(--accent, #c2410c);
3241 color: var(--paper, #fff);
3242 cursor: pointer;
3243 display: inline-flex;
3244 align-items: center;
3245 justify-content: center;
3246 transition: transform .1s, background .15s;
3247 padding: 0;
3248 position: relative;
3249 overflow: hidden;
3250}
3251.post-audio-track .pat-play:hover { transform: scale(1.04); }
3252.post-audio-track .pat-play:active { transform: scale(.96); }
3253.post-audio-track .pat-play svg,
3254.post-audio-track .pat-play .pat-sitelogo {
3255 width: 100%; height: 100%;
3256 position: absolute;
3257 top: 0; left: 0;
3258 transition: opacity .15s;
3259}
3260.post-audio-track .pat-play .icon-play,
3261.post-audio-track .pat-play .icon-pause {
3262 width: 18px; height: 18px;
3263 position: absolute;
3264 top: 50%; left: 50%;
3265 transform: translate(-50%, -50%);
3266 fill: currentColor;
3267 opacity: 0; /* verborgen tot hover of is-current */
3268}
3269/* Site logo: object-cover binnen 42x42 box */
3270.post-audio-track .pat-play .pat-sitelogo {
3271 object-fit: cover;
3272 opacity: 1;
3273}
3274.post-audio-track .pat-play .pat-sitelogo-fallback {
3275 padding: 11px; /* SVG music-note iets kleiner in box */
3276 opacity: 1;
3277}
3278/* Bij hover: site logo faded, play-icoon verschijnt */
3279.post-audio-track:hover .pat-play .pat-sitelogo { opacity: 0.25; }
3280.post-audio-track:hover .pat-play .icon-play { opacity: 1; }
3281/* Bij current + playing: toon pause-icon */
3282.post-audio-track.is-current .pat-play .pat-sitelogo { opacity: 0.25; }
3283.post-audio-track.is-current .pat-play .icon-play { opacity: 1; }
3284.post-audio-track.is-current.is-playing .pat-play .icon-play { opacity: 0; }
3285.post-audio-track.is-current.is-playing .pat-play .icon-pause { opacity: 1; }
3286.post-audio-track.is-current {
3287 border-color: var(--accent, #c2410c);
3288 background: color-mix(in srgb, var(--accent, #c2410c) 10%, transparent);
3289}
3290.post-audio-track .pat-meta {
3291 flex: 1;
3292 min-width: 0;
3293 display: flex;
3294 flex-direction: column;
3295 gap: 2px;
3296}
3297.post-audio-track .pat-title {
3298 display: block;
3299 font-weight: 600;
3300 color: var(--ink);
3301 font-size: .95rem;
3302 overflow: hidden;
3303 text-overflow: ellipsis;
3304 white-space: nowrap;
3305}
3306.post-audio-track .pat-artist {
3307 display: block;
3308 font-size: .78rem;
3309 color: var(--ink-muted, var(--ink));
3310 opacity: .65;
3311 overflow: hidden;
3312 text-overflow: ellipsis;
3313 white-space: nowrap;
3314}
3315.post-audio-track .pat-duration {
3316 flex-shrink: 0;
3317 font-family: ui-monospace, monospace;
3318 font-size: .8rem;
3319 opacity: .55;
3320}
3321
3322/* Album block in een post */
3323.post-album {
3324 position: relative;
3325 border: 1px solid var(--rule, rgba(0,0,0,.1));
3326 border-radius: 14px;
3327 overflow: hidden;
3328 margin: 1.25rem 0;
3329 background: var(--paper-2, color-mix(in srgb, var(--ink) 3%, transparent));
3330}
3331.post-album-header {
3332 display: flex;
3333 gap: .75rem;
3334 padding: .55rem .7rem;
3335 align-items: center;
3336}
3337.post-album-cover {
3338 width: 120px;
3339 height: 120px;
3340 border-radius: 8px;
3341 background-size: cover;
3342 background-position: center;
3343 background-color: var(--rule);
3344 flex-shrink: 0;
3345}
3346/* v9.0 — Collage van track-covers als album-cover leeg is */
3347.post-album-cover-collage {
3348 display: grid;
3349 grid-template-columns: 1fr 1fr;
3350 grid-template-rows: 1fr 1fr;
3351 gap: 0;
3352 overflow: hidden;
3353 background: transparent;
3354}
3355.post-album-cover-collage .post-album-cover-tile {
3356 background-size: cover;
3357 background-position: center;
3358 width: 100%;
3359 height: 100%;
3360}
3361/* Empty state: gradient met muziek-noot */
3362.post-album-cover-empty {
3363 display: flex;
3364 align-items: center;
3365 justify-content: center;
3366 background: linear-gradient(135deg, color-mix(in srgb, var(--accent) 25%, var(--paper-2)), color-mix(in srgb, var(--accent) 10%, var(--paper)));
3367 color: var(--accent, #c2410c);
3368}
3369.post-album-cover-empty svg {
3370 width: 42%;
3371 height: 42%;
3372 opacity: .55;
3373}
3374.post-album-info {
3375 flex: 1;
3376 min-width: 0;
3377}
3378.post-album-label {
3379 text-transform: uppercase;
3380 font-size: .68rem;
3381 letter-spacing: .1em;
3382 opacity: .55;
3383 margin: 0 0 .15rem;
3384 font-weight: 700;
3385}
3386.post-album-title {
3387 font-family: var(--font-display);
3388 font-size: 1.1rem;
3389 font-weight: 600;
3390 margin: 0 0 .1rem;
3391 line-height: 1.15;
3392 letter-spacing: -0.01em;
3393}
3394.post-album-artist {
3395 font-size: .88rem;
3396 opacity: .8;
3397 margin: 0 0 .12rem;
3398 line-height: 1.25;
3399}
3400.post-album-meta {
3401 font-size: .74rem;
3402 opacity: .55;
3403 margin: 0;
3404 line-height: 1.2;
3405}
3406.post-album-playall {
3407 margin-top: .75rem;
3408 padding: .45rem .9rem;
3409 background: var(--accent, #c2410c);
3410 color: var(--paper, #fff);
3411 border: none;
3412 border-radius: 6px;
3413 font-weight: 600;
3414 cursor: pointer;
3415 font-size: .88rem;
3416 display: inline-flex;
3417 align-items: center;
3418 gap: .35rem;
3419}
3420.post-album-playall:hover { filter: brightness(1.08); }
3421
3422/* ============================================================
3423 v9.0 — Album cover clickable button
3424 ============================================================ */
3425.post-album-cover-btn {
3426 position: relative;
3427 background: none;
3428 border: none;
3429 padding: 0;
3430 margin: 0;
3431 cursor: pointer;
3432 flex-shrink: 0;
3433 border-radius: 8px;
3434 overflow: hidden;
3435 display: block;
3436 width: auto;
3437 /* v9.1 — voorkom mobile 300ms double-tap zoom delay, anders zou 2× snel klikken
3438 een zoom triggeren i.p.v. 2× click-events */
3439 touch-action: manipulation;
3440 -webkit-tap-highlight-color: transparent;
3441}
3442.post-album-cover-btn .post-album-cover {
3443 display: block;
3444 width: 76px;
3445 height: 76px;
3446 border-radius: 7px;
3447 background-size: cover;
3448 background-position: center;
3449 background-color: var(--rule);
3450 transition: transform .25s ease;
3451}
3452.post-album-cover-btn:hover .post-album-cover {
3453 transform: scale(1.04);
3454}
3455.post-album-cover-btn .post-album-cover-empty {
3456 background: linear-gradient(135deg,
3457 color-mix(in srgb, var(--accent, #c2410c) 35%, var(--paper)),
3458 color-mix(in srgb, var(--accent, #c2410c) 10%, var(--paper-2)));
3459 display: flex;
3460 align-items: center;
3461 justify-content: center;
3462}
3463.post-album-cover-btn .post-album-cover-empty svg {
3464 width: 28px;
3465 height: 28px;
3466 color: color-mix(in srgb, var(--accent, #c2410c) 60%, transparent);
3467}
3468/* Play overlay op hover */
3469.post-album-cover-play {
3470 position: absolute;
3471 inset: 0;
3472 display: flex;
3473 align-items: center;
3474 justify-content: center;
3475 background: rgba(0, 0, 0, .35);
3476 opacity: 0;
3477 transition: opacity .2s ease;
3478 border-radius: 8px;
3479 pointer-events: none;
3480}
3481.post-album-cover-play svg {
3482 width: 48px;
3483 height: 48px;
3484 color: #fff;
3485 filter: drop-shadow(0 2px 8px rgba(0,0,0,.4));
3486}
3487.post-album-cover-btn:hover .post-album-cover-play,
3488.post-album-cover-btn:focus-visible .post-album-cover-play {
3489 opacity: 1;
3490}
3491
3492/* ============================================================
3493 v1 P52 — Admin actions overlay (edit / delete)
3494 Only rendered when the viewer has god role. Sits top-right
3495 of the card so it doesn't compete with the cover play affordance.
3496 ============================================================ */
3497.post-album-actions {
3498 position: absolute;
3499 top: .4rem;
3500 right: .4rem;
3501 display: flex;
3502 gap: .25rem;
3503 z-index: 2;
3504}
3505.post-album-action {
3506 width: 28px;
3507 height: 28px;
3508 border-radius: 6px;
3509 border: 1px solid var(--rule);
3510 background: color-mix(in srgb, var(--paper) 78%, transparent);
3511 backdrop-filter: blur(8px);
3512 -webkit-backdrop-filter: blur(8px);
3513 color: var(--ink);
3514 display: inline-flex;
3515 align-items: center;
3516 justify-content: center;
3517 cursor: pointer;
3518 text-decoration: none;
3519 opacity: .65;
3520 padding: 0;
3521 transition: opacity .15s ease, transform .15s ease, background .15s ease, color .15s ease, border-color .15s ease;
3522 -webkit-tap-highlight-color: transparent;
3523}
3524.post-album-action:hover,
3525.post-album-action:focus-visible {
3526 opacity: 1;
3527 transform: translateY(-1px);
3528 outline: none;
3529}
3530.post-album-action.is-danger:hover,
3531.post-album-action.is-danger:focus-visible {
3532 background: color-mix(in srgb, #c2410c 18%, var(--paper));
3533 border-color: color-mix(in srgb, #c2410c 45%, var(--rule));
3534 color: #c2410c;
3535}
3536.post-album-action svg {
3537 width: 15px;
3538 height: 15px;
3539 display: block;
3540}
3541
3542/* ============================================================
3543 v9.0 — Compacte tracklist (informatief, niet-klikbaar)
3544 ============================================================ */
3545.post-album-tracks {
3546 list-style: none;
3547 padding: 0;
3548 margin: 0;
3549 border-top: 1px solid var(--rule);
3550}
3551/* v9.4 — Playlist insert modal rows */
3552.pli-row {
3553 display: flex;
3554 align-items: center;
3555 gap: .75rem;
3556 padding: .65rem .5rem;
3557 border-bottom: 1px solid var(--border);
3558}
3559.pli-row:last-child { border-bottom: none; }
3560.pli-row-cover {
3561 width: 44px;
3562 height: 44px;
3563 border-radius: 6px;
3564 background-size: cover;
3565 background-position: center;
3566 background-color: color-mix(in srgb, var(--ink, #000) 8%, transparent);
3567 flex-shrink: 0;
3568 display: flex;
3569 align-items: center;
3570 justify-content: center;
3571 font-size: 1.4rem;
3572}
3573.pli-row-info {
3574 flex: 1;
3575 min-width: 0;
3576}
3577.pli-row-title {
3578 font-weight: 600;
3579 overflow: hidden;
3580 text-overflow: ellipsis;
3581 white-space: nowrap;
3582}
3583.pli-row-meta {
3584 font-size: .82rem;
3585 overflow: hidden;
3586 text-overflow: ellipsis;
3587 white-space: nowrap;
3588}
3589.post-playlist-placeholder {
3590 margin: 1rem 0;
3591 user-select: none;
3592}
3593
3594/* v9.4 — Generic modal classes (gebruikt door playlist-editor en andere modals) */
3595.pcms-modal-backdrop {
3596 position: fixed;
3597 inset: 0;
3598 background: rgba(0, 0, 0, .6);
3599 display: flex;
3600 align-items: center;
3601 justify-content: center;
3602 z-index: 9000;
3603 padding: 1rem;
3604 box-sizing: border-box;
3605 overflow-y: auto;
3606}
3607.pcms-modal {
3608 background: var(--paper, #fff);
3609 color: var(--ink, #000);
3610 border-radius: 12px;
3611 width: 100%;
3612 max-width: 640px;
3613 max-height: calc(100vh - 2rem);
3614 display: flex;
3615 flex-direction: column;
3616 overflow: hidden;
3617 box-shadow: 0 20px 60px rgba(0, 0, 0, .3);
3618}
3619.pcms-modal-header {
3620 display: flex;
3621 align-items: center;
3622 justify-content: space-between;
3623 padding: 1rem 1.25rem;
3624 border-bottom: 1px solid var(--border);
3625 flex-shrink: 0;
3626}
3627.pcms-modal-header h3 { font-size: 1.1rem; }
3628.pcms-modal-close {
3629 background: transparent;
3630 border: none;
3631 font-size: 1.6rem;
3632 line-height: 1;
3633 cursor: pointer;
3634 padding: .25rem .5rem;
3635 color: var(--fg-muted, #666);
3636 border-radius: 4px;
3637}
3638.pcms-modal-close:hover {
3639 background: color-mix(in srgb, var(--ink, #000) 8%, transparent);
3640}
3641.pcms-modal-body {
3642 padding: 1.25rem;
3643 overflow-y: auto;
3644 overscroll-behavior: contain;
3645 flex: 1;
3646 min-height: 0;
3647}
3648.pcms-modal-footer {
3649 display: flex;
3650 gap: .5rem;
3651 justify-content: flex-end;
3652 padding: .75rem 1.25rem;
3653 border-top: 1px solid var(--border);
3654 flex-shrink: 0;
3655 background: color-mix(in srgb, var(--ink, #000) 3%, transparent);
3656}
3657
3658/* On mobile: full-screen modal */
3659@media (max-width: 600px) {
3660 .pcms-modal-backdrop {
3661 padding: 0;
3662 }
3663 .pcms-modal {
3664 border-radius: 0;
3665 max-width: 100%;
3666 max-height: 100vh;
3667 height: 100vh;
3668 }
3669}
3670
3671/* v9.4 — Media → Playlists tab */
3672.playlists-page-header {
3673 display: flex;
3674 flex-wrap: wrap;
3675 gap: 1rem;
3676 align-items: center;
3677 justify-content: space-between;
3678 margin-bottom: 1.25rem;
3679}
3680.playlists-page-header > p { flex: 1; min-width: 200px; }
3681.playlists-grid {
3682 display: grid;
3683 grid-template-columns: 1fr;
3684 gap: .75rem;
3685}
3686@media (min-width: 720px) {
3687 .playlists-grid { grid-template-columns: repeat(2, 1fr); }
3688}
3689@media (min-width: 1100px) {
3690 .playlists-grid { grid-template-columns: repeat(3, 1fr); }
3691}
3692.playlist-card {
3693 display: grid;
3694 grid-template-columns: 64px 1fr auto;
3695 gap: .75rem;
3696 align-items: center;
3697 padding: .75rem;
3698 border: 1px solid var(--border);
3699 border-radius: var(--radius);
3700 background: var(--paper, #fff);
3701}
3702.playlist-card-cover {
3703 width: 64px;
3704 height: 64px;
3705 border-radius: 8px;
3706 overflow: hidden;
3707 background-color: color-mix(in srgb, var(--ink, #000) 6%, transparent);
3708 display: flex;
3709 align-items: center;
3710 justify-content: center;
3711}
3712.playlist-card-cover img {
3713 width: 100%;
3714 height: 100%;
3715 object-fit: cover;
3716}
3717.playlist-card-cover-empty { font-size: 1.6rem; opacity: .5; }
3718.playlist-card-info { min-width: 0; }
3719.playlist-card-title {
3720 font-weight: 600;
3721 overflow: hidden;
3722 text-overflow: ellipsis;
3723 white-space: nowrap;
3724}
3725.playlist-card-artist,
3726.playlist-card-meta {
3727 font-size: .82rem;
3728 overflow: hidden;
3729 text-overflow: ellipsis;
3730 white-space: nowrap;
3731}
3732.playlist-card-actions {
3733 display: flex;
3734 gap: .25rem;
3735 flex-shrink: 0;
3736}
3737
3738/* v9.4 — Playlist editor modal (mobile-friendly, single-column) */
3739.pl-editor {
3740 /* Erft van .pcms-modal */
3741}
3742.pl-editor-meta {
3743 display: grid;
3744 grid-template-columns: 1fr;
3745 gap: .75rem;
3746 margin-bottom: 1rem;
3747}
3748@media (min-width: 560px) {
3749 .pl-editor-meta {
3750 grid-template-columns: 1fr 1fr;
3751 }
3752 .pl-editor-meta .pl-editor-field-full { grid-column: 1 / -1; }
3753}
3754.pl-editor-field {
3755 display: flex;
3756 flex-direction: column;
3757 gap: .25rem;
3758 min-width: 0;
3759}
3760.pl-editor-field span {
3761 font-size: .82rem;
3762 color: var(--fg-muted, #666);
3763 font-weight: 500;
3764}
3765.pl-editor-field input,
3766.pl-editor-field select {
3767 width: 100%;
3768 box-sizing: border-box;
3769 padding: .5rem .65rem;
3770 font-size: .95rem;
3771 border: 1px solid var(--border);
3772 border-radius: 6px;
3773 background: var(--paper, #fff);
3774 color: var(--ink, #000);
3775}
3776.pl-editor-field input:focus,
3777.pl-editor-field select:focus {
3778 outline: 2px solid var(--accent, #5a8a5a);
3779 outline-offset: -1px;
3780}
3781.pl-editor-section-title {
3782 margin: 1.25rem 0 .5rem;
3783 font-size: 1rem;
3784 font-weight: 600;
3785}
3786.pl-tracks-selected {
3787 border: 1px solid var(--border);
3788 border-radius: var(--radius);
3789 background: var(--paper, #fff);
3790 min-height: 60px;
3791 margin-bottom: 1rem;
3792 padding: .25rem;
3793}
3794.pl-tracks-empty {
3795 padding: 1.5rem;
3796 text-align: center;
3797 color: var(--fg-muted, #666);
3798 font-size: .9rem;
3799}
3800.pl-track-row {
3801 display: grid;
3802 grid-template-columns: 32px 36px 1fr auto;
3803 gap: .5rem;
3804 align-items: center;
3805 padding: .5rem;
3806 border-bottom: 1px solid var(--border);
3807 background: var(--paper, #fff);
3808 user-select: none;
3809 touch-action: pan-x;
3810}
3811.pl-track-row:last-child { border-bottom: none; }
3812.pl-track-row.is-dragging {
3813 opacity: .55;
3814 transform: scale(.98);
3815 background: color-mix(in srgb, var(--accent, #5a8a5a) 10%, transparent);
3816 border-radius: 6px;
3817}
3818.pl-track-row.drop-target-above {
3819 box-shadow: inset 0 2px 0 0 var(--accent, #5a8a5a);
3820}
3821.pl-track-row.drop-target-below {
3822 box-shadow: inset 0 -2px 0 0 var(--accent, #5a8a5a);
3823}
3824.pl-track-handle {
3825 cursor: grab;
3826 font-size: 1.2rem;
3827 line-height: 1;
3828 color: var(--fg-muted, #666);
3829 display: flex;
3830 align-items: center;
3831 justify-content: center;
3832 height: 32px;
3833 width: 32px;
3834 border-radius: 4px;
3835 flex-shrink: 0;
3836}
3837.pl-track-handle:active { cursor: grabbing; }
3838.pl-track-handle:hover {
3839 background: color-mix(in srgb, var(--ink, #000) 8%, transparent);
3840}
3841.pl-track-num {
3842 text-align: center;
3843 color: var(--fg-muted, #666);
3844 font-size: .85rem;
3845 width: 36px;
3846}
3847.pl-track-info {
3848 min-width: 0;
3849 overflow: hidden;
3850}
3851.pl-track-title {
3852 font-weight: 500;
3853 overflow: hidden;
3854 text-overflow: ellipsis;
3855 white-space: nowrap;
3856}
3857.pl-track-artist {
3858 font-size: .78rem;
3859 color: var(--fg-muted, #666);
3860 overflow: hidden;
3861 text-overflow: ellipsis;
3862 white-space: nowrap;
3863}
3864.pl-track-remove {
3865 background: transparent;
3866 border: none;
3867 cursor: pointer;
3868 padding: .35rem;
3869 border-radius: 4px;
3870 color: var(--fg-muted, #666);
3871 font-size: 1.2rem;
3872 line-height: 1;
3873}
3874.pl-track-remove:hover {
3875 background: color-mix(in srgb, #c00 12%, transparent);
3876 color: #c00;
3877}
3878
3879/* Available tracks panel */
3880.pl-tracks-available-panel {
3881 border: 1px solid var(--border);
3882 border-radius: var(--radius);
3883 background: var(--paper, #fff);
3884}
3885.pl-tracks-available-search {
3886 padding: .5rem;
3887 border-bottom: 1px solid var(--border);
3888}
3889.pl-tracks-available-search input {
3890 width: 100%;
3891 box-sizing: border-box;
3892}
3893.pl-tracks-available-list {
3894 max-height: 30vh;
3895 overflow-y: auto;
3896}
3897.pl-track-row-available {
3898 display: grid;
3899 grid-template-columns: 1fr auto;
3900 gap: .5rem;
3901 align-items: center;
3902 padding: .5rem;
3903 border-bottom: 1px solid var(--border);
3904 cursor: pointer;
3905}
3906.pl-track-row-available:last-child { border-bottom: none; }
3907.pl-track-row-available:hover {
3908 background: color-mix(in srgb, var(--accent, #5a8a5a) 8%, transparent);
3909}
3910.pl-track-row-available.is-already-added {
3911 opacity: .4;
3912 pointer-events: none;
3913}
3914.pl-track-add-btn {
3915 background: transparent;
3916 border: 1px solid var(--border);
3917 border-radius: 4px;
3918 padding: .25rem .5rem;
3919 cursor: pointer;
3920 font-size: .85rem;
3921 color: var(--accent, #5a8a5a);
3922}
3923
3924/* v9.3 — Tracklist items zijn nu klikbare <button class="pat-row"> binnen <li>.
3925 De LI is puur een container zonder visuele styling; alles gebeurt op de button. */
3926.post-album-track-compact {
3927 padding: 0;
3928 margin: 0;
3929 border-bottom: 1px solid var(--rule);
3930 list-style: none;
3931}
3932.post-album-track-compact:last-child { border-bottom: none; }
3933
3934.pat-row {
3935 display: grid;
3936 grid-template-columns: 32px 1fr auto;
3937 gap: .65rem;
3938 align-items: center;
3939 width: 100%;
3940 padding: .5rem .85rem;
3941 background: transparent;
3942 border: none;
3943 color: inherit;
3944 font: inherit;
3945 font-size: .82rem;
3946 text-align: left;
3947 cursor: pointer;
3948 position: relative;
3949 transition: background .15s ease;
3950}
3951.pat-row:hover {
3952 background: color-mix(in srgb, var(--ink, #000) 6%, transparent);
3953}
3954.pat-row:active { transform: scale(.995); }
3955[data-theme="dark"] .pat-row:hover {
3956 background: color-mix(in srgb, var(--paper, #fff) 10%, transparent);
3957}
3958
3959/* Leader: track-nummer OF cover-thumb (afhankelijk van kind).
3960 v9.3 — pat-leader is altijd 32×32, met overgang voor spinner-vervanging. */
3961.pat-row .pat-num,
3962.pat-row .pat-cover {
3963 width: 32px;
3964 height: 32px;
3965 border-radius: 4px;
3966 flex-shrink: 0;
3967 transition: opacity .25s ease, transform .25s ease;
3968}
3969.pat-row .pat-num {
3970 font-family: ui-monospace, monospace;
3971 font-size: .8rem;
3972 opacity: .5;
3973 display: flex;
3974 align-items: center;
3975 justify-content: center;
3976}
3977.pat-row .pat-cover {
3978 background-size: cover;
3979 background-position: center;
3980 background-color: color-mix(in srgb, var(--ink, #000) 8%, transparent);
3981}
3982
3983/* v9.3 — Loading-spiraal als overlay op de leader-kolom.
3984 pat-num/pat-cover faden uit, spinner faded in via ::before. */
3985.pat-row::before {
3986 content: "";
3987 position: absolute;
3988 left: .85rem; top: 50%;
3989 width: 32px; height: 32px;
3990 transform: translateY(-50%);
3991 color: var(--accent, #c2410c);
3992 background-color: currentColor;
3993 -webkit-mask: url('/assets/spinner.svg') center/26px 26px no-repeat;
3994 mask: url('/assets/spinner.svg') center/26px 26px no-repeat;
3995 opacity: 0;
3996 transition: opacity .25s ease;
3997 pointer-events: none;
3998 animation: pat-spinner-rotate 1.2s linear infinite;
3999 animation-play-state: paused;
4000}
4001.pat-row.is-loading::before {
4002 opacity: 1;
4003 animation-play-state: running;
4004}
4005.pat-row.is-loading .pat-num,
4006.pat-row.is-loading .pat-cover {
4007 opacity: 0;
4008 transform: scale(.85);
4009}
4010@keyframes pat-spinner-rotate {
4011 from { transform: translateY(-50%) rotate(0deg); }
4012 to { transform: translateY(-50%) rotate(-360deg); }
4013}
4014
4015/* Meta-kolom */
4016.pat-row .pat-meta {
4017 display: flex;
4018 flex-direction: column;
4019 min-width: 0;
4020 gap: 1px;
4021 overflow: hidden;
4022}
4023.pat-row .pat-title {
4024 font-weight: 500;
4025 overflow: hidden;
4026 text-overflow: ellipsis;
4027 white-space: nowrap;
4028}
4029.pat-row .pat-artist {
4030 font-size: .72rem;
4031 opacity: .6;
4032 overflow: hidden;
4033 text-overflow: ellipsis;
4034 white-space: nowrap;
4035}
4036.pat-row .pat-duration {
4037 font-family: ui-monospace, monospace;
4038 font-size: .72rem;
4039 opacity: .55;
4040 font-variant-numeric: tabular-nums;
4041 white-space: nowrap;
4042}
4043.pat-row .pat-duration-empty {
4044 opacity: .25;
4045}
4046
4047/* is-current — actieve track in de player */
4048.pat-row.is-current {
4049 background: color-mix(in srgb, var(--accent, #c2410c) 12%, transparent);
4050}
4051.pat-row.is-current .pat-title,
4052.pat-row.is-current .pat-artist { color: var(--accent, #c2410c); }
4053
4054/* v9.3 — Marquee bij actief afspelen: titel scrollt heen-en-weer.
4055 --pat-shift wordt door JS gezet (= overflow in pixels). Bij 0 → geen
4056 beweging want translateX(0) blijft 0.
4057 Snelle cyclus (6s) met korte rust aan beide uiteinden (8%) zodat 't
4058 vlot voelt zonder onleesbaar te zijn. */
4059.pat-row.is-current.is-playing .pat-title {
4060 animation: pat-title-marquee 6s ease-in-out infinite alternate;
4061 text-overflow: clip;
4062 overflow: visible;
4063 will-change: transform;
4064}
4065@keyframes pat-title-marquee {
4066 0%, 8% { transform: translateX(0); }
4067 92%, 100% { transform: translateX(calc(-1 * var(--pat-shift, 0px))); }
4068}
4069
4070/* ============================================================
4071 v9.0 — CSS-migratie voor OUDE opgeslagen albums
4072 Oude posts hebben <li class="post-audio-track"> met play-knoppen + cover-spans.
4073 We renderen die VISUEEL als compact, zonder de HTML aan te passen.
4074 ============================================================ */
4075.post-album-tracks .post-audio-track {
4076 display: grid;
4077 grid-template-columns: 28px 1fr auto;
4078 gap: .75rem;
4079 align-items: center;
4080 padding: .5rem .85rem;
4081 margin: 0;
4082 border: none;
4083 border-bottom: 1px solid var(--rule);
4084 background: transparent;
4085 border-radius: 0;
4086 cursor: default;
4087 font-size: .92rem;
4088}
4089.post-album-tracks .post-audio-track:last-child { border-bottom: none; }
4090/* Verberg de cover-thumb en play-button in OUDE saved posts */
4091.post-album-tracks .post-audio-track .pat-cover,
4092.post-album-tracks .post-audio-track .pat-play {
4093 display: none !important;
4094}
4095.post-album-tracks .post-audio-track .pat-num {
4096 font-family: ui-monospace, monospace;
4097 font-size: .8rem;
4098 opacity: .45;
4099 text-align: center;
4100 width: auto;
4101}
4102.post-album-tracks .post-audio-track .pat-meta {
4103 display: flex;
4104 flex-direction: column;
4105 min-width: 0;
4106 gap: 1px;
4107}
4108.post-album-tracks .post-audio-track .pat-title {
4109 font-weight: 500;
4110 overflow: hidden;
4111 text-overflow: ellipsis;
4112 white-space: nowrap;
4113}
4114.post-album-tracks .post-audio-track .pat-artist {
4115 font-size: .78rem;
4116 opacity: .6;
4117}
4118.post-album-tracks .post-audio-track .pat-duration {
4119 font-family: ui-monospace, monospace;
4120 font-size: .78rem;
4121 opacity: .55;
4122}
4123.post-album-tracks .post-audio-track.is-current {
4124 background: color-mix(in srgb, var(--accent, #c2410c) 10%, transparent);
4125}
4126.post-album-tracks .post-audio-track.is-current .pat-num,
4127.post-album-tracks .post-audio-track.is-current .pat-title {
4128 color: var(--accent);
4129}
4130
4131@media (max-width: 540px) {
4132 .post-album-header { flex-direction: column; }
4133 .post-album-cover-btn .post-album-cover { width: 100%; max-width: 240px; height: auto; aspect-ratio: 1/1; }
4134}
4135@media (max-width: 380px) {
4136 .post-album-header { padding: .75rem; gap: .75rem; }
4137 .post-album-cover-btn .post-album-cover { max-width: 180px; }
4138 .post-album-title { font-size: 1.15rem; }
4139 .post-album-meta { font-size: .8rem; }
4140 .post-album-track-compact,
4141 .post-album-tracks .post-audio-track {
4142 grid-template-columns: 24px 1fr auto;
4143 gap: .5rem;
4144 padding: .4rem .6rem;
4145 font-size: .85rem;
4146 }
4147 .post-album-track-compact .pat-duration,
4148 .post-album-tracks .post-audio-track .pat-duration {
4149 font-size: .72rem;
4150 }
4151 /* Queue items in expand-sheet */
4152 .audio-sheet-queue-item { padding: .4rem .45rem; gap: .55rem; }
4153 .audio-sheet-queue-cover { width: 32px; height: 32px; }
4154 .audio-sheet-queue-title { font-size: .85rem; }
4155 .audio-sheet-queue-artist { font-size: .7rem; }
4156}
4157
4158/* External track (SoundCloud / YouTube / Spotify / etc) — klikbaar maar link-naar-platform */
4159.post-audio-external {
4160 display: flex;
4161 align-items: center;
4162 gap: .75rem;
4163 padding: .65rem .85rem;
4164 background: var(--paper-2, color-mix(in srgb, var(--ink) 4%, transparent));
4165 border: 1px solid var(--rule, rgba(0,0,0,.08));
4166 border-radius: 10px;
4167 margin: .75rem 0;
4168 text-decoration: none;
4169 color: var(--ink);
4170 transition: background .15s, border-color .15s;
4171}
4172.post-audio-external:hover {
4173 border-color: var(--accent);
4174 background: color-mix(in srgb, var(--accent) 5%, var(--paper-2, transparent));
4175}
4176.post-audio-external .pae-icon {
4177 flex-shrink: 0;
4178 width: 42px;
4179 height: 42px;
4180 border-radius: 8px;
4181 display: inline-flex;
4182 align-items: center;
4183 justify-content: center;
4184 background: var(--platform-color, #555);
4185 color: #fff;
4186 font-size: 1.2rem;
4187}
4188.post-audio-external .pae-icon-svg svg {
4189 width: 60%;
4190 height: 60%;
4191 fill: currentColor;
4192}
4193/* Per-platform vult de box net wat anders — brand-specifiek geoptimaliseerd */
4194.post-audio-external[data-platform="soundcloud"] .pae-icon-svg svg { width: 72%; height: auto; }
4195.post-audio-external[data-platform="spotify"] .pae-icon-svg svg { width: 72%; height: 72%; }
4196.post-audio-external[data-platform="youtube"] .pae-icon-svg svg { width: 68%; height: auto; }
4197.post-audio-external[data-platform="bandcamp"] .pae-icon-svg svg { width: 62%; height: auto; }
4198.post-audio-external[data-platform="apple"] .pae-icon-svg svg { width: 58%; height: 58%; }
4199.post-audio-external[data-platform="tidal"] .pae-icon-svg svg { width: 68%; height: auto; }
4200.post-audio-external[data-platform="deezer"] .pae-icon-svg svg { width: 65%; height: auto; }
4201.post-audio-external[data-platform="mixcloud"] .pae-icon-svg svg { width: 75%; height: auto; }
4202.post-audio-external[data-platform="soundcloud"] .pae-icon { background: #ff5500; }
4203.post-audio-external[data-platform="spotify"] .pae-icon { background: #1db954; }
4204.post-audio-external[data-platform="youtube"] .pae-icon { background: #ff0000; }
4205.post-audio-external[data-platform="bandcamp"] .pae-icon { background: #1da0c3; }
4206.post-audio-external[data-platform="apple"] .pae-icon { background: #fa243c; }
4207.post-audio-external[data-platform="tidal"] .pae-icon { background: #000; }
4208.post-audio-external[data-platform="deezer"] .pae-icon { background: #a238ff; }
4209.post-audio-external[data-platform="mixcloud"] .pae-icon { background: #314359; }
4210.post-audio-external[data-platform="other"] .pae-icon { background: #555; }
4211.post-audio-external .pae-meta {
4212 flex: 1;
4213 min-width: 0;
4214 display: flex;
4215 flex-direction: column;
4216 gap: 2px;
4217}
4218.post-audio-external .pae-title {
4219 display: block;
4220 font-weight: 600;
4221 overflow: hidden;
4222 text-overflow: ellipsis;
4223 white-space: nowrap;
4224 color: var(--ink);
4225}
4226.post-audio-external .pae-platform {
4227 display: block;
4228 font-size: .78rem;
4229 opacity: .65;
4230 text-transform: capitalize;
4231}
4232.post-audio-external .pae-go {
4233 flex-shrink: 0;
4234 opacity: .5;
4235 font-size: 1.1rem;
4236}
4237
4238/* =========================================================================
4239 v9.0 — Video player (inline)
4240 ========================================================================= */
4241
4242.post-video-figure {
4243 margin: 1.25rem 0;
4244 max-width: 100%;
4245}
4246
4247.post-video {
4248 display: block;
4249 width: 100%;
4250 max-width: 100%;
4251 height: auto;
4252 border-radius: 10px;
4253 background: #000;
4254 box-shadow: 0 4px 20px rgba(0,0,0,.15);
4255}
4256
4257.post-video-caption {
4258 margin-top: .5rem;
4259 font-size: .88rem;
4260 color: var(--ink-muted, color-mix(in srgb, var(--ink) 60%, transparent));
4261 text-align: center;
4262 line-height: 1.5;
4263}
4264
4265.post-video-caption strong {
4266 display: inline;
4267 font-weight: 600;
4268 color: var(--ink);
4269}
4270
4271@media (max-width: 640px) {
4272 .post-video-figure { margin: .75rem -.5rem; }
4273 .post-video { border-radius: 6px; }
4274}
4275
4276/* v9.3 — Floating "Bewerken" knop voor album-blokken in de post-editor.
4277 Verschijnt bij hover over een .post-album binnen #visual en wordt via JS
4278 geplaatst op de rechterbovenhoek van het blok. Niet in de opgeslagen HTML. */
4279.pcms-album-edit-overlay {
4280 position: absolute;
4281 z-index: 1000;
4282 transform: translateX(-100%);
4283 display: inline-flex;
4284 align-items: center;
4285 gap: .35rem;
4286 padding: .35rem .7rem;
4287 background: var(--accent, #c2410c);
4288 color: #fff;
4289 border: none;
4290 border-radius: 6px;
4291 font-size: .82rem;
4292 font-weight: 600;
4293 cursor: pointer;
4294 box-shadow: 0 4px 12px rgba(0, 0, 0, .18);
4295 transition: transform .12s ease, box-shadow .12s ease;
4296}
4297.pcms-album-edit-overlay:hover {
4298 transform: translateX(-100%) translateY(-1px);
4299 box-shadow: 0 6px 16px rgba(0, 0, 0, .24);
4300}
4301.pcms-album-edit-overlay:active {
4302 transform: translateX(-100%) translateY(0);
4303 box-shadow: 0 2px 6px rgba(0, 0, 0, .18);
4304}
4305
4306/* v9.3 — Drag-and-drop in de album-builder selected-lijst */
4307.ab-selected-row { cursor: default; }
4308.ab-selected-row .ab-drag-handle {
4309 display: inline-flex;
4310 align-items: center;
4311 justify-content: center;
4312 width: 18px;
4313 height: 100%;
4314 color: color-mix(in srgb, currentColor 40%, transparent);
4315 cursor: grab;
4316 user-select: none;
4317 font-size: .9rem;
4318 letter-spacing: -2px;
4319 flex-shrink: 0;
4320}
4321.ab-selected-row:hover .ab-drag-handle {
4322 color: color-mix(in srgb, currentColor 70%, transparent);
4323}
4324.ab-selected-row.is-dragging {
4325 opacity: .35;
4326 cursor: grabbing;
4327}
4328.ab-selected-row.is-dragging .ab-drag-handle { cursor: grabbing; }
4329/* Drop-indicator lijnen boven/onder de target rij */
4330.ab-selected-row.is-drag-target-before {
4331 box-shadow: 0 -2px 0 0 var(--accent, #c2410c) inset, 0 2px 0 0 var(--accent, #c2410c);
4332 /* Gebruik outline voor cross-browser zichtbaarheid */
4333 position: relative;
4334}
4335.ab-selected-row.is-drag-target-before::before {
4336 content: "";
4337 position: absolute;
4338 top: -1px; left: 0; right: 0;
4339 height: 2px;
4340 background: var(--accent, #c2410c);
4341 pointer-events: none;
4342}
4343.ab-selected-row.is-drag-target-after::after {
4344 content: "";
4345 position: absolute;
4346 bottom: -1px; left: 0; right: 0;
4347 height: 2px;
4348 background: var(--accent, #c2410c);
4349 pointer-events: none;
4350}
4351.ab-selected-row.is-drag-target-after { position: relative; }
4352
4353/* v9.3 — Playlist fallback states (missing of empty playlist reference in post) */
4354.post-playlist-missing, .post-playlist-empty {
4355 padding: 1rem;
4356 margin: .75rem 0;
4357 background: color-mix(in srgb, var(--accent, #c2410c) 8%, transparent);
4358 border: 1px dashed color-mix(in srgb, var(--accent, #c2410c) 30%, transparent);
4359 border-radius: 8px;
4360 font-size: .9rem;
4361}
4362.post-playlist-missing em, .post-playlist-empty em {
4363 opacity: .8;
4364}
4365
4366/* v9.3 — Install-app footer-knop */
4367.site-footer-install {
4368 display: flex;
4369 justify-content: center;
4370 padding: 1rem 1rem 1.25rem;
4371 border-top: 1px solid color-mix(in srgb, currentColor 8%, transparent);
4372 margin-top: .5rem;
4373}
4374
4375/* v9.4 — Cooler install-knop: gradient + shimmer + perfect centering.
4376 Twee kleur-stops voor diepte, animated shimmer-streep om aandacht te trekken,
4377 icon perfect verticaal gecentreerd via flex (was: net iets te hoog tov tekst). */
4378.install-app-btn {
4379 position: relative;
4380 display: inline-flex;
4381 align-items: center;
4382 justify-content: center;
4383 gap: .55rem;
4384 padding: .8rem 1.6rem;
4385 background: linear-gradient(135deg,
4386 var(--accent, #c2410c),
4387 color-mix(in srgb, var(--accent, #c2410c) 80%, #000));
4388 color: #fff;
4389 border: none;
4390 border-radius: 999px;
4391 font: inherit;
4392 font-weight: 600;
4393 font-size: .95rem;
4394 line-height: 1;
4395 letter-spacing: .01em;
4396 cursor: pointer;
4397 overflow: hidden;
4398 isolation: isolate;
4399 box-shadow:
4400 0 1px 0 rgba(255,255,255,.15) inset,
4401 0 -2px 0 rgba(0,0,0,.1) inset,
4402 0 4px 14px color-mix(in srgb, var(--accent, #c2410c) 40%, transparent),
4403 0 1px 3px rgba(0,0,0,.18);
4404 transition:
4405 transform .15s cubic-bezier(.4, 0, .2, 1),
4406 box-shadow .2s ease,
4407 filter .15s ease;
4408}
4409.install-app-btn svg {
4410 flex-shrink: 0;
4411 /* subtle bounce-on-hover trigger, separate animation */
4412 transition: transform .25s cubic-bezier(.34, 1.56, .64, 1);
4413}
4414.install-app-btn span {
4415 line-height: 1;
4416}
4417
4418/* Shimmer-streep die langzaam over de knop loopt — "alive" effect */
4419.install-app-btn::before {
4420 content: "";
4421 position: absolute;
4422 top: 0;
4423 left: -100%;
4424 width: 60%;
4425 height: 100%;
4426 background: linear-gradient(110deg,
4427 transparent 30%,
4428 rgba(255,255,255,.25) 50%,
4429 transparent 70%);
4430 z-index: -1;
4431 animation: pcmsInstallShimmer 4s ease-in-out infinite;
4432 pointer-events: none;
4433}
4434@keyframes pcmsInstallShimmer {
4435 0%, 35% { left: -100%; }
4436 65%, 100% { left: 200%; }
4437}
4438
4439.install-app-btn:hover {
4440 transform: translateY(-2px) scale(1.02);
4441 filter: brightness(1.06);
4442 box-shadow:
4443 0 1px 0 rgba(255,255,255,.2) inset,
4444 0 -2px 0 rgba(0,0,0,.1) inset,
4445 0 8px 24px color-mix(in srgb, var(--accent, #c2410c) 55%, transparent),
4446 0 2px 6px rgba(0,0,0,.2);
4447}
4448.install-app-btn:hover svg {
4449 transform: translateY(-2px);
4450}
4451.install-app-btn:active {
4452 transform: translateY(0) scale(.98);
4453 transition-duration: .05s;
4454}
4455.install-app-btn:focus-visible {
4456 outline: 2px solid var(--accent, #c2410c);
4457 outline-offset: 3px;
4458}
4459
4460/* Reduced motion: shimmer uit, alleen statisch */
4461@media (prefers-reduced-motion: reduce) {
4462 .install-app-btn::before { animation: none; left: -100%; }
4463 .install-app-btn:hover { transform: none; }
4464 .install-app-btn:hover svg { transform: none; }
4465}
4466
4467/* Install-instructions modal */
4468.install-modal {
4469 position: fixed;
4470 inset: 0;
4471 z-index: 10000;
4472 display: flex;
4473 align-items: center;
4474 justify-content: center;
4475 padding: 1rem;
4476}
4477.install-modal-backdrop {
4478 position: absolute;
4479 inset: 0;
4480 background: rgba(0,0,0,.55);
4481 backdrop-filter: blur(3px);
4482}
4483.install-modal-panel {
4484 position: relative;
4485 z-index: 1;
4486 background: var(--paper);
4487 color: var(--ink);
4488 border: 1px solid var(--rule);
4489 border-radius: 14px;
4490 padding: 1.5rem;
4491 max-width: 440px;
4492 width: 100%;
4493 max-height: 90vh;
4494 overflow-y: auto;
4495 box-shadow: 0 20px 60px rgba(0,0,0,.4);
4496}
4497.install-modal-panel h3 { font-size: 1.15rem; color: var(--ink); }
4498.install-modal-panel h4 {
4499 margin: 1rem 0 .4rem;
4500 font-size: .92rem;
4501 letter-spacing: .03em;
4502 text-transform: uppercase;
4503 opacity: .7;
4504 color: var(--ink);
4505}
4506.install-modal-panel p { color: var(--ink); }
4507.install-steps {
4508 margin: 0;
4509 padding-left: 1.35rem;
4510 display: flex;
4511 flex-direction: column;
4512 gap: .45rem;
4513 font-size: .95rem;
4514 line-height: 1.45;
4515 color: var(--ink);
4516}
4517.install-steps li::marker { color: var(--accent); font-weight: 700; }
4518.install-apk-block {
4519 margin-top: 1.25rem;
4520 padding-top: 1rem;
4521 border-top: 1px dashed var(--rule);
4522}
4523.install-apk-link {
4524 display: inline-flex;
4525 align-items: center;
4526 margin-top: .4rem;
4527 padding: .6rem 1rem;
4528 background: var(--accent);
4529 color: #fff;
4530 border-radius: 8px;
4531 text-decoration: none;
4532 font-weight: 600;
4533}
4534.install-apk-link:hover { filter: brightness(1.08); }
4535.install-modal-actions {
4536 display: flex;
4537 justify-content: flex-end;
4538 margin-top: 1.25rem;
4539}
4540.install-modal-actions .btn {
4541 padding: .5rem 1rem;
4542 background: var(--paper-2);
4543 border: 1px solid var(--rule);
4544 border-radius: 8px;
4545 color: var(--ink);
4546 cursor: pointer;
4547 font: inherit;
4548 font-weight: 500;
4549}
4550.install-modal-actions .btn:hover {
4551 background: color-mix(in srgb, var(--accent) 10%, var(--paper-2));
4552 border-color: var(--accent);
4553 color: var(--accent);
4554}
4555
4556@media (max-width: 520px) {
4557 .install-modal-panel { padding: 1.2rem; }
4558 .install-app-btn { width: 100%; justify-content: center; }
4559}
4560
4561/* v9.3 — Install-modal: choice-blocks met voor/nadelen */
4562.install-choice {
4563 margin-top: 1.25rem;
4564 padding: 1rem;
4565 border: 1px solid color-mix(in srgb, currentColor 15%, transparent);
4566 border-radius: 10px;
4567 background: color-mix(in srgb, currentColor 3%, transparent);
4568}
4569.install-choice + .install-choice { margin-top: 1rem; }
4570.install-choice h4 {
4571 margin: 0 0 .75rem;
4572 font-size: 1rem;
4573 letter-spacing: 0;
4574 text-transform: none;
4575 opacity: 1;
4576}
4577.install-pros-cons {
4578 display: flex;
4579 gap: 1rem;
4580 margin: .5rem 0 1rem;
4581}
4582.install-pros,
4583.install-cons {
4584 flex: 1;
4585 min-width: 0;
4586 font-size: .85rem;
4587 line-height: 1.45;
4588}
4589.install-pros strong,
4590.install-cons strong {
4591 display: block;
4592 margin-bottom: .35rem;
4593 font-size: .82rem;
4594 letter-spacing: .02em;
4595}
4596.install-pros strong { color: #16a34a; }
4597.install-cons strong { color: #dc2626; }
4598.install-pros ul,
4599.install-cons ul {
4600 margin: 0;
4601 padding-left: 1.1rem;
4602 display: flex;
4603 flex-direction: column;
4604 gap: .25rem;
4605}
4606.install-pros li::marker { color: #16a34a; }
4607.install-cons li::marker { color: #dc2626; }
4608
4609.install-choice-cta {
4610 display: inline-flex;
4611 align-items: center;
4612 justify-content: center;
4613 gap: .35rem;
4614 margin-top: .5rem;
4615 padding: .7rem 1.1rem;
4616 background: var(--accent, #c2410c);
4617 color: #fff;
4618 border: none;
4619 border-radius: 8px;
4620 text-decoration: none;
4621 font: inherit;
4622 font-weight: 600;
4623 font-size: .95rem;
4624 cursor: pointer;
4625 transition: filter .12s ease;
4626}
4627.install-choice-cta:hover { filter: brightness(1.08); }
4628.install-choice-note {
4629 margin: .5rem 0 0;
4630 padding: .6rem .8rem;
4631 background: color-mix(in srgb, currentColor 4%, transparent);
4632 border-left: 3px solid var(--accent, #c2410c);
4633 border-radius: 4px;
4634 font-size: .9rem;
4635 line-height: 1.45;
4636}
4637
4638@media (max-width: 520px) {
4639 .install-pros-cons { flex-direction: column; gap: .75rem; }
4640}
4641
4642/* v9.4 — Soft fade-overgang tussen posts bij navigatie.
4643 Fade-out is rustig (450ms): oude content vervaagt geleidelijk terwijl
4644 de scroll-naar-top loopt. Fade-in is snel (180ms) met een lichte blur-
4645 onscherp → scherp animatie zodat de nieuwe content niet abrupt verschijnt. */
4646#pcms-main {
4647 transition: opacity .45s ease-out;
4648}
4649#pcms-main.is-pcms-transitioning-out {
4650 opacity: 0;
4651}
4652#pcms-main.is-pcms-transitioning-in {
4653 opacity: 0;
4654 filter: blur(6px);
4655 animation: pcmsFadeIn .18s ease-out forwards;
4656 will-change: opacity, filter;
4657}
4658@keyframes pcmsFadeIn {
4659 from { opacity: 0; filter: blur(6px); }
4660 to { opacity: 1; filter: blur(0); }
4661}
4662
4663/* Respecteer reduced-motion voorkeur (iOS/Android accessibility setting) */
4664@media (prefers-reduced-motion: reduce) {
4665 #pcms-main {
4666 transition: opacity .15s ease-out;
4667 }
4668 #pcms-main.is-pcms-transitioning-in {
4669 filter: none;
4670 animation: none;
4671 opacity: 1;
4672 }
4673}
4674
4675/* === Fediverse interactions — inherits the native .comment styling === */
4676.post-fediverse .fedi-stats { display: flex; gap: .45rem; margin: .35rem 0 1.5rem; align-items: center; }
4677.post-fediverse .fedi-stat {
4678 display: inline-flex; align-items: center; gap: .4rem;
4679 padding: .32rem .7rem; border-radius: 999px; font-size: .85rem; line-height: 1;
4680 font-variant-numeric: tabular-nums;
4681 color: var(--ink-muted); background: transparent;
4682 border: 1px solid var(--rule);
4683}
4684.post-fediverse .fedi-stat svg { width: 15px; height: 15px; }
4685.post-fediverse .fedi-stat-btn { cursor: pointer; font: inherit; line-height: 1; transition: color .15s, border-color .15s, background .15s; }
4686.post-fediverse .fedi-stat-btn:hover { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 55%, var(--rule)); background: var(--accent-tint); }
4687.post-fediverse .fedi-stat-btn:hover svg { fill: color-mix(in srgb, var(--accent) 22%, transparent); }
4688.post-fediverse .fedi-handle { color: var(--ink-soft, #888); font-size: .82rem; }
4689.post-fediverse .comment-content p { margin: .2rem 0; }
4690.post-fediverse .comment-content p:first-child { margin-top: 0; }
4691.post-fediverse .comment-content p:last-child { margin-bottom: 0; }
4692/* reply toggle: a plain "Reageer" action like the comment buttons (no triangle) */
4693.post-fediverse .fedi-reply-toggle { list-style: none; cursor: pointer; display: inline-block; }
4694.post-fediverse .fedi-reply-toggle::-webkit-details-marker { display: none; }
4695.post-fediverse details[open] .fedi-reply-toggle { margin-bottom: .5rem; }
4696
4697/* Reply-via-fediverse CTA on post pages */
4698.post-fediverse-cta { margin: 1.75rem 0; }
4699.fedi-remote-reply-btn { display: inline-flex; align-items: center; gap: .45rem; }
4700.post-fediverse-cta .fedi-remote-reply-btn {
4701 border: 1px solid color-mix(in srgb, var(--accent, #888) 55%, transparent);
4702 background: color-mix(in srgb, var(--accent, #888) 10%, transparent);
4703 color: var(--ink, inherit); border-radius: 999px; padding: .5rem 1.05rem;
4704 font-weight: 600; cursor: pointer; transition: background .15s ease;
4705}
4706.post-fediverse-cta .fedi-remote-reply-btn:hover { background: color-mix(in srgb, var(--accent, #888) 22%, transparent); }
4707.post-fediverse-cta .fedi-remote-reply-btn svg { color: var(--accent, currentColor); }
4708.post-fediverse .comment-actions .fedi-remote-reply-btn { gap: .3rem; }
4709
4710/* Inline "reply via fediverse" address form (replaces the browser prompt) */
4711.fedi-remote-form {
4712 position: absolute; z-index: 60; display: inline-flex; align-items: center; gap: .4rem;
4713 padding: .4rem; border-radius: 999px;
4714 background: var(--paper-2, var(--paper, #fff));
4715 border: 1px solid color-mix(in srgb, var(--ink, #000) 12%, transparent);
4716 box-shadow: 0 10px 30px rgba(0,0,0,.28);
4717}
4718.fedi-remote-form input {
4719 height: 2.2rem; padding: 0 .9rem; border-radius: 999px; font: inherit; min-width: 230px;
4720 border: 1px solid color-mix(in srgb, var(--ink, #000) 18%, transparent);
4721 background: color-mix(in srgb, var(--ink, #000) 4%, transparent); color: var(--ink, #000);
4722}
4723.fedi-remote-form input::placeholder { color: var(--ink-soft, #999); }
4724.fedi-remote-form input:focus { outline: none; border-color: color-mix(in srgb, var(--accent, #888) 70%, transparent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent, #888) 22%, transparent); }
4725.fedi-remote-form .fedi-remote-go {
4726 height: 2.2rem; min-width: 2.2rem; padding: 0 .85rem; border-radius: 999px;
4727 display: inline-flex; align-items: center; justify-content: center; font-size: 1rem;
4728}
4729.fedi-remote-form .fedi-remote-cancel { background: none; border: none; color: var(--ink-soft, #888); cursor: pointer; font-size: 1.1rem; line-height: 1; padding: .25rem .35rem; }
4730.fedi-remote-form .fedi-remote-cancel:hover { color: var(--ink, #000); }
4731
4732/* ── NSFW / sensitive content — blur + click to reveal ───────────────── */
4733.nsfw-media { position: relative; }
4734.nsfw-veil {
4735 position: absolute; inset: 0; z-index: 4; cursor: pointer; border-radius: inherit;
4736 display: flex; flex-direction: column; align-items: center; justify-content: center;
4737 gap: .5rem; padding: .75rem; text-align: center;
4738 background: color-mix(in srgb, var(--paper, #14141a) 50%, transparent);
4739 backdrop-filter: blur(22px) saturate(.6); -webkit-backdrop-filter: blur(22px) saturate(.6);
4740}
4741.nsfw-media.is-shown > .nsfw-veil { display: none; }
4742.nsfw-veil-label { font-weight: 700; font-size: .82rem; color: var(--ink, #f3f1ea); text-shadow: 0 1px 2px rgba(0,0,0,.5); }
4743.nsfw-veil-btn {
4744 font-size: .72rem; font-weight: 600; padding: .3rem .8rem; border-radius: 999px;
4745 border: 1px solid color-mix(in srgb, var(--ink, #fff) 55%, transparent);
4746 background: color-mix(in srgb, var(--paper, #000) 35%, transparent); color: var(--ink, #f3f1ea);
4747}
4748/* Post page: blur cover + body behind a content-warning banner until revealed */
4749.nsfw-gate .post-cover,
4750.nsfw-gate .post-content { filter: blur(26px); pointer-events: none; user-select: none; transition: filter .2s ease; }
4751.nsfw-gate.is-shown .post-cover,
4752.nsfw-gate.is-shown .post-content { filter: none; pointer-events: auto; user-select: auto; }
4753.nsfw-banner {
4754 display: flex; align-items: center; gap: .7rem; flex-wrap: wrap; margin: 0 0 1.5rem;
4755 padding: .8rem 1rem; border-radius: 12px;
4756 border: 1px solid color-mix(in srgb, var(--accent, #e8b04b) 45%, transparent);
4757 background: color-mix(in srgb, var(--accent, #e8b04b) 9%, transparent);
4758}
4759.nsfw-gate.is-shown .nsfw-banner { display: none; }
4760.nsfw-banner-icon { font-size: 1.2rem; }
4761.nsfw-banner-text { font-weight: 600; font-size: .92rem; color: var(--ink); }
4762.nsfw-banner-btn {
4763 margin-left: auto; cursor: pointer; font: inherit; font-size: .82rem; font-weight: 600;
4764 padding: .4rem 1rem; border-radius: 999px; border: 0;
4765 background: var(--accent, #e8b04b); color: #1a1205;
4766}
Note: See TracBrowser for help on using the repository browser.