@grove-dev/astro 0.4.0 → 0.5.0-next.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/package.json +3 -2
- package/src/components/CollectionIndex.astro +51 -16
- package/src/components/CollectionPage.astro +51 -35
- package/src/components/CollectionRow.astro +209 -72
- package/src/components/CollectionTeaser.astro +21 -59
- package/src/components/EditorialSummary.astro +57 -0
- package/src/components/IndexRow.astro +5 -5
- package/src/components/ItemCard.astro +11 -28
- package/src/components/LanguageBreakdown.astro +63 -0
- package/src/components/MarkdownBody.astro +37 -0
- package/src/components/RecordHeader.astro +156 -0
- package/src/components/RecordSidebar.astro +329 -0
- package/src/components/StackPlatformChips.astro +73 -0
- package/src/components/TableOfContents.astro +115 -0
- package/src/server/collections.test.ts +22 -0
- package/src/server/collections.ts +7 -0
- package/src/server/directory.ts +311 -65
- package/src/server/models.ts +155 -3
- package/src/styles.css +485 -59
package/src/styles.css
CHANGED
|
@@ -315,106 +315,532 @@
|
|
|
315
315
|
|
|
316
316
|
/* ──────────────────────────────────────────────────────────────────
|
|
317
317
|
* Rendered record Markdown
|
|
318
|
+
*
|
|
319
|
+
* The `.grove-prose` class wraps any rendered Markdown body (record
|
|
320
|
+
* sidecar or consumer-authored page). Sizing follows the editorial
|
|
321
|
+
* recipe:
|
|
322
|
+
* body 17px / 1.75
|
|
323
|
+
* h2 28px h3 21px h4 17px h5/h6 smaller, uppercase tracker
|
|
324
|
+
* The parent column owns the measure (≈760–820px on lg+), so the
|
|
325
|
+
* `.grove-prose` wrapper intentionally omits a `max-width`.
|
|
326
|
+
*
|
|
327
|
+
* Colors come from the package's `ink-*` scale via CSS variables so
|
|
328
|
+
* every consumer gets the same baseline regardless of brand overrides.
|
|
318
329
|
* ────────────────────────────────────────────────────────────────── */
|
|
319
330
|
.grove-prose {
|
|
320
|
-
|
|
321
|
-
color: var(--color-ink-800);
|
|
322
|
-
font-size: 15px;
|
|
331
|
+
font-size: 1.0625rem; /* 17px */
|
|
323
332
|
line-height: 1.75;
|
|
333
|
+
color: var(--color-ink-700, #3a3a3a);
|
|
334
|
+
overflow-wrap: break-word;
|
|
335
|
+
word-wrap: break-word;
|
|
324
336
|
}
|
|
337
|
+
.dark .grove-prose { color: var(--color-ink-200, #d4d4d4); }
|
|
338
|
+
.grove-prose > :first-child { margin-top: 0; }
|
|
339
|
+
.grove-prose > :last-child { margin-bottom: 0; }
|
|
325
340
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
font-weight: 500;
|
|
334
|
-
letter-spacing: -0.025em;
|
|
341
|
+
/* Headings — full depth. */
|
|
342
|
+
.grove-prose :where(h1, h2, h3, h4, h5, h6) {
|
|
343
|
+
font-weight: 600;
|
|
344
|
+
line-height: 1.25;
|
|
345
|
+
letter-spacing: -0.015em;
|
|
346
|
+
color: var(--color-ink-900, #1a1a1a);
|
|
347
|
+
scroll-margin-top: 5rem;
|
|
335
348
|
}
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
color: var(--color-ink-100);
|
|
349
|
+
.dark .grove-prose :where(h1, h2, h3, h4, h5, h6) {
|
|
350
|
+
color: var(--color-ink-100, #f0f0f0);
|
|
339
351
|
}
|
|
340
|
-
|
|
341
|
-
.
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
352
|
+
/* Page bodies open with a `# <Page name>` heading that duplicates
|
|
353
|
+
the page title. Hide the first heading so the body flows from a
|
|
354
|
+
top-level paragraph into sections. */
|
|
355
|
+
.grove-prose > h1:first-child { display: none; }
|
|
356
|
+
.grove-prose h1:not(:first-child) {
|
|
357
|
+
font-size: 2.5rem; /* 40px */
|
|
358
|
+
margin-top: 2.5rem; margin-bottom: 1rem;
|
|
345
359
|
}
|
|
346
|
-
|
|
347
360
|
.grove-prose h2 {
|
|
348
|
-
font-size: 1.
|
|
349
|
-
|
|
361
|
+
font-size: 1.75rem; /* 28px */
|
|
362
|
+
margin-top: 2.5rem; margin-bottom: 0.75rem;
|
|
363
|
+
padding-bottom: 0.5rem;
|
|
364
|
+
border-bottom: 1px solid var(--color-ink-200, #e5e5e5);
|
|
350
365
|
}
|
|
351
|
-
|
|
366
|
+
.dark .grove-prose h2 { border-bottom-color: var(--color-ink-800, #2a2a2a); }
|
|
352
367
|
.grove-prose h3 {
|
|
353
|
-
font-size: 1.
|
|
354
|
-
|
|
368
|
+
font-size: 1.3125rem; /* 21px */
|
|
369
|
+
margin-top: 2rem; margin-bottom: 0.5rem;
|
|
355
370
|
}
|
|
356
|
-
|
|
357
371
|
.grove-prose h4 {
|
|
358
|
-
font-size:
|
|
359
|
-
|
|
372
|
+
font-size: 1.0625rem; /* 17px */
|
|
373
|
+
margin-top: 1.5rem; margin-bottom: 0.4rem;
|
|
360
374
|
}
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
margin:
|
|
375
|
+
.grove-prose h5 {
|
|
376
|
+
font-size: 0.9375rem; /* 15px */
|
|
377
|
+
margin-top: 1.25rem; margin-bottom: 0.4rem;
|
|
378
|
+
text-transform: uppercase;
|
|
379
|
+
letter-spacing: 0.04em;
|
|
380
|
+
color: var(--color-ink-600, #555555);
|
|
364
381
|
}
|
|
382
|
+
.grove-prose h6 {
|
|
383
|
+
font-size: 0.875rem; /* 14px */
|
|
384
|
+
margin-top: 1rem; margin-bottom: 0.35rem;
|
|
385
|
+
text-transform: uppercase;
|
|
386
|
+
letter-spacing: 0.06em;
|
|
387
|
+
color: var(--color-ink-500, #6a6a6a);
|
|
388
|
+
}
|
|
389
|
+
.dark .grove-prose h5 { color: var(--color-ink-400, #8a8a8a); }
|
|
390
|
+
.dark .grove-prose h6 { color: var(--color-ink-500, #6a6a6a); }
|
|
365
391
|
|
|
392
|
+
/* Paragraphs + lists. */
|
|
393
|
+
.grove-prose p { margin: 0 0 1rem 0; }
|
|
366
394
|
.grove-prose :where(ul, ol) {
|
|
395
|
+
margin: 0 0 1rem 0;
|
|
367
396
|
padding-left: 1.5rem;
|
|
368
397
|
}
|
|
398
|
+
.grove-prose ul { list-style: disc; }
|
|
399
|
+
.grove-prose ol { list-style: decimal; }
|
|
400
|
+
.grove-prose li { margin-bottom: 0.35rem; padding-left: 0.25rem; }
|
|
401
|
+
.grove-prose li > :where(ul, ol) {
|
|
402
|
+
margin-top: 0.35rem; margin-bottom: 0;
|
|
403
|
+
}
|
|
369
404
|
|
|
370
|
-
.
|
|
371
|
-
|
|
372
|
-
|
|
405
|
+
/* Definition lists. */
|
|
406
|
+
.grove-prose dl { margin: 0 0 1rem 0; }
|
|
407
|
+
.grove-prose dt {
|
|
408
|
+
font-weight: 600;
|
|
409
|
+
color: var(--color-ink-900, #1a1a1a);
|
|
410
|
+
margin-top: 0.5rem;
|
|
411
|
+
}
|
|
412
|
+
.grove-prose dd {
|
|
413
|
+
margin-left: 1.5rem; margin-bottom: 0.5rem;
|
|
414
|
+
color: var(--color-ink-700, #3a3a3a);
|
|
415
|
+
}
|
|
416
|
+
.dark .grove-prose dt { color: var(--color-ink-100, #f0f0f0); }
|
|
417
|
+
.dark .grove-prose dd { color: var(--color-ink-200, #d4d4d4); }
|
|
418
|
+
|
|
419
|
+
/* Inline emphasis. */
|
|
420
|
+
.grove-prose strong { font-weight: 600; color: var(--color-ink-900, #1a1a1a); }
|
|
421
|
+
.grove-prose em { font-style: italic; }
|
|
422
|
+
.grove-prose u { text-decoration: underline; text-underline-offset: 2px; }
|
|
423
|
+
.grove-prose :where(s, del) {
|
|
424
|
+
text-decoration: line-through;
|
|
425
|
+
color: var(--color-ink-500, #6a6a6a);
|
|
426
|
+
}
|
|
427
|
+
.grove-prose ins {
|
|
373
428
|
text-decoration: underline;
|
|
374
|
-
text-
|
|
375
|
-
text-
|
|
429
|
+
text-decoration-style: double;
|
|
430
|
+
text-underline-offset: 2px;
|
|
376
431
|
}
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
color: var(--color-ink-
|
|
380
|
-
text-decoration-color: var(--color-ink-400);
|
|
432
|
+
.grove-prose small {
|
|
433
|
+
font-size: 0.85em;
|
|
434
|
+
color: var(--color-ink-500, #6a6a6a);
|
|
381
435
|
}
|
|
382
|
-
|
|
383
|
-
.grove-prose :
|
|
436
|
+
.dark .grove-prose strong { color: var(--color-ink-100, #f0f0f0); }
|
|
437
|
+
.dark .grove-prose small { color: var(--color-ink-400, #8a8a8a); }
|
|
438
|
+
|
|
439
|
+
/* Inline marks / keys / abbreviations. */
|
|
440
|
+
.grove-prose mark {
|
|
441
|
+
background-color: oklch(95% 0.05 90);
|
|
442
|
+
color: var(--color-ink-900, #1a1a1a);
|
|
443
|
+
padding: 0.05em 0.25em;
|
|
444
|
+
border-radius: 0.2rem;
|
|
445
|
+
}
|
|
446
|
+
.dark .grove-prose mark {
|
|
447
|
+
background-color: oklch(35% 0.08 80);
|
|
448
|
+
color: var(--color-ink-50, #fafafa);
|
|
449
|
+
}
|
|
450
|
+
.grove-prose kbd {
|
|
384
451
|
font-family: var(--font-mono);
|
|
452
|
+
font-size: 0.8em;
|
|
453
|
+
background-color: var(--color-ink-100, #f0f0f0);
|
|
454
|
+
color: var(--color-ink-900, #1a1a1a);
|
|
455
|
+
border: 1px solid var(--color-ink-300, #c0c0c0);
|
|
456
|
+
border-bottom-width: 2px;
|
|
457
|
+
border-radius: 0.3rem;
|
|
458
|
+
padding: 0.05em 0.4em;
|
|
459
|
+
line-height: 1;
|
|
460
|
+
display: inline-block;
|
|
461
|
+
vertical-align: baseline;
|
|
462
|
+
box-shadow: 0 1px 0 var(--color-ink-300, #c0c0c0);
|
|
463
|
+
}
|
|
464
|
+
.dark .grove-prose kbd {
|
|
465
|
+
background-color: var(--color-ink-900, #1a1a1a);
|
|
466
|
+
color: var(--color-ink-100, #f0f0f0);
|
|
467
|
+
border-color: var(--color-ink-700, #4a4a4a);
|
|
468
|
+
box-shadow: 0 1px 0 var(--color-ink-700, #4a4a4a);
|
|
469
|
+
}
|
|
470
|
+
.grove-prose abbr[title] {
|
|
471
|
+
text-decoration: underline dotted;
|
|
472
|
+
text-underline-offset: 2px;
|
|
473
|
+
cursor: help;
|
|
474
|
+
}
|
|
475
|
+
.grove-prose :where(sub, sup) {
|
|
476
|
+
font-size: 0.75em; line-height: 1;
|
|
477
|
+
position: relative; vertical-align: baseline;
|
|
478
|
+
}
|
|
479
|
+
.grove-prose sub { bottom: -0.25em; }
|
|
480
|
+
.grove-prose sup { top: -0.5em; }
|
|
481
|
+
.grove-prose time { font-variant-numeric: tabular-nums; }
|
|
482
|
+
|
|
483
|
+
/* Links. */
|
|
484
|
+
.grove-prose a {
|
|
485
|
+
color: var(--color-ink-900, #1a1a1a);
|
|
486
|
+
text-decoration: underline;
|
|
487
|
+
text-decoration-color: var(--color-ink-300, #c0c0c0);
|
|
488
|
+
text-underline-offset: 2px;
|
|
489
|
+
text-decoration-thickness: 1px;
|
|
490
|
+
transition: text-decoration-color 120ms ease;
|
|
491
|
+
}
|
|
492
|
+
.grove-prose a:hover {
|
|
493
|
+
text-decoration-color: currentColor;
|
|
494
|
+
text-decoration-thickness: 2px;
|
|
495
|
+
}
|
|
496
|
+
.dark .grove-prose a {
|
|
497
|
+
color: var(--color-ink-100, #f0f0f0);
|
|
498
|
+
text-decoration-color: var(--color-ink-700, #4a4a4a);
|
|
385
499
|
}
|
|
386
500
|
|
|
501
|
+
/* Inline code. */
|
|
387
502
|
.grove-prose code {
|
|
388
|
-
|
|
389
|
-
background: var(--color-ink-100);
|
|
390
|
-
padding: 0.1em 0.3em;
|
|
503
|
+
font-family: var(--font-mono);
|
|
391
504
|
font-size: 0.875em;
|
|
505
|
+
background-color: var(--color-ink-100, #f0f0f0);
|
|
506
|
+
color: var(--color-ink-900, #1a1a1a);
|
|
507
|
+
padding: 0.15em 0.4em;
|
|
508
|
+
border-radius: 0.3rem;
|
|
509
|
+
word-break: break-word;
|
|
392
510
|
}
|
|
393
|
-
|
|
394
511
|
.dark .grove-prose code {
|
|
395
|
-
background: var(--color-ink-
|
|
512
|
+
background-color: var(--color-ink-900, #1a1a1a);
|
|
513
|
+
color: var(--color-ink-100, #f0f0f0);
|
|
396
514
|
}
|
|
397
515
|
|
|
516
|
+
/* Code blocks — full column width, internal scroll on overflow. */
|
|
398
517
|
.grove-prose pre {
|
|
518
|
+
background-color: var(--color-ink-100, #f0f0f0);
|
|
519
|
+
color: var(--color-ink-900, #1a1a1a);
|
|
520
|
+
padding: 1rem 1.25rem;
|
|
521
|
+
border-radius: 0.5rem;
|
|
399
522
|
overflow-x: auto;
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
523
|
+
margin: 0 0 1.5rem 0;
|
|
524
|
+
font-size: 0.875rem;
|
|
525
|
+
line-height: 1.6;
|
|
526
|
+
border: 1px solid var(--color-ink-200, #e5e5e5);
|
|
527
|
+
max-width: 100%;
|
|
404
528
|
}
|
|
405
|
-
|
|
406
529
|
.dark .grove-prose pre {
|
|
407
|
-
|
|
408
|
-
|
|
530
|
+
background-color: var(--color-ink-900, #1a1a1a);
|
|
531
|
+
color: var(--color-ink-100, #f0f0f0);
|
|
532
|
+
border-color: var(--color-ink-800, #2a2a2a);
|
|
409
533
|
}
|
|
410
|
-
|
|
411
534
|
.grove-prose pre code {
|
|
412
535
|
background: transparent;
|
|
413
536
|
padding: 0;
|
|
537
|
+
border-radius: 0;
|
|
538
|
+
font-size: inherit;
|
|
539
|
+
word-break: normal;
|
|
540
|
+
white-space: pre;
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
/* Shiki-themed code blocks. Shiki emits `<pre class="shiki …">`
|
|
544
|
+
with per-token `<span style="--shiki-light: …; --shiki-dark: …">`
|
|
545
|
+
when configured with `defaultColor: false`. Our job is to:
|
|
546
|
+
1. Give the block a slightly different background to read as
|
|
547
|
+
"code" (lighter than the prose surface in light mode,
|
|
548
|
+
darker in dark mode).
|
|
549
|
+
2. Make the foreground colour resolve through the dual
|
|
550
|
+
variables so the same HTML is themed correctly when
|
|
551
|
+
`.dark` toggles on `<html>`. */
|
|
552
|
+
.grove-prose pre.shiki {
|
|
553
|
+
background-color: var(--color-ink-50, #fafafa) !important;
|
|
554
|
+
color: var(--shiki-light, var(--color-ink-900, #1a1a1a));
|
|
555
|
+
border-color: var(--color-ink-200, #e5e5e5);
|
|
556
|
+
}
|
|
557
|
+
.dark .grove-prose pre.shiki {
|
|
558
|
+
background-color: var(--color-ink-950, #0a0a0a) !important;
|
|
559
|
+
color: var(--shiki-dark, var(--color-ink-100, #f0f0f0));
|
|
560
|
+
border-color: var(--color-ink-800, #2a2a2a);
|
|
414
561
|
}
|
|
562
|
+
.grove-prose pre.shiki code { color: inherit; }
|
|
563
|
+
.grove-prose pre.shiki span { color: var(--shiki-light); }
|
|
564
|
+
.dark .grove-prose pre.shiki span { color: var(--shiki-dark); }
|
|
415
565
|
|
|
566
|
+
/* Blockquotes — italic + left border + background tint. */
|
|
416
567
|
.grove-prose blockquote {
|
|
417
|
-
|
|
418
|
-
padding
|
|
419
|
-
|
|
568
|
+
margin: 0 0 1rem 0;
|
|
569
|
+
padding: 0.65rem 1rem 0.65rem 1.1rem;
|
|
570
|
+
border-left: 3px solid var(--color-ink-300, #c0c0c0);
|
|
571
|
+
color: var(--color-ink-500, #6a6a6a);
|
|
572
|
+
font-style: italic;
|
|
573
|
+
background-color: var(--color-ink-50, #fafafa);
|
|
574
|
+
border-radius: 0 0.4rem 0.4rem 0;
|
|
575
|
+
}
|
|
576
|
+
.grove-prose blockquote > :first-child { margin-top: 0; }
|
|
577
|
+
.grove-prose blockquote > :last-child { margin-bottom: 0; }
|
|
578
|
+
.grove-prose blockquote p { margin: 0 0 0.5rem 0; }
|
|
579
|
+
.grove-prose blockquote blockquote {
|
|
580
|
+
margin: 0.5rem 0;
|
|
581
|
+
border-left-width: 2px;
|
|
582
|
+
}
|
|
583
|
+
.dark .grove-prose blockquote {
|
|
584
|
+
border-left-color: var(--color-ink-700, #4a4a4a);
|
|
585
|
+
color: var(--color-ink-400, #8a8a8a);
|
|
586
|
+
background-color: var(--color-ink-900, #1a1a1a);
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
/* Horizontal rules. */
|
|
590
|
+
.grove-prose hr {
|
|
591
|
+
border: 0;
|
|
592
|
+
border-top: 1px solid var(--color-ink-200, #e5e5e5);
|
|
593
|
+
margin: 2.25rem 0;
|
|
594
|
+
}
|
|
595
|
+
.dark .grove-prose hr { border-top-color: var(--color-ink-800, #2a2a2a); }
|
|
596
|
+
|
|
597
|
+
/* Images — rounded border, full column width. */
|
|
598
|
+
.grove-prose img {
|
|
599
|
+
max-width: 100%;
|
|
600
|
+
height: auto;
|
|
601
|
+
border-radius: 0.5rem;
|
|
602
|
+
border: 1px solid var(--color-ink-200, #e5e5e5);
|
|
603
|
+
display: block;
|
|
604
|
+
margin: 1.25rem 0;
|
|
605
|
+
}
|
|
606
|
+
.dark .grove-prose img { border-color: var(--color-ink-800, #2a2a2a); }
|
|
607
|
+
|
|
608
|
+
/* Figures + captions. */
|
|
609
|
+
.grove-prose figure { margin: 1.25rem 0; padding: 0; }
|
|
610
|
+
.grove-prose figure > img { margin: 0 0 0.5rem 0; }
|
|
611
|
+
.grove-prose figcaption {
|
|
612
|
+
font-size: 0.85rem;
|
|
613
|
+
color: var(--color-ink-500, #6a6a6a);
|
|
614
|
+
text-align: center;
|
|
615
|
+
margin-top: 0.4rem;
|
|
420
616
|
}
|
|
617
|
+
.dark .grove-prose figcaption { color: var(--color-ink-400, #8a8a8a); }
|
|
618
|
+
|
|
619
|
+
/* GFM tables — the renderer wraps them in `.grove-prose-table-wrap`
|
|
620
|
+
so the column-width overflow is contained. */
|
|
621
|
+
.grove-prose-table-wrap {
|
|
622
|
+
margin: 0 0 1.5rem 0;
|
|
623
|
+
overflow-x: auto;
|
|
624
|
+
border-radius: 0.5rem;
|
|
625
|
+
border: 1px solid var(--color-ink-200, #e5e5e5);
|
|
626
|
+
background-color: var(--grove-background, #ffffff);
|
|
627
|
+
}
|
|
628
|
+
.dark .grove-prose-table-wrap { border-color: var(--color-ink-800, #2a2a2a); }
|
|
629
|
+
.grove-prose table {
|
|
630
|
+
width: 100%;
|
|
631
|
+
border-collapse: collapse;
|
|
632
|
+
font-size: 0.95rem;
|
|
633
|
+
line-height: 1.55;
|
|
634
|
+
}
|
|
635
|
+
.grove-prose table caption {
|
|
636
|
+
text-align: left;
|
|
637
|
+
font-size: 0.85rem;
|
|
638
|
+
color: var(--color-ink-500, #6a6a6a);
|
|
639
|
+
padding: 0.5rem 1rem;
|
|
640
|
+
caption-side: bottom;
|
|
641
|
+
}
|
|
642
|
+
.grove-prose thead {
|
|
643
|
+
background-color: var(--color-ink-50, #fafafa);
|
|
644
|
+
border-bottom: 2px solid var(--color-ink-200, #e5e5e5);
|
|
645
|
+
}
|
|
646
|
+
.dark .grove-prose thead {
|
|
647
|
+
background-color: var(--color-ink-900, #1a1a1a);
|
|
648
|
+
border-bottom-color: var(--color-ink-700, #4a4a4a);
|
|
649
|
+
}
|
|
650
|
+
.grove-prose th {
|
|
651
|
+
text-align: left;
|
|
652
|
+
font-weight: 600;
|
|
653
|
+
padding: 0.75rem 1rem;
|
|
654
|
+
color: var(--color-ink-900, #1a1a1a);
|
|
655
|
+
border-bottom: 1px solid var(--color-ink-200, #e5e5e5);
|
|
656
|
+
}
|
|
657
|
+
.grove-prose td {
|
|
658
|
+
padding: 0.65rem 1rem;
|
|
659
|
+
border-bottom: 1px solid var(--color-ink-100, #f0f0f0);
|
|
660
|
+
color: var(--color-ink-700, #3a3a3a);
|
|
661
|
+
vertical-align: top;
|
|
662
|
+
}
|
|
663
|
+
.grove-prose th[align="center"], .grove-prose td[align="center"] { text-align: center; }
|
|
664
|
+
.grove-prose th[align="right"], .grove-prose td[align="right"] { text-align: right; }
|
|
665
|
+
.grove-prose tbody tr:last-child td { border-bottom: 0; }
|
|
666
|
+
.grove-prose tbody tr:hover { background-color: var(--color-ink-50, #fafafa); }
|
|
667
|
+
.dark .grove-prose th { color: var(--color-ink-100, #f0f0f0); border-bottom-color: var(--color-ink-700, #4a4a4a); }
|
|
668
|
+
.dark .grove-prose td { color: var(--color-ink-200, #d4d4d4); border-bottom-color: var(--color-ink-800, #2a2a2a); }
|
|
669
|
+
.dark .grove-prose tbody tr:hover { background-color: var(--color-ink-900, #1a1a1a); }
|
|
670
|
+
|
|
671
|
+
/* GFM task-list checkboxes — read-only at runtime. */
|
|
672
|
+
.grove-prose input[type="checkbox"] {
|
|
673
|
+
appearance: none;
|
|
674
|
+
-webkit-appearance: none;
|
|
675
|
+
width: 1em; height: 1em;
|
|
676
|
+
border: 1.5px solid var(--color-ink-400, #999999);
|
|
677
|
+
border-radius: 0.25rem;
|
|
678
|
+
margin-right: 0.45rem;
|
|
679
|
+
margin-top: 0.15rem;
|
|
680
|
+
vertical-align: middle;
|
|
681
|
+
position: relative; top: -0.05em;
|
|
682
|
+
background-color: var(--grove-background, #ffffff);
|
|
683
|
+
cursor: default;
|
|
684
|
+
flex-shrink: 0;
|
|
685
|
+
}
|
|
686
|
+
.grove-prose input[type="checkbox"]:checked {
|
|
687
|
+
background-color: var(--color-ink-900, #1a1a1a);
|
|
688
|
+
border-color: var(--color-ink-900, #1a1a1a);
|
|
689
|
+
}
|
|
690
|
+
.grove-prose input[type="checkbox"]:checked::after {
|
|
691
|
+
content: "";
|
|
692
|
+
position: absolute;
|
|
693
|
+
left: 4px; top: 1px;
|
|
694
|
+
width: 4px; height: 8px;
|
|
695
|
+
border: solid var(--grove-background, #ffffff);
|
|
696
|
+
border-width: 0 2px 2px 0;
|
|
697
|
+
transform: rotate(45deg);
|
|
698
|
+
}
|
|
699
|
+
.grove-prose input[type="checkbox"]:disabled { opacity: 0.7; }
|
|
700
|
+
.dark .grove-prose input[type="checkbox"] {
|
|
701
|
+
border-color: var(--color-ink-600, #555555);
|
|
702
|
+
background-color: var(--grove-background, #1a1a1a);
|
|
703
|
+
}
|
|
704
|
+
.dark .grove-prose input[type="checkbox"]:checked {
|
|
705
|
+
background-color: var(--color-ink-100, #f0f0f0);
|
|
706
|
+
border-color: var(--color-ink-100, #f0f0f0);
|
|
707
|
+
}
|
|
708
|
+
.dark .grove-prose input[type="checkbox"]:checked::after {
|
|
709
|
+
border-color: var(--grove-background, #1a1a1a);
|
|
710
|
+
}
|
|
711
|
+
.grove-prose li:has(> input[type="checkbox"]) {
|
|
712
|
+
list-style: none;
|
|
713
|
+
margin-left: -1.25rem;
|
|
714
|
+
display: flex; align-items: flex-start;
|
|
715
|
+
gap: 0.15rem;
|
|
716
|
+
}
|
|
717
|
+
.grove-prose li:has(> input[type="checkbox"]) > input[type="checkbox"] {
|
|
718
|
+
margin-right: 0.55rem; margin-left: 0.15rem;
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
/* Collapsibles (details / summary). */
|
|
722
|
+
.grove-prose details {
|
|
723
|
+
margin: 0 0 1rem 0;
|
|
724
|
+
border: 1px solid var(--color-ink-200, #e5e5e5);
|
|
725
|
+
border-radius: 0.5rem;
|
|
726
|
+
background-color: var(--color-ink-50, #fafafa);
|
|
727
|
+
overflow: hidden;
|
|
728
|
+
}
|
|
729
|
+
.grove-prose details[open] { background-color: var(--grove-background, #ffffff); }
|
|
730
|
+
.grove-prose details + details { margin-top: -0.5rem; }
|
|
731
|
+
.dark .grove-prose details {
|
|
732
|
+
border-color: var(--color-ink-800, #2a2a2a);
|
|
733
|
+
background-color: var(--color-ink-900, #1a1a1a);
|
|
734
|
+
}
|
|
735
|
+
.dark .grove-prose details[open] { background-color: var(--grove-background, #1a1a1a); }
|
|
736
|
+
.grove-prose summary {
|
|
737
|
+
cursor: pointer;
|
|
738
|
+
padding: 0.75rem 1rem;
|
|
739
|
+
font-weight: 600;
|
|
740
|
+
color: var(--color-ink-900, #1a1a1a);
|
|
741
|
+
list-style: none;
|
|
742
|
+
user-select: none;
|
|
743
|
+
display: flex; align-items: center; gap: 0.5rem;
|
|
744
|
+
transition: background-color 120ms ease;
|
|
745
|
+
}
|
|
746
|
+
.grove-prose summary::-webkit-details-marker { display: none; }
|
|
747
|
+
.grove-prose summary::before {
|
|
748
|
+
content: "";
|
|
749
|
+
width: 0; height: 0;
|
|
750
|
+
border-style: solid;
|
|
751
|
+
border-width: 0.35rem 0 0.35rem 0.55rem;
|
|
752
|
+
border-color: transparent transparent transparent var(--color-ink-500, #6a6a6a);
|
|
753
|
+
transition: transform 120ms ease;
|
|
754
|
+
flex-shrink: 0;
|
|
755
|
+
}
|
|
756
|
+
.grove-prose details[open] > summary::before { transform: rotate(90deg); }
|
|
757
|
+
.grove-prose summary:hover { background-color: var(--color-ink-100, #f0f0f0); }
|
|
758
|
+
.grove-prose summary strong { font-weight: inherit; }
|
|
759
|
+
.dark .grove-prose summary { color: var(--color-ink-100, #f0f0f0); }
|
|
760
|
+
.dark .grove-prose summary:hover { background-color: var(--color-ink-800, #2a2a2a); }
|
|
761
|
+
.grove-prose details > :not(summary) { padding: 0 1rem 1rem 1rem; }
|
|
762
|
+
.grove-prose details > :not(summary):first-of-type { padding-top: 0; }
|
|
763
|
+
|
|
764
|
+
/* ──────────────────────────────────────────────────────────────────
|
|
765
|
+
* On-page TOC component (`.grove-toc-*`)
|
|
766
|
+
* Selectors are static so Tailwind purges nothing. The active state
|
|
767
|
+
* is set imperatively by the TableOfContents script via
|
|
768
|
+
* `[data-toc-active]` on the matching anchor.
|
|
769
|
+
* ────────────────────────────────────────────────────────────────── */
|
|
770
|
+
.grove-toc summary { color: inherit; }
|
|
771
|
+
.grove-toc[open] .grove-toc-chevron,
|
|
772
|
+
.grove-toc > summary:hover .grove-toc-chevron { transform: rotate(90deg); }
|
|
773
|
+
.grove-toc-item { padding: 0; }
|
|
774
|
+
.grove-toc-link[data-toc-active] {
|
|
775
|
+
background-color: var(--color-ink-100, #f0f0f0);
|
|
776
|
+
color: var(--color-ink-900, #1a1a1a);
|
|
777
|
+
font-weight: 600;
|
|
778
|
+
border-radius: 0.375rem;
|
|
779
|
+
}
|
|
780
|
+
.dark .grove-toc-link[data-toc-active] {
|
|
781
|
+
background-color: var(--color-ink-800, #2a2a2a);
|
|
782
|
+
color: var(--color-ink-100, #f0f0f0);
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
/* ──────────────────────────────────────────────────────────────────
|
|
786
|
+
* Activity-badge tone classes.
|
|
787
|
+
*
|
|
788
|
+
* Tone is set via `data-activity-tone` on the element. The rules
|
|
789
|
+
* below are static strings, so Tailwind's content scanner can see
|
|
790
|
+
* them at build time and ship the CSS. Avoid rebuilding tone
|
|
791
|
+
* strings from variables — Tailwind purges anything it can't see.
|
|
792
|
+
* ────────────────────────────────────────────────────────────────── */
|
|
793
|
+
.grove-pill--activity {
|
|
794
|
+
border-color: var(--color-ink-300, #c0c0c0);
|
|
795
|
+
background-color: var(--color-ink-100, #f0f0f0);
|
|
796
|
+
color: var(--color-ink-700, #3a3a3a);
|
|
797
|
+
}
|
|
798
|
+
[data-activity-tone="fresh"] {
|
|
799
|
+
border-color: oklch(87% 0.15 154);
|
|
800
|
+
background-color: oklch(98% 0.018 156);
|
|
801
|
+
color: oklch(40% 0.12 152);
|
|
802
|
+
}
|
|
803
|
+
[data-activity-tone="ok"] {
|
|
804
|
+
border-color: oklch(83% 0.11 230);
|
|
805
|
+
background-color: oklch(97% 0.014 255);
|
|
806
|
+
color: oklch(40% 0.16 255);
|
|
807
|
+
}
|
|
808
|
+
[data-activity-tone="low"] {
|
|
809
|
+
border-color: oklch(90% 0.08 70);
|
|
810
|
+
background-color: oklch(98% 0.016 74);
|
|
811
|
+
color: oklch(40% 0.13 60);
|
|
812
|
+
}
|
|
813
|
+
[data-activity-tone="dead"] {
|
|
814
|
+
border-color: oklch(90% 0.08 40);
|
|
815
|
+
background-color: oklch(98% 0.016 38);
|
|
816
|
+
color: oklch(40% 0.13 40);
|
|
817
|
+
}
|
|
818
|
+
.dark [data-activity-tone="fresh"] {
|
|
819
|
+
border-color: oklch(35% 0.10 154);
|
|
820
|
+
background-color: oklch(20% 0.05 156);
|
|
821
|
+
color: oklch(85% 0.15 154);
|
|
822
|
+
}
|
|
823
|
+
.dark [data-activity-tone="ok"] {
|
|
824
|
+
border-color: oklch(30% 0.10 230);
|
|
825
|
+
background-color: oklch(20% 0.05 255);
|
|
826
|
+
color: oklch(80% 0.13 230);
|
|
827
|
+
}
|
|
828
|
+
.dark [data-activity-tone="low"] {
|
|
829
|
+
border-color: oklch(35% 0.10 60);
|
|
830
|
+
background-color: oklch(20% 0.05 74);
|
|
831
|
+
color: oklch(85% 0.13 70);
|
|
832
|
+
}
|
|
833
|
+
.dark [data-activity-tone="dead"] {
|
|
834
|
+
border-color: oklch(35% 0.10 40);
|
|
835
|
+
background-color: oklch(20% 0.05 40);
|
|
836
|
+
color: oklch(85% 0.13 40);
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
/* ──────────────────────────────────────────────────────────────────
|
|
840
|
+
* Sidebar key-value rows.
|
|
841
|
+
* Static selector (no dynamic class concatenation) — Tailwind ships
|
|
842
|
+
* the CSS because the class string appears literally here.
|
|
843
|
+
* ────────────────────────────────────────────────────────────────── */
|
|
844
|
+
.grove-kv div { line-height: 1.4; }
|
|
845
|
+
.grove-card-title { letter-spacing: 0.04em; }
|
|
846
|
+
.grove-card--muted { background-color: color-mix(in oklab, var(--grove-background) 60%, transparent); }
|