@grove-dev/astro 0.4.1 → 0.5.0-next.2

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/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
- max-width: 72ch;
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
- .dark .grove-prose {
327
- color: var(--color-ink-300);
328
- }
329
-
330
- .grove-prose :where(h1, h2, h3, h4) {
331
- margin: 1.75em 0 0.65em;
332
- color: var(--color-ink-900);
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
- .dark .grove-prose :where(h1, h2, h3, h4) {
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
- .grove-prose h1 {
342
- font-size: 1.875rem;
343
- font-weight: 600;
344
- line-height: 2.25rem;
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.25rem;
349
- line-height: 1.75rem;
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.125rem;
354
- line-height: 1.75rem;
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: 1rem;
359
- line-height: 1.5rem;
372
+ font-size: 1.0625rem; /* 17px */
373
+ margin-top: 1.5rem; margin-bottom: 0.4rem;
360
374
  }
361
-
362
- .grove-prose :where(p, ul, ol, pre, blockquote) {
363
- margin: 1em 0;
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
- .grove-prose a {
371
- color: var(--color-ink-900);
372
- font-weight: 500;
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-underline-offset: 0.18em;
375
- text-decoration-color: var(--color-ink-500);
429
+ text-decoration-style: double;
430
+ text-underline-offset: 2px;
376
431
  }
377
-
378
- .dark .grove-prose a {
379
- color: var(--color-ink-50);
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 :where(code, pre) {
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
- border-radius: 0.25rem;
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-800);
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
- border: 1px solid var(--color-ink-200);
401
- border-radius: var(--radius-lg);
402
- background: var(--color-ink-50);
403
- padding: 1rem;
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
- border-color: var(--color-ink-800);
408
- background: var(--color-ink-900);
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
- border-left: 3px solid var(--color-ink-300);
418
- padding-left: 1rem;
419
- color: var(--color-ink-500);
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); }