@binarynoir/vitepress-blog 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/style.css CHANGED
@@ -10,6 +10,9 @@
10
10
  --vp-blog-tag-bg: var(--vp-c-default-soft);
11
11
  --vp-blog-tag-color: var(--vp-c-text-2);
12
12
  --vp-blog-accent: var(--vp-c-brand-1);
13
+ --vp-blog-browse-bg: transparent;
14
+ /* Width of the label column in the browse panel, so every row's chips line up. */
15
+ --vp-blog-facet-label-width: 6.5rem;
13
16
  --vp-blog-announcement-height: 40px;
14
17
  --vp-blog-announcement-bg: var(--vp-button-brand-bg);
15
18
  --vp-blog-announcement-color: var(--vp-button-brand-text);
@@ -46,7 +49,7 @@
46
49
  border-color: var(--vp-blog-accent);
47
50
  }
48
51
 
49
- .vp-blog-card--sticky {
52
+ .vp-blog-card--pinned {
50
53
  border-color: var(--vp-blog-accent);
51
54
  }
52
55
 
@@ -86,6 +89,28 @@
86
89
  padding: 16px 20px 20px;
87
90
  }
88
91
 
92
+ /* The category, above the title: a small linked eyebrow. */
93
+ .vp-blog-card__category {
94
+ margin-bottom: -4px;
95
+ font-size: 12px;
96
+ font-weight: 600;
97
+ letter-spacing: 0.06em;
98
+ line-height: 1.4;
99
+ text-transform: uppercase;
100
+ }
101
+
102
+ .vp-blog-card .vp-blog-card__category a {
103
+ color: var(--vp-blog-accent);
104
+ font-weight: 600;
105
+ text-decoration: none;
106
+ }
107
+
108
+ .vp-blog-card .vp-blog-card__category a:hover,
109
+ .vp-blog-card .vp-blog-card__category a.is-active {
110
+ text-decoration: underline;
111
+ text-underline-offset: 3px;
112
+ }
113
+
89
114
  .vp-blog-card__title {
90
115
  font-size: 18px;
91
116
  font-weight: 600;
@@ -165,9 +190,11 @@
165
190
  }
166
191
 
167
192
  .vp-blog-tag,
193
+ .vp-blog-category,
168
194
  .vp-blog-badge,
169
- .vp-blog-tags a,
195
+ .vp-blog-facet__chips a,
170
196
  .vp-blog-card__tags a,
197
+ .vp-blog-byline__category a,
171
198
  .vp-blog-byline__tags a {
172
199
  display: inline-block;
173
200
  margin: 2px 4px 2px 0;
@@ -177,29 +204,51 @@
177
204
  color: var(--vp-blog-tag-color);
178
205
  font-size: 12px;
179
206
  font-weight: 500;
180
- line-height: 22px;
207
+ /* 24px: the smallest target WCAG 2.2 AA allows. Touch screens get more below. */
208
+ line-height: 24px;
181
209
  }
182
210
 
183
- /* Keyword chips are links that filter their blog. */
184
- .vp-blog .vp-blog-tags a,
211
+ /* Chips you tap are 32px high on touch screens. */
212
+ @media (pointer: coarse) {
213
+ .vp-blog-facet__chips a,
214
+ .vp-blog-card__tags a,
215
+ .vp-blog-byline__category a,
216
+ .vp-blog-byline__tags a {
217
+ line-height: 32px;
218
+ }
219
+ }
220
+
221
+ /* Chips are links that filter their blog. */
222
+ .vp-blog .vp-blog-facet__chips a,
185
223
  .vp-blog .vp-blog-card__tags a,
224
+ .vp-blog-byline__category a,
186
225
  .vp-blog-byline__tags a {
187
226
  text-decoration: none;
188
227
  transition:
189
228
  background-color 0.25s,
190
- color 0.25s;
229
+ color 0.25s,
230
+ opacity 0.25s;
191
231
  }
192
232
 
193
- .vp-blog .vp-blog-tags a:hover,
233
+ .vp-blog .vp-blog-facet__chips a:hover,
194
234
  .vp-blog .vp-blog-card__tags a:hover,
235
+ .vp-blog-byline__category a:hover,
195
236
  .vp-blog-byline__tags a:hover,
196
- .vp-blog-tags a.is-active,
197
- .vp-blog-card__tags a.is-active {
237
+ .vp-blog .vp-blog-facet__chips a.is-active,
238
+ .vp-blog .vp-blog-card__tags a.is-active {
198
239
  background: var(--vp-c-brand-soft);
199
240
  color: var(--vp-blog-accent);
200
241
  }
201
242
 
202
- .vp-blog-badge--sticky {
243
+ /* A post's category in its byline: a chip in the accent, ahead of its keywords. */
244
+ .vp-blog-category,
245
+ .vp-blog-byline__category a {
246
+ background: var(--vp-c-brand-soft);
247
+ color: var(--vp-blog-accent);
248
+ font-weight: 600;
249
+ }
250
+
251
+ .vp-blog-badge--pinned {
203
252
  background: var(--vp-c-brand-soft);
204
253
  color: var(--vp-c-brand-1);
205
254
  }
@@ -266,29 +315,70 @@
266
315
  }
267
316
  }
268
317
 
269
- /* The blog: keyword list, filter banner, pinned posts and page links. */
318
+ /* The blog: browse panel, active filters, pinned posts and page links. */
270
319
  .vp-blog {
271
320
  scroll-margin-top: calc(var(--vp-nav-height, 64px) + 24px);
272
321
  }
273
322
 
274
- .vp-blog-tags {
275
- margin: 16px 0 8px;
276
- line-height: 2;
323
+ /*
324
+ * The browse panel: one row each for categories, keywords and years, and the
325
+ * months of the year in view below the years. A flat toolbar between two
326
+ * rules, so it reads as a tool rather than another post. On wide screens the
327
+ * labels sit in a column of their own and chips wrap; on narrow ones each row
328
+ * is a single line that scrolls sideways.
329
+ */
330
+ .vp-blog-browse {
331
+ display: flex;
332
+ flex-direction: column;
333
+ gap: 8px;
334
+ margin: 16px 0;
335
+ padding: 12px 0;
336
+ border-top: 1px solid var(--vp-c-divider);
337
+ border-bottom: 1px solid var(--vp-c-divider);
338
+ background: var(--vp-blog-browse-bg);
277
339
  }
278
340
 
279
- .vp-blog-tags p {
280
- margin: 0;
341
+ .vp-blog-facet {
342
+ display: grid;
343
+ /* Label, chips, then "+N more" and the "Subscribe" link when the row has them. */
344
+ grid-template-columns: var(--vp-blog-facet-label-width) minmax(0, 1fr) auto auto;
345
+ gap: 4px 12px;
346
+ align-items: baseline;
281
347
  }
282
348
 
283
- .vp-blog-tags__label {
284
- margin-right: 8px;
349
+ .vp-blog-facet__label {
285
350
  color: var(--vp-blog-meta-color);
286
- font-size: 14px;
351
+ font-size: 13px;
287
352
  font-weight: 600;
353
+ line-height: 28px;
288
354
  }
289
355
 
290
- /* The post count in a keyword pill: a small counter badge inside it. */
291
- .vp-blog-tags__count {
356
+ /* A year's months, under the years: their label is the year. */
357
+ .vp-blog-facet--month .vp-blog-facet__label {
358
+ font-variant-numeric: tabular-nums;
359
+ font-weight: 500;
360
+ }
361
+
362
+ .vp-blog-facet__chips {
363
+ min-width: 0;
364
+ }
365
+
366
+ .vp-blog-facet__chips p {
367
+ display: flex;
368
+ flex-wrap: wrap;
369
+ gap: 4px 6px;
370
+ align-items: center;
371
+ margin: 0;
372
+ }
373
+
374
+ .vp-blog .vp-blog-facet__chips a {
375
+ flex: none;
376
+ margin: 0;
377
+ white-space: nowrap;
378
+ }
379
+
380
+ /* The post count in a chip: a small counter badge inside it. */
381
+ .vp-blog-facet__count {
292
382
  display: inline-block;
293
383
  min-width: 18px;
294
384
  margin-left: 6px;
@@ -307,14 +397,134 @@
307
397
  color 0.25s;
308
398
  }
309
399
 
310
- .vp-blog-tags a:hover .vp-blog-tags__count,
311
- .vp-blog-tags a.is-active .vp-blog-tags__count {
400
+ .vp-blog-facet__chips a:hover .vp-blog-facet__count,
401
+ .vp-blog-facet__chips a.is-active .vp-blog-facet__count {
312
402
  background: var(--vp-blog-accent);
313
403
  /* The page background, so the number stays readable on the accent in light and dark mode. */
314
404
  color: var(--vp-c-bg);
315
405
  }
316
406
 
407
+ /* A chip that would show no posts with the other filters kept. */
408
+ .vp-blog .vp-blog-facet__chips a.is-empty {
409
+ opacity: 0.45;
410
+ }
411
+
412
+ .vp-blog .vp-blog-facet__chips a.is-empty:hover {
413
+ opacity: 0.8;
414
+ }
415
+
416
+ /* "+N more" and "Show fewer": a quiet text button at the end of the row's first line. */
417
+ .vp-blog-facet__more {
418
+ justify-self: start;
419
+ padding: 0 6px;
420
+ border-radius: 6px;
421
+ color: var(--vp-blog-accent);
422
+ font-size: 12px;
423
+ font-weight: 600;
424
+ line-height: 28px;
425
+ white-space: nowrap;
426
+ cursor: pointer;
427
+ }
428
+
429
+ .vp-blog-facet__more:hover {
430
+ background: var(--vp-c-brand-soft);
431
+ }
432
+
433
+ /* The field that narrows a long open row, above its chips. */
434
+ .vp-blog-facet__filter {
435
+ display: block;
436
+ box-sizing: border-box;
437
+ width: min(100%, 18rem);
438
+ margin: 0 0 8px;
439
+ padding: 4px 10px;
440
+ border: 1px solid var(--vp-c-divider);
441
+ border-radius: 8px;
442
+ background: var(--vp-c-bg);
443
+ color: var(--vp-c-text-1);
444
+ font-size: 13px;
445
+ line-height: 20px;
446
+ }
447
+
448
+ .vp-blog-facet__filter:focus {
449
+ border-color: var(--vp-blog-accent);
450
+ outline: none;
451
+ }
452
+
453
+ .vp-blog-facet__empty {
454
+ margin: 0;
455
+ color: var(--vp-blog-meta-color);
456
+ font-size: 13px;
457
+ }
458
+
459
+ /* The "Subscribe" link at the end of the first row. */
460
+ .vp-blog-facet__aside p {
461
+ margin: 0;
462
+ white-space: nowrap;
463
+ }
464
+
465
+ @media (pointer: coarse) {
466
+ .vp-blog-facet__more {
467
+ line-height: 32px;
468
+ }
469
+
470
+ .vp-blog-facet__label {
471
+ line-height: 32px;
472
+ }
473
+ }
474
+
475
+ @media (max-width: 639px) {
476
+ .vp-blog-facet {
477
+ grid-template-columns: auto minmax(0, 1fr) auto auto;
478
+ gap: 4px 8px;
479
+ align-items: center;
480
+ }
481
+
482
+ .vp-blog-facet__label {
483
+ font-size: 12px;
484
+ }
485
+
486
+ /* One line per row, scrolled sideways, its end fading while there is more. */
487
+ .vp-blog-facet:not(.is-open) .vp-blog-facet__chips {
488
+ overflow-x: auto;
489
+ overscroll-behavior-x: contain;
490
+ scrollbar-width: none;
491
+ }
492
+
493
+ .vp-blog-facet:not(.is-open) .vp-blog-facet__chips::-webkit-scrollbar {
494
+ display: none;
495
+ }
496
+
497
+ .vp-blog-facet:not(.is-open) .vp-blog-facet__chips p {
498
+ flex-wrap: nowrap;
499
+ }
500
+
501
+ .vp-blog-facet.is-scrollable:not(.is-open) .vp-blog-facet__chips {
502
+ mask-image: linear-gradient(to right, #000 calc(100% - 32px), transparent);
503
+ }
504
+
505
+ /* An open row wraps under its label, at full width. */
506
+ .vp-blog-facet.is-open .vp-blog-facet__chips {
507
+ grid-column: 1 / -1;
508
+ grid-row: 2;
509
+ }
510
+
511
+ /* The RSS icon alone, its words kept for screen readers. */
512
+ .vp-blog-facet__aside .vp-blog-rss__text {
513
+ position: absolute;
514
+ width: 1px;
515
+ height: 1px;
516
+ overflow: hidden;
517
+ clip-path: inset(50%);
518
+ white-space: nowrap;
519
+ }
520
+ }
521
+
522
+ /* The active filters: how many posts match, a removable chip for each filter, and a link to clear them all. */
317
523
  .vp-blog-filter {
524
+ display: flex;
525
+ flex-wrap: wrap;
526
+ gap: 8px;
527
+ align-items: center;
318
528
  margin: 16px 0;
319
529
  padding: 10px 16px;
320
530
  border-radius: 8px;
@@ -322,15 +532,61 @@
322
532
  font-size: 14px;
323
533
  }
324
534
 
535
+ .vp-blog-filter__count {
536
+ margin-right: 4px;
537
+ color: var(--vp-c-text-1);
538
+ font-weight: 600;
539
+ }
540
+
541
+ .vp-blog .vp-blog-filter__chip {
542
+ display: inline-flex;
543
+ gap: 4px;
544
+ align-items: center;
545
+ padding: 0 4px 0 10px;
546
+ border: 1px solid var(--vp-blog-accent);
547
+ border-radius: 999px;
548
+ background: var(--vp-c-bg);
549
+ color: var(--vp-c-text-1);
550
+ font-size: 13px;
551
+ font-weight: 500;
552
+ line-height: 24px;
553
+ text-decoration: none;
554
+ }
555
+
556
+ .vp-blog-filter__kind {
557
+ color: var(--vp-blog-meta-color);
558
+ font-weight: 400;
559
+ }
560
+
561
+ .vp-blog-filter__remove {
562
+ display: inline-flex;
563
+ align-items: center;
564
+ justify-content: center;
565
+ width: 18px;
566
+ height: 18px;
567
+ border-radius: 50%;
568
+ color: var(--vp-blog-meta-color);
569
+ font-size: 14px;
570
+ line-height: 1;
571
+ transition:
572
+ background-color 0.25s,
573
+ color 0.25s;
574
+ }
575
+
576
+ .vp-blog .vp-blog-filter__chip:hover .vp-blog-filter__remove {
577
+ background: var(--vp-c-brand-soft);
578
+ color: var(--vp-blog-accent);
579
+ }
580
+
325
581
  .vp-blog-filter__clear {
326
- margin-left: 8px;
582
+ margin-left: auto;
327
583
  }
328
584
 
329
- .vp-blog-sticky {
585
+ .vp-blog-pinned {
330
586
  margin: 24px 0;
331
587
  }
332
588
 
333
- .vp-blog-sticky .vp-blog-list {
589
+ .vp-blog-pinned .vp-blog-list {
334
590
  margin: 0;
335
591
  }
336
592