source: Klonkt/src/assets/css/style.css@ 598f090

main
Last change on this file since 598f090 was 598f090, checked in by Robin <roboburr@…>, 3 weeks ago

De cover in de leesweergave: niet opblazen, niet bijsnijden

Barts melding (20-8): het plaatje bij een post in Lezen mag netter, zoals
het in de tijdlijn was. Nagemeten in de browser op dev, twee gevallen:

geen-koffie-wel-thee 221x165 natuurlijk -> 505x378 getoond (2,28x)
strike-homerun 553x464 natuurlijk -> 505x400 getoond (bijgesneden)

Allebei kwamen ze uit width:100% met object-fit:cover. De kleine werd ruim
twee keer opgeblazen en dus wazig; de grote verloor zijn onderkant tegen
de hoogtegrens. De tijdlijn deed dat nooit -- daar zat een cover in een
vakje van 120px, dus klein bleef klein.

Nu: width/height auto met max-width en max-height, zodat de browser de
verhouding zelf houdt en het beeld HEEL in het vak past. De figure krimpt
eromheen (fit-content) en staat gecentreerd, in plaats van een klein
plaatje in een veel te grote lijst te zetten. Wit erachter voor logo's met
doorzichtige achtergrond, dezelfde keuze als .post-list-cover.

De hoogtegrens van 45svh blijft: die houdt titel en eerste alinea boven de
vouw. Zonder het bijsnijden krimpt een staande foto nu netjes mee in
plaats van dat er een stuk af gaat.

style.css naar v72 -- /assets staat buiten development op max-age=1y, dus
zonder bump krijgt wie hier eerder was de oude opmaak bij de nieuwe pagina.

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

  • Property mode set to 100644
File size: 155.3 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 /* Krimpt om het beeld heen en staat gecentreerd, in plaats van de kolom vol
2464 te trekken. Anders staat een klein plaatje in een veel te grote lijst. */
2465 width: fit-content;
2466 max-width: 100%;
2467 margin: 0 auto 1.2rem;
2468 border-radius: 10px;
2469 overflow: hidden;
2470}
2471.feed-reader .read-cover img,
2472.feed-reader .read-cover video {
2473 display: block;
2474 /* GEEN width:100%. Dat blies een cover van 221x165 op tot 505x378 -- ruim
2475 twee keer zo groot als hij is, en dus wazig. De tijdlijn deed dat nooit:
2476 daar zat een cover in een vakje van 120px, dus klein bleef klein. Met
2477 auto + max-width vult een grote afbeelding de kolom en blijft een kleine
2478 op ware grootte staan.
2479 En GEEN object-fit:cover: samen met de hoogtegrens sneed dat de onderkant
2480 eraf (553x464 kwam er als 505x400 uit). Met max-width en max-height houdt
2481 de browser de verhouding zelf en past het beeld HEEL in het vak. */
2482 width: auto;
2483 height: auto;
2484 max-width: 100%;
2485 max-height: 45svh;
2486 /* Een logo met doorzichtige achtergrond zweeft anders op de paginakleur;
2487 dezelfde keuze als bij .post-list-cover in de tijdlijn. */
2488 background-color: #fff;
2489}
2490
2491.feed-reader .read-head { padding-bottom: .5rem; }
2492.feed-reader .read-title { font-size: clamp(1.6rem, 4vw, 2.4rem); line-height: 1.15; margin: 0 0 .3rem; }
2493/* De titel is een link, maar mag er niet als een link uitzien: dit is een
2494 leesscherm, geen index. */
2495.feed-reader .read-title a { color: inherit; text-decoration: none; }
2496.feed-reader .read-title a:hover,
2497.feed-reader .read-title a:focus-visible { text-decoration: underline; }
2498.feed-reader .read-when { font-size: .85rem; opacity: .6; margin: 0; }
2499
2500.feed-reader .read-foot { margin-top: 2rem; }
2501.feed-reader .read-open {
2502 display: inline-block; font-size: .9rem; opacity: .75;
2503 text-decoration: none; border-bottom: 1px solid currentColor; padding-bottom: 1px;
2504}
2505.feed-reader .read-open:hover,
2506.feed-reader .read-open:focus-visible { opacity: 1; }
2507
2508@media (prefers-reduced-motion: reduce) {
2509 html:has(body.on-home[data-feed-view="reader"]) { scroll-snap-type: none; }
2510}
2511
2512/* -------- GRID VIEW TILES (Instagram-stijl) -------- */
2513.feed-grid {
2514 padding: 1rem 0 2rem;
2515}
2516.grid-tiles {
2517 display: grid;
2518 gap: 4px;
2519 grid-template-columns: repeat(2, 1fr);
2520}
2521.grid-tile {
2522 position: relative;
2523 display: block;
2524 aspect-ratio: 1;
2525 background-size: cover;
2526 background-position: center;
2527 background-color: var(--paper-2);
2528 overflow: hidden;
2529 text-decoration: none;
2530 color: var(--ink);
2531 transition: transform .2s;
2532 cursor: pointer;
2533 -webkit-tap-highlight-color: rgba(0,0,0,.1);
2534}
2535
2536/* Transparent covers (PNG logos etc.) sit on white so they don't blend into a dark
2537 theme. The white is on the IMG, so the tile's accent-gradient placeholder shows
2538 while the image is still loading. */
2539.post-cover img,
2540.post-list-cover img,
2541.grid-tile-img { background-color: #fff; }
2542/* Accent-gradient placeholder shown while the cover image loads (the image fades in
2543 over it), instead of a white flash on cover tiles. */
2544.grid-tile:not(.grid-tile-gradient) {
2545 background-image: linear-gradient(135deg,
2546 color-mix(in srgb, var(--accent, #888) 22%, var(--paper-2, var(--paper))) 0%,
2547 color-mix(in srgb, var(--accent, #888) 6%, var(--paper-2, var(--paper))) 100%);
2548}
2549/* Cover as a real <img> (not background-image): browsers downsample <img> with the
2550 high-quality image pipeline, so high-res line-art covers don't go jagged when shrunk.
2551 Fades in on load (.is-loading removed) so the placeholder shows meanwhile. */
2552.grid-tile-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: center; display: block; transition: opacity .4s ease; }
2553.grid-tile-img.is-loading { opacity: 0; }
2554/* Audio tile (Shaer, Robins vraag 30-7): the waveform PNG is white on
2555 transparent and floats OVER the tile's own hue gradient, so every audio
2556 post keeps its color and gets its shape. Wave and title each get their
2557 own band (wave upper, title lower): centering both stacked them right
2558 through each other (Robins schermafdruk). */
2559.grid-tile-img.grid-tile-wave {
2560 background-color: transparent;
2561 object-fit: contain;
2562 /* explicit box, not auto: an absolutely positioned img falls back to its
2563 intrinsic size when width/height are auto, collapsing the band */
2564 top: 8%; left: 8%; right: auto; bottom: auto;
2565 width: 84%; height: 46%;
2566 opacity: .85;
2567}
2568.grid-tile-audio .grid-tile-title { position: absolute; left: 10%; right: 10%; top: 60%; }
2569.grid-tile-audio .grid-tile-gradient-src { position: absolute; left: 10%; right: 10%; top: 76%; }
2570/* Cover videos are decorative, not players: let clicks + right-click pass through to the
2571 tile link so you get the normal link menu (not the browser's <video> menu/controls).
2572 Autoplay is independent of pointer-events, so the video still plays. */
2573video.grid-tile-img,
2574.post-list-cover video,
2575.post-cover video { pointer-events: none; }
2576.grid-tile:hover { transform: scale(0.98); }
2577.grid-tile-overlay {
2578 position: absolute;
2579 inset: 0;
2580 padding: .6rem;
2581 display: flex;
2582 flex-direction: column;
2583 justify-content: flex-end;
2584 align-items: flex-start;
2585 background: linear-gradient(to top, rgba(0,0,0,.65) 0%, rgba(0,0,0,0) 50%);
2586 opacity: 0;
2587 transition: opacity .2s;
2588 pointer-events: none; /* klik moet naar de <a> eronder gaan, niet naar de overlay */
2589}
2590/* Bron-site (cirkel-feed): toont bij hover "van <site>" onder de titel. */
2591/* Source label: small text that wraps to 2 lines if needed, with a big chain icon
2592 beside it (the text was 1.44rem — bigger than the title — and overflowed on mobile). */
2593.grid-tile-overlay-src {
2594 color: #fff; opacity: .85;
2595 font-size: .72rem; line-height: 1.2; margin-top: .25rem;
2596 display: flex; align-items: center; gap: .3rem; width: 100%;
2597}
2598.grid-tile-overlay-src::before { content: "⛓"; font-size: 1.3rem; line-height: 1; flex: 0 0 auto; }
2599.grid-tile-gradient-src {
2600 margin-top: .35rem; font-size: .72rem; line-height: 1.2; opacity: .85;
2601 color: var(--ink-soft);
2602 display: flex; align-items: center; gap: .3rem; width: 100%;
2603}
2604.grid-tile-gradient-src::before { content: "⛓"; font-size: 1.3rem; line-height: 1; flex: 0 0 auto; }
2605.grid-tile-overlay strong {
2606 color: #fff;
2607 font-family: var(--font-display);
2608 font-size: .9rem;
2609 font-weight: 500;
2610 line-height: 1.15;
2611 display: -webkit-box;
2612 -webkit-line-clamp: 3;
2613 -webkit-box-orient: vertical;
2614 overflow: hidden;
2615}
2616@media (hover: hover) {
2617 .grid-tile:hover .grid-tile-overlay { opacity: 1; }
2618}
2619@media (hover: none) {
2620 /* Op touch-devices altijd overlay tonen zodat titels zichtbaar zijn */
2621 .grid-tile-overlay { opacity: 1; background: linear-gradient(to top, rgba(0,0,0,.7) 0%, rgba(0,0,0,0) 70%); }
2622}
2623
2624.grid-tile-gradient {
2625 background-image: none;
2626 background-color: hsl(var(--tile-hue, 30), 40%, 85%);
2627 background-image: linear-gradient(135deg, hsl(var(--tile-hue, 30), 45%, 88%), hsl(calc(var(--tile-hue, 30) + 30), 35%, 75%));
2628 display: flex;
2629 flex-direction: column;
2630 align-items: center;
2631 justify-content: center;
2632 padding: 1rem;
2633 text-align: center;
2634}
2635[data-theme="dark"] .grid-tile-gradient,
2636.grid-tile-gradient[data-theme="dark"] {
2637 background-image: linear-gradient(135deg, hsl(var(--tile-hue, 30), 30%, 18%), hsl(calc(var(--tile-hue, 30) + 30), 25%, 12%));
2638}
2639.grid-tile-title {
2640 font-family: var(--font-display);
2641 font-size: 1rem;
2642 font-weight: 500;
2643 color: var(--ink);
2644 line-height: 1.2;
2645 display: -webkit-box;
2646 -webkit-line-clamp: 4;
2647 -webkit-box-orient: vertical;
2648 overflow: hidden;
2649 z-index: 1;
2650 /* Federated link posts can have a long bare URL as their title — break it so it wraps
2651 inside the tile and clamps cleanly instead of overflowing past both edges. */
2652 max-width: 100%;
2653 overflow-wrap: anywhere;
2654 word-break: break-word;
2655 hyphens: auto;
2656}
2657
2658.grid-tile-pin {
2659 position: absolute;
2660 top: .5rem;
2661 right: .5rem;
2662 display: inline-flex;
2663 align-items: center;
2664 gap: .25rem;
2665 padding: .2rem .55rem;
2666 background: var(--accent);
2667 color: #fff;
2668 border-radius: 999px;
2669 font-family: var(--font-ui);
2670 font-size: .65rem;
2671 font-weight: 700;
2672 text-transform: uppercase;
2673 letter-spacing: .06em;
2674 z-index: 3;
2675 box-shadow: 0 2px 6px rgba(0,0,0,.3);
2676 pointer-events: none;
2677}
2678.grid-tile-pin svg {
2679 width: .95em;
2680 height: .95em;
2681 margin-top: -1px;
2682}
2683/* Pinned/boosted tile: accent ring. An outline on the tile is painted UNDER the absolute
2684 cover <img>, so draw the ring as a pseudo-element overlay ABOVE the image (z-index above
2685 the img, below the corner badges + nsfw veil). */
2686.grid-tile.is-pinned { position: relative; z-index: 1; }
2687.grid-tile.is-pinned::after {
2688 content: '';
2689 position: absolute;
2690 inset: 0;
2691 border: 3px solid var(--accent);
2692 border-radius: inherit;
2693 pointer-events: none;
2694 z-index: 1;
2695}
2696.grid-tile-type {
2697 position: absolute;
2698 top: .4rem;
2699 left: .4rem;
2700 padding: .15rem .5rem;
2701 background: rgba(0,0,0,.55);
2702 color: #fff;
2703 border-radius: 999px;
2704 font-family: var(--font-ui);
2705 font-size: .6rem;
2706 font-weight: 600;
2707 text-transform: uppercase;
2708 letter-spacing: .05em;
2709 z-index: 2;
2710}
2711
2712@media (min-width: 600px) {
2713 .grid-tiles { grid-template-columns: repeat(3, 1fr); }
2714}
2715@media (min-width: 900px) {
2716 .grid-tiles { grid-template-columns: repeat(3, 1fr); gap: 8px; }
2717}
2718
2719/* -------- POST-TYPE SPECIFIEKE LAYOUTS -------- */
2720
2721/* Foto-post: beeld prominent, geen titel bovenaan, caption onder */
2722.feed-timeline[data-post-type="foto"] .post-title {
2723 font-size: 1.1rem;
2724 color: var(--ink-muted);
2725 font-weight: 400;
2726}
2727.feed-timeline[data-post-type="foto"] .post-cover {
2728 margin: 0 -1rem 1rem;
2729 border-radius: 0;
2730}
2731.feed-timeline[data-post-type="foto"] .post-cover img {
2732 width: 100%;
2733 border-radius: 0;
2734}
2735
2736/* Post-caption onder de cover */
2737.post-caption {
2738 font-family: var(--font-body);
2739 font-size: 1rem;
2740 color: var(--ink);
2741 line-height: 1.5;
2742 margin: 0 0 1.25rem;
2743 padding: 0 0 1rem;
2744 border-bottom: 1px solid var(--rule);
2745 white-space: pre-wrap;
2746}
2747.feed-timeline[data-post-type="foto"] .post-caption {
2748 font-size: 1.05rem;
2749 margin-top: -.5rem;
2750 padding-bottom: 1.25rem;
2751}
2752
2753/* Audio/video posts — type-chip helder, content eronder zoals normaal */
2754.feed-timeline[data-post-type="audio"] .post-title,
2755.feed-timeline[data-post-type="video"] .post-title {
2756 font-size: 1.5rem;
2757}
2758
2759@media (min-width: 768px) {
2760 .feed-timeline[data-post-type="foto"] .post-cover {
2761 margin: 0 0 1.5rem;
2762 border-radius: var(--radius);
2763 }
2764}
2765
2766/* -------- ADMIN EDIT-BUTTON op post-view (alleen zichtbaar voor ingelogde admin) -------- */
2767.post-edit-btn {
2768 position: absolute;
2769 top: 1rem;
2770 right: 1rem;
2771 display: inline-flex;
2772 align-items: center;
2773 justify-content: center;
2774 width: 44px;
2775 height: 44px;
2776 background: var(--paper);
2777 border: 1px solid var(--rule);
2778 border-radius: 50%;
2779 color: var(--ink-muted);
2780 text-decoration: none;
2781 box-shadow: 0 2px 8px rgba(0,0,0,.08);
2782 transition: background .15s, color .15s, transform .15s, border-color .15s;
2783 z-index: 10;
2784}
2785.post-edit-btn:hover {
2786 background: var(--accent);
2787 border-color: var(--accent);
2788 color: var(--paper);
2789 transform: scale(1.05);
2790}
2791.post-edit-btn .icon {
2792 width: 1.1rem;
2793 height: 1.1rem;
2794}
2795/* Zorg dat de article relative is zodat absolute positionering werkt */
2796.feed-timeline { position: relative; }
2797
2798@media (min-width: 768px) {
2799 .post-edit-btn {
2800 top: 1.5rem;
2801 right: 1.5rem;
2802 }
2803}
2804
2805/* ============================================================
2806 v8.0 — ACCENT SPAN + POST-TABLE (published posts)
2807 ============================================================ */
2808.post span.accent,
2809.post-content span.accent,
2810article span.accent,
2811page-container span.accent {
2812 color: var(--accent);
2813 font-weight: 500;
2814}
2815
2816.post-table,
2817article table.post-table {
2818 width: 100%;
2819 max-width: 100%;
2820 border-collapse: collapse;
2821 margin: 1.25rem 0;
2822 font-size: .95rem;
2823 display: block;
2824 overflow-x: auto;
2825 -webkit-overflow-scrolling: touch;
2826}
2827.post-table thead { background: color-mix(in srgb, var(--accent) 10%, transparent); }
2828.post-table th,
2829.post-table td {
2830 padding: .6rem .8rem;
2831 text-align: left;
2832 border: 1px solid var(--rule);
2833 vertical-align: top;
2834}
2835.post-table th {
2836 font-family: var(--font-ui);
2837 font-weight: 600;
2838 font-size: .88rem;
2839 color: var(--ink);
2840 letter-spacing: .02em;
2841}
2842.post-table tbody tr:nth-child(even) {
2843 background: color-mix(in srgb, var(--ink) 3%, transparent);
2844}
2845@media (min-width: 700px) {
2846 .post-table { display: table; overflow: visible; }
2847}
2848
2849/* ============================================================
2850 v8.0 fix — grid-cols picker (desktop only) + grid col overrides
2851 ============================================================ */
2852
2853/* Switcher-wrap bevat nu ook de cols-picker; layout side-by-side */
2854.view-switcher-wrap .container {
2855 display: flex;
2856 align-items: center;
2857 justify-content: center;
2858 gap: 1rem;
2859 flex-wrap: wrap;
2860}
2861
2862/* Solo / Cirkel scope-switcher (alleen in circle-modus) — segmented toggle, centraal.
2863 Hoge specificiteit (+ !important op tekst) zodat 'ie globale link-stijlen wint. */
2864.view-switcher-wrap .feed-scope {
2865 display: inline-flex;
2866 background: var(--paper-2);
2867 border: 1px solid var(--rule);
2868 border-radius: 999px;
2869 padding: 3px;
2870}
2871.view-switcher-wrap .feed-scope-btn {
2872 display: inline-flex;
2873 align-items: center;
2874 padding: .32rem .95rem;
2875 min-height: 30px;
2876 border: none !important;
2877 border-radius: 999px !important;
2878 background: transparent !important;
2879 color: var(--ink-muted) !important;
2880 font-family: var(--font-ui);
2881 font-size: .82rem;
2882 font-weight: 500 !important;
2883 text-decoration: none !important;
2884 cursor: pointer;
2885 transition: all .15s;
2886}
2887.view-switcher-wrap .feed-scope-btn:hover { color: var(--ink) !important; }
2888.view-switcher-wrap .feed-scope-btn.is-active {
2889 background: var(--ink) !important;
2890 color: var(--paper) !important;
2891}
2892
2893.grid-cols-picker {
2894 display: none; /* default hidden — desktop + grid-active maakt 'm zichtbaar */
2895 gap: 2px;
2896 padding: 0;
2897}
2898.grid-cols-btn {
2899 display: inline-flex;
2900 align-items: center;
2901 justify-content: center;
2902 min-width: 36px;
2903 height: 32px;
2904 padding: 0 .6rem;
2905 background: transparent;
2906 border: 1px solid var(--rule);
2907 color: var(--ink-muted);
2908 font-family: var(--font-ui);
2909 font-size: .85rem;
2910 font-weight: 500;
2911 cursor: pointer;
2912 transition: all .12s;
2913}
2914.grid-cols-btn:first-child { border-radius: 999px 0 0 999px; }
2915.grid-cols-btn:last-child { border-radius: 0 999px 999px 0; }
2916.grid-cols-btn:not(:first-child):not(:last-child) { border-left: none; border-right: none; }
2917.grid-cols-btn:hover { color: var(--ink); }
2918/* Active state puur via body[data-grid-cols] — geen is-active-class meer. */
2919body[data-grid-cols="2"] .grid-cols-btn[data-cols="2"],
2920body[data-grid-cols="3"] .grid-cols-btn[data-cols="3"],
2921body[data-grid-cols="4"] .grid-cols-btn[data-cols="4"] {
2922 background: var(--ink);
2923 color: var(--paper);
2924 border-color: var(--ink);
2925}
2926
2927/* Desktop + grid-view → toon cols-picker (op de home-feed; niet op archief) */
2928@media (min-width: 600px) {
2929 body.on-home[data-feed-view="grid"] .grid-cols-picker {
2930 display: inline-flex;
2931 }
2932}
2933
2934/* Kolom-overrides op desktop. Mobiel negeert dit (staat vast op 2). Geldt op ELKE
2935 feed met grid (home én cirkel/tag/type/user) — scope op .feed-grid .grid-tiles. */
2936@media (min-width: 600px) {
2937 body[data-grid-cols="2"] .feed-grid .grid-tiles { grid-template-columns: repeat(2, 1fr); }
2938 body[data-grid-cols="3"] .feed-grid .grid-tiles { grid-template-columns: repeat(3, 1fr); }
2939 body[data-grid-cols="4"] .feed-grid .grid-tiles { grid-template-columns: repeat(4, 1fr); }
2940}
2941
2942/* Gradient-tile: iets meer contrast voor light + dark mode zodat titel altijd leesbaar is */
2943.grid-tile-gradient {
2944 background-image: linear-gradient(135deg,
2945 hsl(var(--tile-hue, 30), 55%, 72%),
2946 hsl(calc(var(--tile-hue, 30) + 40), 45%, 60%));
2947}
2948[data-theme="dark"] .grid-tile-gradient {
2949 background-image: linear-gradient(135deg,
2950 hsl(var(--tile-hue, 30), 40%, 30%),
2951 hsl(calc(var(--tile-hue, 30) + 40), 30%, 18%));
2952}
2953.grid-tile-gradient .grid-tile-title {
2954 color: #fff;
2955 text-shadow: 0 1px 3px rgba(0,0,0,.25);
2956}
2957[data-theme="dark"] .grid-tile-gradient .grid-tile-title {
2958 color: #fff;
2959 text-shadow: 0 1px 2px rgba(0,0,0,.5);
2960}
2961
2962/* ============================================================
2963 v8.0.2 — COMPACT DESIGN OVERRIDES
2964 Tighter masthead, padding, margins overall. Profiel-header
2965 collapse/expand blijft zoals 'ie was.
2966 ============================================================ */
2967
2968/* Masthead: compacter */
2969.masthead { padding: calc(.55rem + var(--ios-safe-top, 0px)) 0 .55rem; }
2970.masthead-inner { gap: 1rem; }
2971.site-title { font-size: 1.25rem; }
2972.nav-link, .nav-btn { padding: .4rem .7rem; min-height: 2rem; font-size: .82rem; }
2973
2974/* Main content padding */
2975main { padding-top: 1rem; }
2976.page { padding-block: 1rem 1.75rem; }
2977
2978/* View switcher-bar strakker */
2979.view-switcher { padding: .4rem 0; gap: .3rem; }
2980.view-switch-btn { padding: .4rem .85rem; min-height: 38px; font-size: .8rem; }
2981.grid-cols-btn { min-width: 32px; height: 28px; padding: 0 .5rem; font-size: .8rem; }
2982
2983/* Post header spacing terug */
2984.post-header { margin: 0 0 1.25rem; }
2985.post-title { margin-bottom: .35rem; }
2986.post-meta { font-size: .78rem; }
2987.post-tags { margin-top: .6rem; gap: .3rem; }
2988.post-tag { font-size: .7rem; padding: .15rem .55rem; }
2989
2990/* Article footer + pagination compacter */
2991.article-footer { padding-top: 1.25rem; margin-top: 1.5rem; }
2992.pagination { padding-block: 1.25rem 2rem; margin-top: 1.5rem; }
2993.pagination-item { padding: .75rem .95rem; min-height: 4rem; }
2994.pagination-title { font-size: .95rem; }
2995
2996/* Site footer compacter */
2997.site-footer { padding: 1.25rem 0 calc(1.25rem + env(safe-area-inset-bottom, 0px)); margin-top: 2rem; font-size: .78rem; }
2998.site-footer-inner { gap: .75rem; }
2999
3000/* Profiel-header: full mode iets minder riant (compact mode blijft hetzelfde) */
3001.profile-header { padding: 1rem 0; }
3002.profile-photo { width: 72px; height: 72px; }
3003.profile-photo-fallback { font-size: 1.8rem; }
3004.profile-name { font-size: 1.2rem; }
3005.profile-bio { font-size: .85rem; margin-top: .15rem; }
3006.profile-links { margin-top: .5rem; gap: .4rem; }
3007.profile-links a,
3008.profile-links .profile-fedi-link { width: 32px; height: 32px; }
3009
3010@media (min-width: 768px) {
3011 .profile-header { padding: 1.35rem 0; }
3012 .profile-photo { width: 92px; height: 92px; }
3013 .profile-photo-fallback { font-size: 2.4rem; }
3014 .profile-name { font-size: 1.4rem; }
3015 .profile-bio { font-size: .95rem; }
3016 .profile-header-inner { gap: 1.1rem; }
3017 /* Compact-mode op desktop blijft klein zoals we hadden afgesproken */
3018 .on-post .profile-photo,
3019 .on-special .profile-photo { width: 42px; height: 42px; }
3020}
3021
3022/* Grid-tegels iets strakker gaten */
3023.grid-tiles { gap: 3px; }
3024
3025/* Post-cover margin */
3026.post-cover { margin: 0 0 1rem; }
3027
3028/* Audio player wat lichter */
3029#pcms-audio-bar { padding: .55rem 1rem; }
3030
3031/* v8.1 — pagination CTA + mobile tap target */
3032.pagination-cta {
3033 display: inline-block;
3034 font-family: var(--font-ui);
3035 font-size: .72rem;
3036 font-weight: 600;
3037 color: var(--accent);
3038 margin-top: .35rem;
3039 letter-spacing: .02em;
3040 opacity: .9;
3041}
3042a.pagination-item:hover .pagination-cta { opacity: 1; }
3043
3044/* Mobiel: nog meer tap-feedback + iets prominenter */
3045@media (max-width: 640px) {
3046 a.pagination-item {
3047 padding: 1.1rem 1rem;
3048 min-height: 5.5rem;
3049 border-width: 2px;
3050 }
3051 a.pagination-item:active {
3052 background: color-mix(in srgb, var(--accent) 10%, var(--paper-2));
3053 transform: scale(.98);
3054 }
3055 .pagination-title { font-size: 1rem; }
3056 .pagination-cta { font-size: .75rem; }
3057 .pagination .icon { width: 1.5em; height: 1.5em; }
3058}
3059
3060
3061
3062/* v8.3 / v9.4 — PWA install button (alleen zichtbaar als browser install ondersteunt) */
3063.nav-install-btn[hidden] { display: none; }
3064.nav-install-btn {
3065 position: relative;
3066 display: inline-flex;
3067 align-items: center;
3068 justify-content: center;
3069 gap: .35rem;
3070 background: linear-gradient(135deg,
3071 var(--accent),
3072 color-mix(in srgb, var(--accent) 80%, #000));
3073 color: #fff;
3074 border: none;
3075 border-radius: .65rem;
3076 padding: .45rem .85rem;
3077 font-size: .8rem;
3078 font-weight: 600;
3079 line-height: 1;
3080 cursor: pointer;
3081 overflow: hidden;
3082 isolation: isolate;
3083 box-shadow:
3084 0 1px 0 rgba(255,255,255,.15) inset,
3085 0 2px 6px color-mix(in srgb, var(--accent) 35%, transparent);
3086 transition:
3087 transform .15s cubic-bezier(.4, 0, .2, 1),
3088 box-shadow .2s ease,
3089 filter .15s ease;
3090}
3091.nav-install-btn::before {
3092 content: "";
3093 position: absolute;
3094 top: 0;
3095 left: -100%;
3096 width: 60%;
3097 height: 100%;
3098 background: linear-gradient(110deg,
3099 transparent 30%,
3100 rgba(255,255,255,.22) 50%,
3101 transparent 70%);
3102 z-index: -1;
3103 animation: pcmsInstallShimmer 4s ease-in-out infinite;
3104 pointer-events: none;
3105}
3106.nav-install-btn:hover {
3107 transform: translateY(-1px);
3108 filter: brightness(1.08);
3109 box-shadow:
3110 0 1px 0 rgba(255,255,255,.2) inset,
3111 0 4px 10px color-mix(in srgb, var(--accent) 50%, transparent);
3112}
3113.nav-install-btn:active { transform: translateY(0); }
3114.nav-install-btn .icon {
3115 flex-shrink: 0;
3116 transition: transform .25s cubic-bezier(.34, 1.56, .64, 1);
3117}
3118.nav-install-btn:hover .icon { transform: translateY(-1px); }
3119@media (prefers-reduced-motion: reduce) {
3120 .nav-install-btn::before { animation: none; left: -100%; }
3121 .nav-install-btn:hover { transform: none; }
3122 .nav-install-btn:hover .icon { transform: none; }
3123}
3124/* Als PWA al draait (standalone mode) — verberg install-prompt knop volledig */
3125@media all and (display-mode: standalone) {
3126 #pwa-install-btn { display: none !important; }
3127}
3128
3129/* ========== v8.9.9 — Privé-post indicators ========== */
3130.post-private-banner {
3131 display: flex;
3132 align-items: center;
3133 gap: .6rem;
3134 padding: .75rem 1rem;
3135 background: color-mix(in srgb, #eab308 12%, var(--paper, #fff));
3136 border: 1px solid color-mix(in srgb, #eab308 40%, transparent);
3137 border-radius: 8px;
3138 margin: 0 0 1rem;
3139 font-size: .88rem;
3140 color: var(--ink, #1a1a1a);
3141}
3142.post-private-banner strong {
3143 color: #b45309;
3144}
3145
3146.grid-tile-private {
3147 position: absolute;
3148 top: 8px;
3149 left: 8px;
3150 padding: 3px 8px;
3151 background: rgba(0,0,0,0.7);
3152 color: #fde68a;
3153 font-size: .7rem;
3154 font-weight: 700;
3155 border-radius: 999px;
3156 z-index: 3;
3157 backdrop-filter: blur(4px);
3158 -webkit-backdrop-filter: blur(4px);
3159}
3160
3161/* ========== v8.9.10 — Social chip (inline in post-body) ========== */
3162.social-chip {
3163 display: inline-flex;
3164 align-items: center;
3165 gap: .45rem;
3166 padding: .35rem .75rem;
3167 background: color-mix(in srgb, var(--accent) 10%, transparent);
3168 border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
3169 border-radius: 999px;
3170 color: var(--ink, #1a1a1a);
3171 text-decoration: none;
3172 font-family: var(--font-ui, system-ui);
3173 font-size: .85rem;
3174 font-weight: 600;
3175 line-height: 1.2;
3176 transition: all .15s;
3177 vertical-align: middle;
3178 margin: 0 .1rem;
3179}
3180.social-chip:hover {
3181 background: var(--accent);
3182 color: #fff;
3183 border-color: var(--accent);
3184 text-decoration: none;
3185 transform: translateY(-1px);
3186 box-shadow: 0 2px 8px color-mix(in srgb, var(--accent) 40%, transparent);
3187}
3188.social-chip .icon {
3189 width: 16px;
3190 height: 16px;
3191 flex-shrink: 0;
3192}
3193.social-chip-icon-only {
3194 width: 36px;
3195 height: 36px;
3196 padding: 0;
3197 justify-content: center;
3198 border-radius: 50%;
3199}
3200.social-chip-icon-only .icon {
3201 width: 18px;
3202 height: 18px;
3203}
3204
3205/* v8.9.34 — player hidden state + post audio blocks
3206 v9.3 — Hide-rules uitgeschakeld: mini-player blijft permanent zichtbaar
3207 zodat 'ie niet meer verdwijnt bij browser-back of navigatie. */
3208.audio-player.is-hidden {
3209 /* display: none !important; */
3210}
3211body:not(.has-audio-player) #pcms-audio-player.is-hidden {
3212 /* display: none !important; */
3213}
3214
3215/* Post audio track — single track row in een post */
3216/* Lokale audio-track — visueel consistent met .post-audio-external */
3217.post-audio-track {
3218 display: flex;
3219 align-items: center;
3220 gap: .75rem;
3221 padding: .65rem .85rem;
3222 background: var(--paper-2, color-mix(in srgb, var(--ink) 4%, transparent));
3223 border: 1px solid var(--rule, rgba(0,0,0,.08));
3224 border-radius: 10px;
3225 margin: .75rem 0;
3226 transition: background .15s, border-color .15s;
3227}
3228.post-audio-track:hover {
3229 border-color: var(--accent, #c2410c);
3230 background: color-mix(in srgb, var(--accent, #c2410c) 5%, var(--paper-2, transparent));
3231}
3232/* Korte highlight wanneer je via de mini-speler naar deze track springt. */
3233.post-audio-track.pat-flash,
3234.post-album-track-compact.pat-flash {
3235 animation: patFlash 1.6s ease-out;
3236 border-radius: 8px;
3237}
3238/* Blijvende highlight op de track die NU actief is in de speler. */
3239.post-audio-track.pat-playing,
3240.post-album-track-compact.pat-playing {
3241 background: color-mix(in srgb, var(--accent, #c2410c) 12%, var(--paper-2, transparent));
3242 box-shadow: inset 3px 0 0 0 var(--accent, #c2410c);
3243 border-radius: 8px;
3244}
3245@keyframes patFlash {
3246 0%, 30% { border-color: var(--accent, #c2410c); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent, #c2410c) 35%, transparent); }
3247 100% { box-shadow: 0 0 0 0 transparent; }
3248}
3249.post-audio-track .pat-play {
3250 flex-shrink: 0;
3251 width: 42px;
3252 height: 42px;
3253 border-radius: 8px; /* zelfde rounded-square als pae-icon */
3254 border: none;
3255 background: var(--accent, #c2410c);
3256 color: var(--paper, #fff);
3257 cursor: pointer;
3258 display: inline-flex;
3259 align-items: center;
3260 justify-content: center;
3261 transition: transform .1s, background .15s;
3262 padding: 0;
3263 position: relative;
3264 overflow: hidden;
3265}
3266.post-audio-track .pat-play:hover { transform: scale(1.04); }
3267.post-audio-track .pat-play:active { transform: scale(.96); }
3268.post-audio-track .pat-play svg,
3269.post-audio-track .pat-play .pat-sitelogo {
3270 width: 100%; height: 100%;
3271 position: absolute;
3272 top: 0; left: 0;
3273 transition: opacity .15s;
3274}
3275.post-audio-track .pat-play .icon-play,
3276.post-audio-track .pat-play .icon-pause {
3277 width: 18px; height: 18px;
3278 position: absolute;
3279 top: 50%; left: 50%;
3280 transform: translate(-50%, -50%);
3281 fill: currentColor;
3282 opacity: 0; /* verborgen tot hover of is-current */
3283}
3284/* Site logo: object-cover binnen 42x42 box */
3285.post-audio-track .pat-play .pat-sitelogo {
3286 object-fit: cover;
3287 opacity: 1;
3288}
3289.post-audio-track .pat-play .pat-sitelogo-fallback {
3290 padding: 11px; /* SVG music-note iets kleiner in box */
3291 opacity: 1;
3292}
3293/* Bij hover: site logo faded, play-icoon verschijnt */
3294.post-audio-track:hover .pat-play .pat-sitelogo { opacity: 0.25; }
3295.post-audio-track:hover .pat-play .icon-play { opacity: 1; }
3296/* Bij current + playing: toon pause-icon */
3297.post-audio-track.is-current .pat-play .pat-sitelogo { opacity: 0.25; }
3298.post-audio-track.is-current .pat-play .icon-play { opacity: 1; }
3299.post-audio-track.is-current.is-playing .pat-play .icon-play { opacity: 0; }
3300.post-audio-track.is-current.is-playing .pat-play .icon-pause { opacity: 1; }
3301.post-audio-track.is-current {
3302 border-color: var(--accent, #c2410c);
3303 background: color-mix(in srgb, var(--accent, #c2410c) 10%, transparent);
3304}
3305.post-audio-track .pat-meta {
3306 flex: 1;
3307 min-width: 0;
3308 display: flex;
3309 flex-direction: column;
3310 gap: 2px;
3311}
3312.post-audio-track .pat-title {
3313 display: block;
3314 font-weight: 600;
3315 color: var(--ink);
3316 font-size: .95rem;
3317 overflow: hidden;
3318 text-overflow: ellipsis;
3319 white-space: nowrap;
3320}
3321.post-audio-track .pat-artist {
3322 display: block;
3323 font-size: .78rem;
3324 color: var(--ink-muted, var(--ink));
3325 opacity: .65;
3326 overflow: hidden;
3327 text-overflow: ellipsis;
3328 white-space: nowrap;
3329}
3330.post-audio-track .pat-duration {
3331 flex-shrink: 0;
3332 font-family: ui-monospace, monospace;
3333 font-size: .8rem;
3334 opacity: .55;
3335}
3336
3337/* Album block in een post */
3338.post-album {
3339 position: relative;
3340 border: 1px solid var(--rule, rgba(0,0,0,.1));
3341 border-radius: 14px;
3342 overflow: hidden;
3343 margin: 1.25rem 0;
3344 background: var(--paper-2, color-mix(in srgb, var(--ink) 3%, transparent));
3345}
3346.post-album-header {
3347 display: flex;
3348 gap: .75rem;
3349 padding: .55rem .7rem;
3350 align-items: center;
3351}
3352.post-album-cover {
3353 width: 120px;
3354 height: 120px;
3355 border-radius: 8px;
3356 background-size: cover;
3357 background-position: center;
3358 background-color: var(--rule);
3359 flex-shrink: 0;
3360}
3361/* v9.0 — Collage van track-covers als album-cover leeg is */
3362.post-album-cover-collage {
3363 display: grid;
3364 grid-template-columns: 1fr 1fr;
3365 grid-template-rows: 1fr 1fr;
3366 gap: 0;
3367 overflow: hidden;
3368 background: transparent;
3369}
3370.post-album-cover-collage .post-album-cover-tile {
3371 background-size: cover;
3372 background-position: center;
3373 width: 100%;
3374 height: 100%;
3375}
3376/* Empty state: gradient met muziek-noot */
3377.post-album-cover-empty {
3378 display: flex;
3379 align-items: center;
3380 justify-content: center;
3381 background: linear-gradient(135deg, color-mix(in srgb, var(--accent) 25%, var(--paper-2)), color-mix(in srgb, var(--accent) 10%, var(--paper)));
3382 color: var(--accent, #c2410c);
3383}
3384.post-album-cover-empty svg {
3385 width: 42%;
3386 height: 42%;
3387 opacity: .55;
3388}
3389.post-album-info {
3390 flex: 1;
3391 min-width: 0;
3392}
3393.post-album-label {
3394 text-transform: uppercase;
3395 font-size: .68rem;
3396 letter-spacing: .1em;
3397 opacity: .55;
3398 margin: 0 0 .15rem;
3399 font-weight: 700;
3400}
3401.post-album-title {
3402 font-family: var(--font-display);
3403 font-size: 1.1rem;
3404 font-weight: 600;
3405 margin: 0 0 .1rem;
3406 line-height: 1.15;
3407 letter-spacing: -0.01em;
3408}
3409.post-album-artist {
3410 font-size: .88rem;
3411 opacity: .8;
3412 margin: 0 0 .12rem;
3413 line-height: 1.25;
3414}
3415.post-album-meta {
3416 font-size: .74rem;
3417 opacity: .55;
3418 margin: 0;
3419 line-height: 1.2;
3420}
3421.post-album-playall {
3422 margin-top: .75rem;
3423 padding: .45rem .9rem;
3424 background: var(--accent, #c2410c);
3425 color: var(--paper, #fff);
3426 border: none;
3427 border-radius: 6px;
3428 font-weight: 600;
3429 cursor: pointer;
3430 font-size: .88rem;
3431 display: inline-flex;
3432 align-items: center;
3433 gap: .35rem;
3434}
3435.post-album-playall:hover { filter: brightness(1.08); }
3436
3437/* ============================================================
3438 v9.0 — Album cover clickable button
3439 ============================================================ */
3440.post-album-cover-btn {
3441 position: relative;
3442 background: none;
3443 border: none;
3444 padding: 0;
3445 margin: 0;
3446 cursor: pointer;
3447 flex-shrink: 0;
3448 border-radius: 8px;
3449 overflow: hidden;
3450 display: block;
3451 width: auto;
3452 /* v9.1 — voorkom mobile 300ms double-tap zoom delay, anders zou 2× snel klikken
3453 een zoom triggeren i.p.v. 2× click-events */
3454 touch-action: manipulation;
3455 -webkit-tap-highlight-color: transparent;
3456}
3457.post-album-cover-btn .post-album-cover {
3458 display: block;
3459 width: 76px;
3460 height: 76px;
3461 border-radius: 7px;
3462 background-size: cover;
3463 background-position: center;
3464 background-color: var(--rule);
3465 transition: transform .25s ease;
3466}
3467.post-album-cover-btn:hover .post-album-cover {
3468 transform: scale(1.04);
3469}
3470.post-album-cover-btn .post-album-cover-empty {
3471 background: linear-gradient(135deg,
3472 color-mix(in srgb, var(--accent, #c2410c) 35%, var(--paper)),
3473 color-mix(in srgb, var(--accent, #c2410c) 10%, var(--paper-2)));
3474 display: flex;
3475 align-items: center;
3476 justify-content: center;
3477}
3478.post-album-cover-btn .post-album-cover-empty svg {
3479 width: 28px;
3480 height: 28px;
3481 color: color-mix(in srgb, var(--accent, #c2410c) 60%, transparent);
3482}
3483/* Play overlay op hover */
3484.post-album-cover-play {
3485 position: absolute;
3486 inset: 0;
3487 display: flex;
3488 align-items: center;
3489 justify-content: center;
3490 background: rgba(0, 0, 0, .35);
3491 opacity: 0;
3492 transition: opacity .2s ease;
3493 border-radius: 8px;
3494 pointer-events: none;
3495}
3496.post-album-cover-play svg {
3497 width: 48px;
3498 height: 48px;
3499 color: #fff;
3500 filter: drop-shadow(0 2px 8px rgba(0,0,0,.4));
3501}
3502.post-album-cover-btn:hover .post-album-cover-play,
3503.post-album-cover-btn:focus-visible .post-album-cover-play {
3504 opacity: 1;
3505}
3506
3507/* ============================================================
3508 v1 P52 — Admin actions overlay (edit / delete)
3509 Only rendered when the viewer has god role. Sits top-right
3510 of the card so it doesn't compete with the cover play affordance.
3511 ============================================================ */
3512.post-album-actions {
3513 position: absolute;
3514 top: .4rem;
3515 right: .4rem;
3516 display: flex;
3517 gap: .25rem;
3518 z-index: 2;
3519}
3520.post-album-action {
3521 width: 28px;
3522 height: 28px;
3523 border-radius: 6px;
3524 border: 1px solid var(--rule);
3525 background: color-mix(in srgb, var(--paper) 78%, transparent);
3526 backdrop-filter: blur(8px);
3527 -webkit-backdrop-filter: blur(8px);
3528 color: var(--ink);
3529 display: inline-flex;
3530 align-items: center;
3531 justify-content: center;
3532 cursor: pointer;
3533 text-decoration: none;
3534 opacity: .65;
3535 padding: 0;
3536 transition: opacity .15s ease, transform .15s ease, background .15s ease, color .15s ease, border-color .15s ease;
3537 -webkit-tap-highlight-color: transparent;
3538}
3539.post-album-action:hover,
3540.post-album-action:focus-visible {
3541 opacity: 1;
3542 transform: translateY(-1px);
3543 outline: none;
3544}
3545.post-album-action.is-danger:hover,
3546.post-album-action.is-danger:focus-visible {
3547 background: color-mix(in srgb, #c2410c 18%, var(--paper));
3548 border-color: color-mix(in srgb, #c2410c 45%, var(--rule));
3549 color: #c2410c;
3550}
3551.post-album-action svg {
3552 width: 15px;
3553 height: 15px;
3554 display: block;
3555}
3556
3557/* ============================================================
3558 v9.0 — Compacte tracklist (informatief, niet-klikbaar)
3559 ============================================================ */
3560.post-album-tracks {
3561 list-style: none;
3562 padding: 0;
3563 margin: 0;
3564 border-top: 1px solid var(--rule);
3565}
3566/* v9.4 — Playlist insert modal rows */
3567.pli-row {
3568 display: flex;
3569 align-items: center;
3570 gap: .75rem;
3571 padding: .65rem .5rem;
3572 border-bottom: 1px solid var(--border);
3573}
3574.pli-row:last-child { border-bottom: none; }
3575.pli-row-cover {
3576 width: 44px;
3577 height: 44px;
3578 border-radius: 6px;
3579 background-size: cover;
3580 background-position: center;
3581 background-color: color-mix(in srgb, var(--ink, #000) 8%, transparent);
3582 flex-shrink: 0;
3583 display: flex;
3584 align-items: center;
3585 justify-content: center;
3586 font-size: 1.4rem;
3587}
3588.pli-row-info {
3589 flex: 1;
3590 min-width: 0;
3591}
3592.pli-row-title {
3593 font-weight: 600;
3594 overflow: hidden;
3595 text-overflow: ellipsis;
3596 white-space: nowrap;
3597}
3598.pli-row-meta {
3599 font-size: .82rem;
3600 overflow: hidden;
3601 text-overflow: ellipsis;
3602 white-space: nowrap;
3603}
3604.post-playlist-placeholder {
3605 margin: 1rem 0;
3606 user-select: none;
3607}
3608
3609/* v9.4 — Generic modal classes (gebruikt door playlist-editor en andere modals) */
3610.pcms-modal-backdrop {
3611 position: fixed;
3612 inset: 0;
3613 background: rgba(0, 0, 0, .6);
3614 display: flex;
3615 align-items: center;
3616 justify-content: center;
3617 z-index: 9000;
3618 padding: 1rem;
3619 box-sizing: border-box;
3620 overflow-y: auto;
3621}
3622.pcms-modal {
3623 background: var(--paper, #fff);
3624 color: var(--ink, #000);
3625 border-radius: 12px;
3626 width: 100%;
3627 max-width: 640px;
3628 max-height: calc(100vh - 2rem);
3629 display: flex;
3630 flex-direction: column;
3631 overflow: hidden;
3632 box-shadow: 0 20px 60px rgba(0, 0, 0, .3);
3633}
3634.pcms-modal-header {
3635 display: flex;
3636 align-items: center;
3637 justify-content: space-between;
3638 padding: 1rem 1.25rem;
3639 border-bottom: 1px solid var(--border);
3640 flex-shrink: 0;
3641}
3642.pcms-modal-header h3 { font-size: 1.1rem; }
3643.pcms-modal-close {
3644 background: transparent;
3645 border: none;
3646 font-size: 1.6rem;
3647 line-height: 1;
3648 cursor: pointer;
3649 padding: .25rem .5rem;
3650 color: var(--fg-muted, #666);
3651 border-radius: 4px;
3652}
3653.pcms-modal-close:hover {
3654 background: color-mix(in srgb, var(--ink, #000) 8%, transparent);
3655}
3656.pcms-modal-body {
3657 padding: 1.25rem;
3658 overflow-y: auto;
3659 overscroll-behavior: contain;
3660 flex: 1;
3661 min-height: 0;
3662}
3663.pcms-modal-footer {
3664 display: flex;
3665 gap: .5rem;
3666 justify-content: flex-end;
3667 padding: .75rem 1.25rem;
3668 border-top: 1px solid var(--border);
3669 flex-shrink: 0;
3670 background: color-mix(in srgb, var(--ink, #000) 3%, transparent);
3671}
3672
3673/* On mobile: full-screen modal */
3674@media (max-width: 600px) {
3675 .pcms-modal-backdrop {
3676 padding: 0;
3677 }
3678 .pcms-modal {
3679 border-radius: 0;
3680 max-width: 100%;
3681 max-height: 100vh;
3682 height: 100vh;
3683 }
3684}
3685
3686/* v9.4 — Media → Playlists tab */
3687.playlists-page-header {
3688 display: flex;
3689 flex-wrap: wrap;
3690 gap: 1rem;
3691 align-items: center;
3692 justify-content: space-between;
3693 margin-bottom: 1.25rem;
3694}
3695.playlists-page-header > p { flex: 1; min-width: 200px; }
3696.playlists-grid {
3697 display: grid;
3698 grid-template-columns: 1fr;
3699 gap: .75rem;
3700}
3701@media (min-width: 720px) {
3702 .playlists-grid { grid-template-columns: repeat(2, 1fr); }
3703}
3704@media (min-width: 1100px) {
3705 .playlists-grid { grid-template-columns: repeat(3, 1fr); }
3706}
3707.playlist-card {
3708 display: grid;
3709 grid-template-columns: 64px 1fr auto;
3710 gap: .75rem;
3711 align-items: center;
3712 padding: .75rem;
3713 border: 1px solid var(--border);
3714 border-radius: var(--radius);
3715 background: var(--paper, #fff);
3716}
3717.playlist-card-cover {
3718 width: 64px;
3719 height: 64px;
3720 border-radius: 8px;
3721 overflow: hidden;
3722 background-color: color-mix(in srgb, var(--ink, #000) 6%, transparent);
3723 display: flex;
3724 align-items: center;
3725 justify-content: center;
3726}
3727.playlist-card-cover img {
3728 width: 100%;
3729 height: 100%;
3730 object-fit: cover;
3731}
3732.playlist-card-cover-empty { font-size: 1.6rem; opacity: .5; }
3733.playlist-card-info { min-width: 0; }
3734.playlist-card-title {
3735 font-weight: 600;
3736 overflow: hidden;
3737 text-overflow: ellipsis;
3738 white-space: nowrap;
3739}
3740.playlist-card-artist,
3741.playlist-card-meta {
3742 font-size: .82rem;
3743 overflow: hidden;
3744 text-overflow: ellipsis;
3745 white-space: nowrap;
3746}
3747.playlist-card-actions {
3748 display: flex;
3749 gap: .25rem;
3750 flex-shrink: 0;
3751}
3752
3753/* v9.4 — Playlist editor modal (mobile-friendly, single-column) */
3754.pl-editor {
3755 /* Erft van .pcms-modal */
3756}
3757.pl-editor-meta {
3758 display: grid;
3759 grid-template-columns: 1fr;
3760 gap: .75rem;
3761 margin-bottom: 1rem;
3762}
3763@media (min-width: 560px) {
3764 .pl-editor-meta {
3765 grid-template-columns: 1fr 1fr;
3766 }
3767 .pl-editor-meta .pl-editor-field-full { grid-column: 1 / -1; }
3768}
3769.pl-editor-field {
3770 display: flex;
3771 flex-direction: column;
3772 gap: .25rem;
3773 min-width: 0;
3774}
3775.pl-editor-field span {
3776 font-size: .82rem;
3777 color: var(--fg-muted, #666);
3778 font-weight: 500;
3779}
3780.pl-editor-field input,
3781.pl-editor-field select {
3782 width: 100%;
3783 box-sizing: border-box;
3784 padding: .5rem .65rem;
3785 font-size: .95rem;
3786 border: 1px solid var(--border);
3787 border-radius: 6px;
3788 background: var(--paper, #fff);
3789 color: var(--ink, #000);
3790}
3791.pl-editor-field input:focus,
3792.pl-editor-field select:focus {
3793 outline: 2px solid var(--accent, #5a8a5a);
3794 outline-offset: -1px;
3795}
3796.pl-editor-section-title {
3797 margin: 1.25rem 0 .5rem;
3798 font-size: 1rem;
3799 font-weight: 600;
3800}
3801.pl-tracks-selected {
3802 border: 1px solid var(--border);
3803 border-radius: var(--radius);
3804 background: var(--paper, #fff);
3805 min-height: 60px;
3806 margin-bottom: 1rem;
3807 padding: .25rem;
3808}
3809.pl-tracks-empty {
3810 padding: 1.5rem;
3811 text-align: center;
3812 color: var(--fg-muted, #666);
3813 font-size: .9rem;
3814}
3815.pl-track-row {
3816 display: grid;
3817 grid-template-columns: 32px 36px 1fr auto;
3818 gap: .5rem;
3819 align-items: center;
3820 padding: .5rem;
3821 border-bottom: 1px solid var(--border);
3822 background: var(--paper, #fff);
3823 user-select: none;
3824 touch-action: pan-x;
3825}
3826.pl-track-row:last-child { border-bottom: none; }
3827.pl-track-row.is-dragging {
3828 opacity: .55;
3829 transform: scale(.98);
3830 background: color-mix(in srgb, var(--accent, #5a8a5a) 10%, transparent);
3831 border-radius: 6px;
3832}
3833.pl-track-row.drop-target-above {
3834 box-shadow: inset 0 2px 0 0 var(--accent, #5a8a5a);
3835}
3836.pl-track-row.drop-target-below {
3837 box-shadow: inset 0 -2px 0 0 var(--accent, #5a8a5a);
3838}
3839.pl-track-handle {
3840 cursor: grab;
3841 font-size: 1.2rem;
3842 line-height: 1;
3843 color: var(--fg-muted, #666);
3844 display: flex;
3845 align-items: center;
3846 justify-content: center;
3847 height: 32px;
3848 width: 32px;
3849 border-radius: 4px;
3850 flex-shrink: 0;
3851}
3852.pl-track-handle:active { cursor: grabbing; }
3853.pl-track-handle:hover {
3854 background: color-mix(in srgb, var(--ink, #000) 8%, transparent);
3855}
3856.pl-track-num {
3857 text-align: center;
3858 color: var(--fg-muted, #666);
3859 font-size: .85rem;
3860 width: 36px;
3861}
3862.pl-track-info {
3863 min-width: 0;
3864 overflow: hidden;
3865}
3866.pl-track-title {
3867 font-weight: 500;
3868 overflow: hidden;
3869 text-overflow: ellipsis;
3870 white-space: nowrap;
3871}
3872.pl-track-artist {
3873 font-size: .78rem;
3874 color: var(--fg-muted, #666);
3875 overflow: hidden;
3876 text-overflow: ellipsis;
3877 white-space: nowrap;
3878}
3879.pl-track-remove {
3880 background: transparent;
3881 border: none;
3882 cursor: pointer;
3883 padding: .35rem;
3884 border-radius: 4px;
3885 color: var(--fg-muted, #666);
3886 font-size: 1.2rem;
3887 line-height: 1;
3888}
3889.pl-track-remove:hover {
3890 background: color-mix(in srgb, #c00 12%, transparent);
3891 color: #c00;
3892}
3893
3894/* Available tracks panel */
3895.pl-tracks-available-panel {
3896 border: 1px solid var(--border);
3897 border-radius: var(--radius);
3898 background: var(--paper, #fff);
3899}
3900.pl-tracks-available-search {
3901 padding: .5rem;
3902 border-bottom: 1px solid var(--border);
3903}
3904.pl-tracks-available-search input {
3905 width: 100%;
3906 box-sizing: border-box;
3907}
3908.pl-tracks-available-list {
3909 max-height: 30vh;
3910 overflow-y: auto;
3911}
3912.pl-track-row-available {
3913 display: grid;
3914 grid-template-columns: 1fr auto;
3915 gap: .5rem;
3916 align-items: center;
3917 padding: .5rem;
3918 border-bottom: 1px solid var(--border);
3919 cursor: pointer;
3920}
3921.pl-track-row-available:last-child { border-bottom: none; }
3922.pl-track-row-available:hover {
3923 background: color-mix(in srgb, var(--accent, #5a8a5a) 8%, transparent);
3924}
3925.pl-track-row-available.is-already-added {
3926 opacity: .4;
3927 pointer-events: none;
3928}
3929.pl-track-add-btn {
3930 background: transparent;
3931 border: 1px solid var(--border);
3932 border-radius: 4px;
3933 padding: .25rem .5rem;
3934 cursor: pointer;
3935 font-size: .85rem;
3936 color: var(--accent, #5a8a5a);
3937}
3938
3939/* v9.3 — Tracklist items zijn nu klikbare <button class="pat-row"> binnen <li>.
3940 De LI is puur een container zonder visuele styling; alles gebeurt op de button. */
3941.post-album-track-compact {
3942 padding: 0;
3943 margin: 0;
3944 border-bottom: 1px solid var(--rule);
3945 list-style: none;
3946}
3947.post-album-track-compact:last-child { border-bottom: none; }
3948
3949.pat-row {
3950 display: grid;
3951 grid-template-columns: 32px 1fr auto;
3952 gap: .65rem;
3953 align-items: center;
3954 width: 100%;
3955 padding: .5rem .85rem;
3956 background: transparent;
3957 border: none;
3958 color: inherit;
3959 font: inherit;
3960 font-size: .82rem;
3961 text-align: left;
3962 cursor: pointer;
3963 position: relative;
3964 transition: background .15s ease;
3965}
3966.pat-row:hover {
3967 background: color-mix(in srgb, var(--ink, #000) 6%, transparent);
3968}
3969.pat-row:active { transform: scale(.995); }
3970[data-theme="dark"] .pat-row:hover {
3971 background: color-mix(in srgb, var(--paper, #fff) 10%, transparent);
3972}
3973
3974/* Leader: track-nummer OF cover-thumb (afhankelijk van kind).
3975 v9.3 — pat-leader is altijd 32×32, met overgang voor spinner-vervanging. */
3976.pat-row .pat-num,
3977.pat-row .pat-cover {
3978 width: 32px;
3979 height: 32px;
3980 border-radius: 4px;
3981 flex-shrink: 0;
3982 transition: opacity .25s ease, transform .25s ease;
3983}
3984.pat-row .pat-num {
3985 font-family: ui-monospace, monospace;
3986 font-size: .8rem;
3987 opacity: .5;
3988 display: flex;
3989 align-items: center;
3990 justify-content: center;
3991}
3992.pat-row .pat-cover {
3993 background-size: cover;
3994 background-position: center;
3995 background-color: color-mix(in srgb, var(--ink, #000) 8%, transparent);
3996}
3997
3998/* v9.3 — Loading-spiraal als overlay op de leader-kolom.
3999 pat-num/pat-cover faden uit, spinner faded in via ::before. */
4000.pat-row::before {
4001 content: "";
4002 position: absolute;
4003 left: .85rem; top: 50%;
4004 width: 32px; height: 32px;
4005 transform: translateY(-50%);
4006 color: var(--accent, #c2410c);
4007 background-color: currentColor;
4008 -webkit-mask: url('/assets/spinner.svg') center/26px 26px no-repeat;
4009 mask: url('/assets/spinner.svg') center/26px 26px no-repeat;
4010 opacity: 0;
4011 transition: opacity .25s ease;
4012 pointer-events: none;
4013 animation: pat-spinner-rotate 1.2s linear infinite;
4014 animation-play-state: paused;
4015}
4016.pat-row.is-loading::before {
4017 opacity: 1;
4018 animation-play-state: running;
4019}
4020.pat-row.is-loading .pat-num,
4021.pat-row.is-loading .pat-cover {
4022 opacity: 0;
4023 transform: scale(.85);
4024}
4025@keyframes pat-spinner-rotate {
4026 from { transform: translateY(-50%) rotate(0deg); }
4027 to { transform: translateY(-50%) rotate(-360deg); }
4028}
4029
4030/* Meta-kolom */
4031.pat-row .pat-meta {
4032 display: flex;
4033 flex-direction: column;
4034 min-width: 0;
4035 gap: 1px;
4036 overflow: hidden;
4037}
4038.pat-row .pat-title {
4039 font-weight: 500;
4040 overflow: hidden;
4041 text-overflow: ellipsis;
4042 white-space: nowrap;
4043}
4044.pat-row .pat-artist {
4045 font-size: .72rem;
4046 opacity: .6;
4047 overflow: hidden;
4048 text-overflow: ellipsis;
4049 white-space: nowrap;
4050}
4051.pat-row .pat-duration {
4052 font-family: ui-monospace, monospace;
4053 font-size: .72rem;
4054 opacity: .55;
4055 font-variant-numeric: tabular-nums;
4056 white-space: nowrap;
4057}
4058.pat-row .pat-duration-empty {
4059 opacity: .25;
4060}
4061
4062/* is-current — actieve track in de player */
4063.pat-row.is-current {
4064 background: color-mix(in srgb, var(--accent, #c2410c) 12%, transparent);
4065}
4066.pat-row.is-current .pat-title,
4067.pat-row.is-current .pat-artist { color: var(--accent, #c2410c); }
4068
4069/* v9.3 — Marquee bij actief afspelen: titel scrollt heen-en-weer.
4070 --pat-shift wordt door JS gezet (= overflow in pixels). Bij 0 → geen
4071 beweging want translateX(0) blijft 0.
4072 Snelle cyclus (6s) met korte rust aan beide uiteinden (8%) zodat 't
4073 vlot voelt zonder onleesbaar te zijn. */
4074.pat-row.is-current.is-playing .pat-title {
4075 animation: pat-title-marquee 6s ease-in-out infinite alternate;
4076 text-overflow: clip;
4077 overflow: visible;
4078 will-change: transform;
4079}
4080@keyframes pat-title-marquee {
4081 0%, 8% { transform: translateX(0); }
4082 92%, 100% { transform: translateX(calc(-1 * var(--pat-shift, 0px))); }
4083}
4084
4085/* ============================================================
4086 v9.0 — CSS-migratie voor OUDE opgeslagen albums
4087 Oude posts hebben <li class="post-audio-track"> met play-knoppen + cover-spans.
4088 We renderen die VISUEEL als compact, zonder de HTML aan te passen.
4089 ============================================================ */
4090.post-album-tracks .post-audio-track {
4091 display: grid;
4092 grid-template-columns: 28px 1fr auto;
4093 gap: .75rem;
4094 align-items: center;
4095 padding: .5rem .85rem;
4096 margin: 0;
4097 border: none;
4098 border-bottom: 1px solid var(--rule);
4099 background: transparent;
4100 border-radius: 0;
4101 cursor: default;
4102 font-size: .92rem;
4103}
4104.post-album-tracks .post-audio-track:last-child { border-bottom: none; }
4105/* Verberg de cover-thumb en play-button in OUDE saved posts */
4106.post-album-tracks .post-audio-track .pat-cover,
4107.post-album-tracks .post-audio-track .pat-play {
4108 display: none !important;
4109}
4110.post-album-tracks .post-audio-track .pat-num {
4111 font-family: ui-monospace, monospace;
4112 font-size: .8rem;
4113 opacity: .45;
4114 text-align: center;
4115 width: auto;
4116}
4117.post-album-tracks .post-audio-track .pat-meta {
4118 display: flex;
4119 flex-direction: column;
4120 min-width: 0;
4121 gap: 1px;
4122}
4123.post-album-tracks .post-audio-track .pat-title {
4124 font-weight: 500;
4125 overflow: hidden;
4126 text-overflow: ellipsis;
4127 white-space: nowrap;
4128}
4129.post-album-tracks .post-audio-track .pat-artist {
4130 font-size: .78rem;
4131 opacity: .6;
4132}
4133.post-album-tracks .post-audio-track .pat-duration {
4134 font-family: ui-monospace, monospace;
4135 font-size: .78rem;
4136 opacity: .55;
4137}
4138.post-album-tracks .post-audio-track.is-current {
4139 background: color-mix(in srgb, var(--accent, #c2410c) 10%, transparent);
4140}
4141.post-album-tracks .post-audio-track.is-current .pat-num,
4142.post-album-tracks .post-audio-track.is-current .pat-title {
4143 color: var(--accent);
4144}
4145
4146@media (max-width: 540px) {
4147 .post-album-header { flex-direction: column; }
4148 .post-album-cover-btn .post-album-cover { width: 100%; max-width: 240px; height: auto; aspect-ratio: 1/1; }
4149}
4150@media (max-width: 380px) {
4151 .post-album-header { padding: .75rem; gap: .75rem; }
4152 .post-album-cover-btn .post-album-cover { max-width: 180px; }
4153 .post-album-title { font-size: 1.15rem; }
4154 .post-album-meta { font-size: .8rem; }
4155 .post-album-track-compact,
4156 .post-album-tracks .post-audio-track {
4157 grid-template-columns: 24px 1fr auto;
4158 gap: .5rem;
4159 padding: .4rem .6rem;
4160 font-size: .85rem;
4161 }
4162 .post-album-track-compact .pat-duration,
4163 .post-album-tracks .post-audio-track .pat-duration {
4164 font-size: .72rem;
4165 }
4166 /* Queue items in expand-sheet */
4167 .audio-sheet-queue-item { padding: .4rem .45rem; gap: .55rem; }
4168 .audio-sheet-queue-cover { width: 32px; height: 32px; }
4169 .audio-sheet-queue-title { font-size: .85rem; }
4170 .audio-sheet-queue-artist { font-size: .7rem; }
4171}
4172
4173/* External track (SoundCloud / YouTube / Spotify / etc) — klikbaar maar link-naar-platform */
4174.post-audio-external {
4175 display: flex;
4176 align-items: center;
4177 gap: .75rem;
4178 padding: .65rem .85rem;
4179 background: var(--paper-2, color-mix(in srgb, var(--ink) 4%, transparent));
4180 border: 1px solid var(--rule, rgba(0,0,0,.08));
4181 border-radius: 10px;
4182 margin: .75rem 0;
4183 text-decoration: none;
4184 color: var(--ink);
4185 transition: background .15s, border-color .15s;
4186}
4187.post-audio-external:hover {
4188 border-color: var(--accent);
4189 background: color-mix(in srgb, var(--accent) 5%, var(--paper-2, transparent));
4190}
4191.post-audio-external .pae-icon {
4192 flex-shrink: 0;
4193 width: 42px;
4194 height: 42px;
4195 border-radius: 8px;
4196 display: inline-flex;
4197 align-items: center;
4198 justify-content: center;
4199 background: var(--platform-color, #555);
4200 color: #fff;
4201 font-size: 1.2rem;
4202}
4203.post-audio-external .pae-icon-svg svg {
4204 width: 60%;
4205 height: 60%;
4206 fill: currentColor;
4207}
4208/* Per-platform vult de box net wat anders — brand-specifiek geoptimaliseerd */
4209.post-audio-external[data-platform="soundcloud"] .pae-icon-svg svg { width: 72%; height: auto; }
4210.post-audio-external[data-platform="spotify"] .pae-icon-svg svg { width: 72%; height: 72%; }
4211.post-audio-external[data-platform="youtube"] .pae-icon-svg svg { width: 68%; height: auto; }
4212.post-audio-external[data-platform="bandcamp"] .pae-icon-svg svg { width: 62%; height: auto; }
4213.post-audio-external[data-platform="apple"] .pae-icon-svg svg { width: 58%; height: 58%; }
4214.post-audio-external[data-platform="tidal"] .pae-icon-svg svg { width: 68%; height: auto; }
4215.post-audio-external[data-platform="deezer"] .pae-icon-svg svg { width: 65%; height: auto; }
4216.post-audio-external[data-platform="mixcloud"] .pae-icon-svg svg { width: 75%; height: auto; }
4217.post-audio-external[data-platform="soundcloud"] .pae-icon { background: #ff5500; }
4218.post-audio-external[data-platform="spotify"] .pae-icon { background: #1db954; }
4219.post-audio-external[data-platform="youtube"] .pae-icon { background: #ff0000; }
4220.post-audio-external[data-platform="bandcamp"] .pae-icon { background: #1da0c3; }
4221.post-audio-external[data-platform="apple"] .pae-icon { background: #fa243c; }
4222.post-audio-external[data-platform="tidal"] .pae-icon { background: #000; }
4223.post-audio-external[data-platform="deezer"] .pae-icon { background: #a238ff; }
4224.post-audio-external[data-platform="mixcloud"] .pae-icon { background: #314359; }
4225.post-audio-external[data-platform="other"] .pae-icon { background: #555; }
4226.post-audio-external .pae-meta {
4227 flex: 1;
4228 min-width: 0;
4229 display: flex;
4230 flex-direction: column;
4231 gap: 2px;
4232}
4233.post-audio-external .pae-title {
4234 display: block;
4235 font-weight: 600;
4236 overflow: hidden;
4237 text-overflow: ellipsis;
4238 white-space: nowrap;
4239 color: var(--ink);
4240}
4241.post-audio-external .pae-platform {
4242 display: block;
4243 font-size: .78rem;
4244 opacity: .65;
4245 text-transform: capitalize;
4246}
4247.post-audio-external .pae-go {
4248 flex-shrink: 0;
4249 opacity: .5;
4250 font-size: 1.1rem;
4251}
4252
4253/* =========================================================================
4254 v9.0 — Video player (inline)
4255 ========================================================================= */
4256
4257.post-video-figure {
4258 margin: 1.25rem 0;
4259 max-width: 100%;
4260}
4261
4262.post-video {
4263 display: block;
4264 width: 100%;
4265 max-width: 100%;
4266 height: auto;
4267 border-radius: 10px;
4268 background: #000;
4269 box-shadow: 0 4px 20px rgba(0,0,0,.15);
4270}
4271
4272.post-video-caption {
4273 margin-top: .5rem;
4274 font-size: .88rem;
4275 color: var(--ink-muted, color-mix(in srgb, var(--ink) 60%, transparent));
4276 text-align: center;
4277 line-height: 1.5;
4278}
4279
4280.post-video-caption strong {
4281 display: inline;
4282 font-weight: 600;
4283 color: var(--ink);
4284}
4285
4286@media (max-width: 640px) {
4287 .post-video-figure { margin: .75rem -.5rem; }
4288 .post-video { border-radius: 6px; }
4289}
4290
4291/* v9.3 — Floating "Bewerken" knop voor album-blokken in de post-editor.
4292 Verschijnt bij hover over een .post-album binnen #visual en wordt via JS
4293 geplaatst op de rechterbovenhoek van het blok. Niet in de opgeslagen HTML. */
4294.pcms-album-edit-overlay {
4295 position: absolute;
4296 z-index: 1000;
4297 transform: translateX(-100%);
4298 display: inline-flex;
4299 align-items: center;
4300 gap: .35rem;
4301 padding: .35rem .7rem;
4302 background: var(--accent, #c2410c);
4303 color: #fff;
4304 border: none;
4305 border-radius: 6px;
4306 font-size: .82rem;
4307 font-weight: 600;
4308 cursor: pointer;
4309 box-shadow: 0 4px 12px rgba(0, 0, 0, .18);
4310 transition: transform .12s ease, box-shadow .12s ease;
4311}
4312.pcms-album-edit-overlay:hover {
4313 transform: translateX(-100%) translateY(-1px);
4314 box-shadow: 0 6px 16px rgba(0, 0, 0, .24);
4315}
4316.pcms-album-edit-overlay:active {
4317 transform: translateX(-100%) translateY(0);
4318 box-shadow: 0 2px 6px rgba(0, 0, 0, .18);
4319}
4320
4321/* v9.3 — Drag-and-drop in de album-builder selected-lijst */
4322.ab-selected-row { cursor: default; }
4323.ab-selected-row .ab-drag-handle {
4324 display: inline-flex;
4325 align-items: center;
4326 justify-content: center;
4327 width: 18px;
4328 height: 100%;
4329 color: color-mix(in srgb, currentColor 40%, transparent);
4330 cursor: grab;
4331 user-select: none;
4332 font-size: .9rem;
4333 letter-spacing: -2px;
4334 flex-shrink: 0;
4335}
4336.ab-selected-row:hover .ab-drag-handle {
4337 color: color-mix(in srgb, currentColor 70%, transparent);
4338}
4339.ab-selected-row.is-dragging {
4340 opacity: .35;
4341 cursor: grabbing;
4342}
4343.ab-selected-row.is-dragging .ab-drag-handle { cursor: grabbing; }
4344/* Drop-indicator lijnen boven/onder de target rij */
4345.ab-selected-row.is-drag-target-before {
4346 box-shadow: 0 -2px 0 0 var(--accent, #c2410c) inset, 0 2px 0 0 var(--accent, #c2410c);
4347 /* Gebruik outline voor cross-browser zichtbaarheid */
4348 position: relative;
4349}
4350.ab-selected-row.is-drag-target-before::before {
4351 content: "";
4352 position: absolute;
4353 top: -1px; left: 0; right: 0;
4354 height: 2px;
4355 background: var(--accent, #c2410c);
4356 pointer-events: none;
4357}
4358.ab-selected-row.is-drag-target-after::after {
4359 content: "";
4360 position: absolute;
4361 bottom: -1px; left: 0; right: 0;
4362 height: 2px;
4363 background: var(--accent, #c2410c);
4364 pointer-events: none;
4365}
4366.ab-selected-row.is-drag-target-after { position: relative; }
4367
4368/* v9.3 — Playlist fallback states (missing of empty playlist reference in post) */
4369.post-playlist-missing, .post-playlist-empty {
4370 padding: 1rem;
4371 margin: .75rem 0;
4372 background: color-mix(in srgb, var(--accent, #c2410c) 8%, transparent);
4373 border: 1px dashed color-mix(in srgb, var(--accent, #c2410c) 30%, transparent);
4374 border-radius: 8px;
4375 font-size: .9rem;
4376}
4377.post-playlist-missing em, .post-playlist-empty em {
4378 opacity: .8;
4379}
4380
4381/* v9.3 — Install-app footer-knop */
4382.site-footer-install {
4383 display: flex;
4384 justify-content: center;
4385 padding: 1rem 1rem 1.25rem;
4386 border-top: 1px solid color-mix(in srgb, currentColor 8%, transparent);
4387 margin-top: .5rem;
4388}
4389
4390/* v9.4 — Cooler install-knop: gradient + shimmer + perfect centering.
4391 Twee kleur-stops voor diepte, animated shimmer-streep om aandacht te trekken,
4392 icon perfect verticaal gecentreerd via flex (was: net iets te hoog tov tekst). */
4393.install-app-btn {
4394 position: relative;
4395 display: inline-flex;
4396 align-items: center;
4397 justify-content: center;
4398 gap: .55rem;
4399 padding: .8rem 1.6rem;
4400 background: linear-gradient(135deg,
4401 var(--accent, #c2410c),
4402 color-mix(in srgb, var(--accent, #c2410c) 80%, #000));
4403 color: #fff;
4404 border: none;
4405 border-radius: 999px;
4406 font: inherit;
4407 font-weight: 600;
4408 font-size: .95rem;
4409 line-height: 1;
4410 letter-spacing: .01em;
4411 cursor: pointer;
4412 overflow: hidden;
4413 isolation: isolate;
4414 box-shadow:
4415 0 1px 0 rgba(255,255,255,.15) inset,
4416 0 -2px 0 rgba(0,0,0,.1) inset,
4417 0 4px 14px color-mix(in srgb, var(--accent, #c2410c) 40%, transparent),
4418 0 1px 3px rgba(0,0,0,.18);
4419 transition:
4420 transform .15s cubic-bezier(.4, 0, .2, 1),
4421 box-shadow .2s ease,
4422 filter .15s ease;
4423}
4424.install-app-btn svg {
4425 flex-shrink: 0;
4426 /* subtle bounce-on-hover trigger, separate animation */
4427 transition: transform .25s cubic-bezier(.34, 1.56, .64, 1);
4428}
4429.install-app-btn span {
4430 line-height: 1;
4431}
4432
4433/* Shimmer-streep die langzaam over de knop loopt — "alive" effect */
4434.install-app-btn::before {
4435 content: "";
4436 position: absolute;
4437 top: 0;
4438 left: -100%;
4439 width: 60%;
4440 height: 100%;
4441 background: linear-gradient(110deg,
4442 transparent 30%,
4443 rgba(255,255,255,.25) 50%,
4444 transparent 70%);
4445 z-index: -1;
4446 animation: pcmsInstallShimmer 4s ease-in-out infinite;
4447 pointer-events: none;
4448}
4449@keyframes pcmsInstallShimmer {
4450 0%, 35% { left: -100%; }
4451 65%, 100% { left: 200%; }
4452}
4453
4454.install-app-btn:hover {
4455 transform: translateY(-2px) scale(1.02);
4456 filter: brightness(1.06);
4457 box-shadow:
4458 0 1px 0 rgba(255,255,255,.2) inset,
4459 0 -2px 0 rgba(0,0,0,.1) inset,
4460 0 8px 24px color-mix(in srgb, var(--accent, #c2410c) 55%, transparent),
4461 0 2px 6px rgba(0,0,0,.2);
4462}
4463.install-app-btn:hover svg {
4464 transform: translateY(-2px);
4465}
4466.install-app-btn:active {
4467 transform: translateY(0) scale(.98);
4468 transition-duration: .05s;
4469}
4470.install-app-btn:focus-visible {
4471 outline: 2px solid var(--accent, #c2410c);
4472 outline-offset: 3px;
4473}
4474
4475/* Reduced motion: shimmer uit, alleen statisch */
4476@media (prefers-reduced-motion: reduce) {
4477 .install-app-btn::before { animation: none; left: -100%; }
4478 .install-app-btn:hover { transform: none; }
4479 .install-app-btn:hover svg { transform: none; }
4480}
4481
4482/* Install-instructions modal */
4483.install-modal {
4484 position: fixed;
4485 inset: 0;
4486 z-index: 10000;
4487 display: flex;
4488 align-items: center;
4489 justify-content: center;
4490 padding: 1rem;
4491}
4492.install-modal-backdrop {
4493 position: absolute;
4494 inset: 0;
4495 background: rgba(0,0,0,.55);
4496 backdrop-filter: blur(3px);
4497}
4498.install-modal-panel {
4499 position: relative;
4500 z-index: 1;
4501 background: var(--paper);
4502 color: var(--ink);
4503 border: 1px solid var(--rule);
4504 border-radius: 14px;
4505 padding: 1.5rem;
4506 max-width: 440px;
4507 width: 100%;
4508 max-height: 90vh;
4509 overflow-y: auto;
4510 box-shadow: 0 20px 60px rgba(0,0,0,.4);
4511}
4512.install-modal-panel h3 { font-size: 1.15rem; color: var(--ink); }
4513.install-modal-panel h4 {
4514 margin: 1rem 0 .4rem;
4515 font-size: .92rem;
4516 letter-spacing: .03em;
4517 text-transform: uppercase;
4518 opacity: .7;
4519 color: var(--ink);
4520}
4521.install-modal-panel p { color: var(--ink); }
4522.install-steps {
4523 margin: 0;
4524 padding-left: 1.35rem;
4525 display: flex;
4526 flex-direction: column;
4527 gap: .45rem;
4528 font-size: .95rem;
4529 line-height: 1.45;
4530 color: var(--ink);
4531}
4532.install-steps li::marker { color: var(--accent); font-weight: 700; }
4533.install-apk-block {
4534 margin-top: 1.25rem;
4535 padding-top: 1rem;
4536 border-top: 1px dashed var(--rule);
4537}
4538.install-apk-link {
4539 display: inline-flex;
4540 align-items: center;
4541 margin-top: .4rem;
4542 padding: .6rem 1rem;
4543 background: var(--accent);
4544 color: #fff;
4545 border-radius: 8px;
4546 text-decoration: none;
4547 font-weight: 600;
4548}
4549.install-apk-link:hover { filter: brightness(1.08); }
4550.install-modal-actions {
4551 display: flex;
4552 justify-content: flex-end;
4553 margin-top: 1.25rem;
4554}
4555.install-modal-actions .btn {
4556 padding: .5rem 1rem;
4557 background: var(--paper-2);
4558 border: 1px solid var(--rule);
4559 border-radius: 8px;
4560 color: var(--ink);
4561 cursor: pointer;
4562 font: inherit;
4563 font-weight: 500;
4564}
4565.install-modal-actions .btn:hover {
4566 background: color-mix(in srgb, var(--accent) 10%, var(--paper-2));
4567 border-color: var(--accent);
4568 color: var(--accent);
4569}
4570
4571@media (max-width: 520px) {
4572 .install-modal-panel { padding: 1.2rem; }
4573 .install-app-btn { width: 100%; justify-content: center; }
4574}
4575
4576/* v9.3 — Install-modal: choice-blocks met voor/nadelen */
4577.install-choice {
4578 margin-top: 1.25rem;
4579 padding: 1rem;
4580 border: 1px solid color-mix(in srgb, currentColor 15%, transparent);
4581 border-radius: 10px;
4582 background: color-mix(in srgb, currentColor 3%, transparent);
4583}
4584.install-choice + .install-choice { margin-top: 1rem; }
4585.install-choice h4 {
4586 margin: 0 0 .75rem;
4587 font-size: 1rem;
4588 letter-spacing: 0;
4589 text-transform: none;
4590 opacity: 1;
4591}
4592.install-pros-cons {
4593 display: flex;
4594 gap: 1rem;
4595 margin: .5rem 0 1rem;
4596}
4597.install-pros,
4598.install-cons {
4599 flex: 1;
4600 min-width: 0;
4601 font-size: .85rem;
4602 line-height: 1.45;
4603}
4604.install-pros strong,
4605.install-cons strong {
4606 display: block;
4607 margin-bottom: .35rem;
4608 font-size: .82rem;
4609 letter-spacing: .02em;
4610}
4611.install-pros strong { color: #16a34a; }
4612.install-cons strong { color: #dc2626; }
4613.install-pros ul,
4614.install-cons ul {
4615 margin: 0;
4616 padding-left: 1.1rem;
4617 display: flex;
4618 flex-direction: column;
4619 gap: .25rem;
4620}
4621.install-pros li::marker { color: #16a34a; }
4622.install-cons li::marker { color: #dc2626; }
4623
4624.install-choice-cta {
4625 display: inline-flex;
4626 align-items: center;
4627 justify-content: center;
4628 gap: .35rem;
4629 margin-top: .5rem;
4630 padding: .7rem 1.1rem;
4631 background: var(--accent, #c2410c);
4632 color: #fff;
4633 border: none;
4634 border-radius: 8px;
4635 text-decoration: none;
4636 font: inherit;
4637 font-weight: 600;
4638 font-size: .95rem;
4639 cursor: pointer;
4640 transition: filter .12s ease;
4641}
4642.install-choice-cta:hover { filter: brightness(1.08); }
4643.install-choice-note {
4644 margin: .5rem 0 0;
4645 padding: .6rem .8rem;
4646 background: color-mix(in srgb, currentColor 4%, transparent);
4647 border-left: 3px solid var(--accent, #c2410c);
4648 border-radius: 4px;
4649 font-size: .9rem;
4650 line-height: 1.45;
4651}
4652
4653@media (max-width: 520px) {
4654 .install-pros-cons { flex-direction: column; gap: .75rem; }
4655}
4656
4657/* v9.4 — Soft fade-overgang tussen posts bij navigatie.
4658 Fade-out is rustig (450ms): oude content vervaagt geleidelijk terwijl
4659 de scroll-naar-top loopt. Fade-in is snel (180ms) met een lichte blur-
4660 onscherp → scherp animatie zodat de nieuwe content niet abrupt verschijnt. */
4661#pcms-main {
4662 transition: opacity .45s ease-out;
4663}
4664#pcms-main.is-pcms-transitioning-out {
4665 opacity: 0;
4666}
4667#pcms-main.is-pcms-transitioning-in {
4668 opacity: 0;
4669 filter: blur(6px);
4670 animation: pcmsFadeIn .18s ease-out forwards;
4671 will-change: opacity, filter;
4672}
4673@keyframes pcmsFadeIn {
4674 from { opacity: 0; filter: blur(6px); }
4675 to { opacity: 1; filter: blur(0); }
4676}
4677
4678/* Respecteer reduced-motion voorkeur (iOS/Android accessibility setting) */
4679@media (prefers-reduced-motion: reduce) {
4680 #pcms-main {
4681 transition: opacity .15s ease-out;
4682 }
4683 #pcms-main.is-pcms-transitioning-in {
4684 filter: none;
4685 animation: none;
4686 opacity: 1;
4687 }
4688}
4689
4690/* === Fediverse interactions — inherits the native .comment styling === */
4691.post-fediverse .fedi-stats { display: flex; gap: .45rem; margin: .35rem 0 1.5rem; align-items: center; }
4692.post-fediverse .fedi-stat {
4693 display: inline-flex; align-items: center; gap: .4rem;
4694 padding: .32rem .7rem; border-radius: 999px; font-size: .85rem; line-height: 1;
4695 font-variant-numeric: tabular-nums;
4696 color: var(--ink-muted); background: transparent;
4697 border: 1px solid var(--rule);
4698}
4699.post-fediverse .fedi-stat svg { width: 15px; height: 15px; }
4700.post-fediverse .fedi-stat-btn { cursor: pointer; font: inherit; line-height: 1; transition: color .15s, border-color .15s, background .15s; }
4701.post-fediverse .fedi-stat-btn:hover { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 55%, var(--rule)); background: var(--accent-tint); }
4702.post-fediverse .fedi-stat-btn:hover svg { fill: color-mix(in srgb, var(--accent) 22%, transparent); }
4703.post-fediverse .fedi-handle { color: var(--ink-soft, #888); font-size: .82rem; }
4704.post-fediverse .comment-content p { margin: .2rem 0; }
4705.post-fediverse .comment-content p:first-child { margin-top: 0; }
4706.post-fediverse .comment-content p:last-child { margin-bottom: 0; }
4707/* reply toggle: a plain "Reageer" action like the comment buttons (no triangle) */
4708.post-fediverse .fedi-reply-toggle { list-style: none; cursor: pointer; display: inline-block; }
4709.post-fediverse .fedi-reply-toggle::-webkit-details-marker { display: none; }
4710.post-fediverse details[open] .fedi-reply-toggle { margin-bottom: .5rem; }
4711
4712/* Reply-via-fediverse CTA on post pages */
4713.post-fediverse-cta { margin: 1.75rem 0; }
4714.fedi-remote-reply-btn { display: inline-flex; align-items: center; gap: .45rem; }
4715.post-fediverse-cta .fedi-remote-reply-btn {
4716 border: 1px solid color-mix(in srgb, var(--accent, #888) 55%, transparent);
4717 background: color-mix(in srgb, var(--accent, #888) 10%, transparent);
4718 color: var(--ink, inherit); border-radius: 999px; padding: .5rem 1.05rem;
4719 font-weight: 600; cursor: pointer; transition: background .15s ease;
4720}
4721.post-fediverse-cta .fedi-remote-reply-btn:hover { background: color-mix(in srgb, var(--accent, #888) 22%, transparent); }
4722.post-fediverse-cta .fedi-remote-reply-btn svg { color: var(--accent, currentColor); }
4723.post-fediverse .comment-actions .fedi-remote-reply-btn { gap: .3rem; }
4724
4725/* Inline "reply via fediverse" address form (replaces the browser prompt) */
4726.fedi-remote-form {
4727 position: absolute; z-index: 60; display: inline-flex; align-items: center; gap: .4rem;
4728 padding: .4rem; border-radius: 999px;
4729 background: var(--paper-2, var(--paper, #fff));
4730 border: 1px solid color-mix(in srgb, var(--ink, #000) 12%, transparent);
4731 box-shadow: 0 10px 30px rgba(0,0,0,.28);
4732}
4733.fedi-remote-form input {
4734 height: 2.2rem; padding: 0 .9rem; border-radius: 999px; font: inherit; min-width: 230px;
4735 border: 1px solid color-mix(in srgb, var(--ink, #000) 18%, transparent);
4736 background: color-mix(in srgb, var(--ink, #000) 4%, transparent); color: var(--ink, #000);
4737}
4738.fedi-remote-form input::placeholder { color: var(--ink-soft, #999); }
4739.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); }
4740.fedi-remote-form .fedi-remote-go {
4741 height: 2.2rem; min-width: 2.2rem; padding: 0 .85rem; border-radius: 999px;
4742 display: inline-flex; align-items: center; justify-content: center; font-size: 1rem;
4743}
4744.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; }
4745.fedi-remote-form .fedi-remote-cancel:hover { color: var(--ink, #000); }
4746
4747/* ── NSFW / sensitive content — blur + click to reveal ───────────────── */
4748.nsfw-media { position: relative; }
4749.nsfw-veil {
4750 position: absolute; inset: 0; z-index: 4; cursor: pointer; border-radius: inherit;
4751 display: flex; flex-direction: column; align-items: center; justify-content: center;
4752 gap: .5rem; padding: .75rem; text-align: center;
4753 background: color-mix(in srgb, var(--paper, #14141a) 50%, transparent);
4754 backdrop-filter: blur(22px) saturate(.6); -webkit-backdrop-filter: blur(22px) saturate(.6);
4755}
4756.nsfw-media.is-shown > .nsfw-veil { display: none; }
4757.nsfw-veil-label { font-weight: 700; font-size: .82rem; color: var(--ink, #f3f1ea); text-shadow: 0 1px 2px rgba(0,0,0,.5); }
4758.nsfw-veil-btn {
4759 font-size: .72rem; font-weight: 600; padding: .3rem .8rem; border-radius: 999px;
4760 border: 1px solid color-mix(in srgb, var(--ink, #fff) 55%, transparent);
4761 background: color-mix(in srgb, var(--paper, #000) 35%, transparent); color: var(--ink, #f3f1ea);
4762}
4763/* Post page: blur cover + body behind a content-warning banner until revealed */
4764.nsfw-gate .post-cover,
4765.nsfw-gate .post-content { filter: blur(26px); pointer-events: none; user-select: none; transition: filter .2s ease; }
4766.nsfw-gate.is-shown .post-cover,
4767.nsfw-gate.is-shown .post-content { filter: none; pointer-events: auto; user-select: auto; }
4768.nsfw-banner {
4769 display: flex; align-items: center; gap: .7rem; flex-wrap: wrap; margin: 0 0 1.5rem;
4770 padding: .8rem 1rem; border-radius: 12px;
4771 border: 1px solid color-mix(in srgb, var(--accent, #e8b04b) 45%, transparent);
4772 background: color-mix(in srgb, var(--accent, #e8b04b) 9%, transparent);
4773}
4774.nsfw-gate.is-shown .nsfw-banner { display: none; }
4775.nsfw-banner-icon { font-size: 1.2rem; }
4776.nsfw-banner-text { font-weight: 600; font-size: .92rem; color: var(--ink); }
4777.nsfw-banner-btn {
4778 margin-left: auto; cursor: pointer; font: inherit; font-size: .82rem; font-weight: 600;
4779 padding: .4rem 1rem; border-radius: 999px; border: 0;
4780 background: var(--accent, #e8b04b); color: #1a1205;
4781}
Note: See TracBrowser for help on using the repository browser.