static/styles.css 8.6 K raw
1
/* feeds — self-contained styles.
2
 * Black-on-white inversion of the darkmatter design system.
3
 */
4
5
@font-face {
6
  font-family: "Commit Mono";
7
  src: url("/static/fonts/CommitMono-400-Regular.otf") format("opentype");
8
  font-weight: 400;
9
  font-style: normal;
10
  font-display: swap;
11
}
12
13
@font-face {
14
  font-family: "Commit Mono";
15
  src: url("/static/fonts/CommitMono-700-Regular.otf") format("opentype");
16
  font-weight: 700;
17
  font-style: normal;
18
  font-display: swap;
19
}
20
21
/* ── Reset + webkit hardening ─────────────────────────────────────── */
22
23
*,
24
*::before,
25
*::after {
26
  padding: 0;
27
  margin: 0;
28
  box-sizing: border-box;
29
  font-family: "Commit Mono", monospace, sans-serif;
30
  -webkit-tap-highlight-color: transparent;
31
}
32
33
* {
34
  scrollbar-width: none;
35
  -ms-overflow-style: none;
36
}
37
38
html {
39
  background: #ffffff;
40
  color: #1a1a1a;
41
  font-size: 14px;
42
  line-height: 1.6;
43
  -webkit-text-size-adjust: 100%;
44
  text-size-adjust: 100%;
45
}
46
47
html::-webkit-scrollbar {
48
  display: none;
49
}
50
51
body {
52
  display: flex;
53
  flex-direction: column;
54
  justify-content: start;
55
  align-items: start;
56
  gap: 1.5rem;
57
  min-height: 100vh;
58
  max-width: 700px;
59
  margin: auto;
60
  padding: 0 1rem 4rem;
61
}
62
63
@media (max-width: 480px) {
64
  body {
65
    padding: 1rem;
66
    gap: 1rem;
67
  }
68
}
69
70
/* ── Links ────────────────────────────────────────────────────────── */
71
72
a {
73
  color: #1a1a1a;
74
  text-decoration: none;
75
  touch-action: manipulation;
76
}
77
78
a:hover {
79
  opacity: 0.7;
80
}
81
82
/* ── Header / nav ─────────────────────────────────────────────────── */
83
84
.header {
85
  display: flex;
86
  flex-direction: column;
87
  gap: 0.5rem;
88
  width: 100%;
89
  margin-top: 2rem;
90
  border-bottom: 1px solid #ddd;
91
  padding-bottom: 1rem;
92
}
93
94
.logo {
95
  font-size: 28px;
96
  font-weight: 700;
97
  text-decoration: none;
98
}
99
100
.logo h1 {
101
  font-size: 28px;
102
  font-weight: 700;
103
}
104
105
.links {
106
  display: flex;
107
  align-items: center;
108
  gap: 0.75rem;
109
  font-size: 12px;
110
}
111
112
/* ── Forms ────────────────────────────────────────────────────────── */
113
114
label {
115
  font-size: 12px;
116
  opacity: 0.7;
117
}
118
119
input,
120
textarea,
121
select {
122
  background: #ffffff;
123
  color: #1a1a1a;
124
  border: 1px solid #1a1a1a;
125
  padding: 0.4rem 0.75rem;
126
  font-size: 16px; /* 16px prevents iOS focus zoom */
127
  width: 100%;
128
  border-radius: 0;
129
  -webkit-appearance: none;
130
  appearance: none;
131
  outline: none;
132
}
133
134
input:focus,
135
textarea:focus,
136
select:focus {
137
  outline: none;
138
}
139
140
/* ── Buttons ──────────────────────────────────────────────────────── */
141
142
button,
143
.btn {
144
  background: #ffffff;
145
  color: #1a1a1a;
146
  padding: 0.2rem 0.75rem;
147
  border: 1px solid #1a1a1a;
148
  cursor: pointer;
149
  width: fit-content;
150
  font-size: 14px;
151
  line-height: 1.4;
152
  border-radius: 0;
153
  -webkit-appearance: none;
154
  appearance: none;
155
  text-decoration: none;
156
  display: inline-block;
157
  touch-action: manipulation;
158
}
159
160
button:hover,
161
.btn:hover {
162
  opacity: 0.7;
163
}
164
165
button:disabled {
166
  opacity: 0.3;
167
  cursor: default;
168
}
169
170
button.loading {
171
  cursor: wait;
172
}
173
174
.link-button {
175
  background: none;
176
  border: none;
177
  color: #1a1a1a;
178
  cursor: pointer;
179
  font-size: 12px;
180
  padding: 0;
181
  font-family: inherit;
182
  -webkit-appearance: none;
183
  appearance: none;
184
}
185
186
.link-button:hover {
187
  opacity: 0.7;
188
}
189
190
.link-button.danger {
191
  opacity: 0.5;
192
}
193
194
.link-button.danger:hover {
195
  opacity: 0.3;
196
}
197
198
/* ── Feedback ─────────────────────────────────────────────────────── */
199
200
.error {
201
  color: #1a1a1a;
202
  border-left: 2px solid #1a1a1a;
203
  padding-left: 0.5rem;
204
  font-size: 13px;
205
  opacity: 0.8;
206
}
207
208
.hint {
209
  font-size: 12px;
210
  opacity: 0.5;
211
  line-height: 1.4;
212
}
213
214
/* ── Spinner (braille) ────────────────────────────────────────────── */
215
216
.spinner::after {
217
  content: "⠋";
218
  display: inline-block;
219
  margin-left: 0.4rem;
220
  animation: braille-spin 0.8s steps(10) infinite;
221
}
222
223
@keyframes braille-spin {
224
  0%   { content: "⠋"; }
225
  10%  { content: "⠙"; }
226
  20%  { content: "⠹"; }
227
  30%  { content: "⠸"; }
228
  40%  { content: "⠼"; }
229
  50%  { content: "⠴"; }
230
  60%  { content: "⠦"; }
231
  70%  { content: "⠧"; }
232
  80%  { content: "⠇"; }
233
  90%  { content: "⠏"; }
234
}
235
236
/* ── Utility ─────────────────────────────────────────────────────── */
237
238
.hidden {
239
  display: none;
240
}
241
242
/* ── About / intro ───────────────────────────────────────────────── */
243
244
.about {
245
  display: flex;
246
  flex-direction: column;
247
  gap: 0.5rem;
248
  font-size: 14px;
249
  line-height: 1.25rem;
250
}
251
252
/* ── Builder ─────────────────────────────────────────────────────── */
253
254
.builder {
255
  display: flex;
256
  flex-direction: column;
257
  gap: 1rem;
258
  width: 100%;
259
}
260
261
.discover-row {
262
  display: flex;
263
  gap: 0.5rem;
264
  width: 100%;
265
}
266
267
.discover-row input {
268
  flex: 1;
269
}
270
271
.chips {
272
  display: flex;
273
  flex-wrap: wrap;
274
  gap: 0.5rem;
275
}
276
277
.chip {
278
  display: inline-flex;
279
  align-items: center;
280
  gap: 0.4rem;
281
  font-size: 12px;
282
  padding: 2px 8px;
283
  border: 1px solid #ddd;
284
  opacity: 0.7;
285
}
286
287
.chip:hover {
288
  border-color: #bbb;
289
  opacity: 1;
290
}
291
292
.pending-list {
293
  list-style: none;
294
  display: flex;
295
  flex-direction: column;
296
  width: 100%;
297
}
298
299
.pending-list li {
300
  display: flex;
301
  align-items: center;
302
  gap: 0.5rem;
303
  padding: 0.4rem 0;
304
  border-bottom: 1px solid #ddd;
305
  min-width: 0;
306
}
307
308
.favicon {
309
  width: 16px;
310
  height: 16px;
311
  flex-shrink: 0;
312
}
313
314
.pending-list li:last-child {
315
  border-bottom: none;
316
}
317
318
.pending-label {
319
  font-size: 14px;
320
  flex-shrink: 0;
321
}
322
323
.pending-url {
324
  flex: 1;
325
  font-size: 12px;
326
  opacity: 0.5;
327
  overflow: hidden;
328
  white-space: nowrap;
329
  text-overflow: ellipsis;
330
}
331
332
/* ── Feeds list ──────────────────────────────────────────────────── */
333
334
#feeds-container {
335
  width: 100%;
336
}
337
338
.feeds-list {
339
  width: 100%;
340
  display: flex;
341
  flex-direction: column;
342
  gap: 1.5rem;
343
}
344
345
.feed-item {
346
  width: 100%;
347
  display: flex;
348
  flex-direction: column;
349
  gap: 0.5rem;
350
  padding: 1rem 0;
351
  border-bottom: 1px solid #ddd;
352
}
353
354
.feed-item:last-child {
355
  border-bottom: none;
356
}
357
358
.feed-meta {
359
  display: flex;
360
  justify-content: space-between;
361
  align-items: center;
362
  font-size: 12px;
363
  opacity: 0.5;
364
}
365
366
.feed-title {
367
  font-size: 16px;
368
  font-weight: 400;
369
  line-height: 1.4;
370
}
371
372
.feed-title a {
373
  text-decoration: none;
374
}
375
376
.feed-author {
377
  font-size: 12px;
378
  opacity: 0.5;
379
  font-style: italic;
380
}
381
382
#feed-urls {
383
  font-size: 12px;
384
  opacity: 0.5;
385
}
386
387
#error {
388
  padding: 2rem 0;
389
}
390
391
/* ── Now what? (details dropdown) ────────────────────────────────── */
392
393
.now-what {
394
  width: 100%;
395
  margin-top: -0.5rem;
396
}
397
398
.now-what summary {
399
  font-size: 12px;
400
  opacity: 0.6;
401
  cursor: pointer;
402
  width: fit-content;
403
  list-style: none;
404
  text-decoration: underline;
405
  text-underline-offset: 2px;
406
}
407
408
.now-what summary::-webkit-details-marker {
409
  display: none;
410
}
411
412
.now-what summary:hover {
413
  opacity: 1;
414
}
415
416
.now-what[open] summary {
417
  opacity: 1;
418
}
419
420
.now-what-body {
421
  margin-top: 0.75rem;
422
  padding: 0.75rem 1rem;
423
  border: 1px solid #ddd;
424
  font-size: 13px;
425
  line-height: 1.5;
426
  display: flex;
427
  flex-direction: column;
428
  gap: 0.5rem;
429
}
430
431
.now-what-body ul {
432
  display: flex;
433
  flex-direction: column;
434
  gap: 0.5rem;
435
  padding-left: 1.1rem;
436
}
437
438
.now-what-body a {
439
  text-decoration: underline;
440
  text-underline-offset: 2px;
441
}
442
443
/* ── Footer ──────────────────────────────────────────────────────── */
444
445
.footer {
446
  display: flex;
447
  gap: 1rem;
448
  width: 100%;
449
  margin-top: auto;
450
  padding-top: 1rem;
451
  border-top: 1px solid #ddd;
452
  font-size: 12px;
453
  opacity: 0.6;
454
}
455
456
.footer a:hover {
457
  opacity: 1;
458
}
459
460
@media (max-width: 480px) {
461
  .feed-meta {
462
    flex-direction: column;
463
    align-items: flex-start;
464
    gap: 0.25rem;
465
  }
466
467
  .feed-title {
468
    font-size: 14px;
469
  }
470
}