@lovett/ui 0.0.11 → 0.1.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.
Files changed (141) hide show
  1. package/dist/chunk-RBYWGBQ2.js +2752 -0
  2. package/dist/chunk-RBYWGBQ2.js.map +1 -0
  3. package/dist/index.d.ts +5402 -71
  4. package/dist/index.js +21992 -11618
  5. package/dist/index.js.map +1 -1
  6. package/dist/rich-composer-impl-5NO443A6.js +1859 -0
  7. package/dist/rich-composer-impl-5NO443A6.js.map +1 -0
  8. package/dist/styles.css +1570 -0
  9. package/dist/tokens.css +112 -0
  10. package/package.json +8 -1
  11. package/src/__tests__/avatar.test.tsx +272 -0
  12. package/src/__tests__/bar-chart.test.tsx +809 -0
  13. package/src/__tests__/board.test.tsx +420 -0
  14. package/src/__tests__/chart-math.test.ts +922 -0
  15. package/src/__tests__/chart-series.test.ts +339 -0
  16. package/src/__tests__/code-block.test.tsx +134 -0
  17. package/src/__tests__/display-popover.test.tsx +195 -0
  18. package/src/__tests__/display-store.test.tsx +208 -0
  19. package/src/__tests__/donut-chart.test.tsx +397 -0
  20. package/src/__tests__/dropdown-menu.test.tsx +156 -2
  21. package/src/__tests__/filter-menu.test.tsx +175 -0
  22. package/src/__tests__/gauge-ring.test.tsx +233 -0
  23. package/src/__tests__/line-chart.test.tsx +612 -0
  24. package/src/__tests__/ranked-bars.test.tsx +343 -0
  25. package/src/__tests__/remark-underline.test.ts +194 -0
  26. package/src/__tests__/sparkline.test.tsx +368 -0
  27. package/src/__tests__/stat-layer.test.tsx +271 -0
  28. package/src/__tests__/stat-strip.test.tsx +175 -0
  29. package/src/__tests__/status.test.tsx +293 -0
  30. package/src/__tests__/tabs.test.tsx +303 -0
  31. package/src/__tests__/token-shape.test.ts +132 -2
  32. package/src/avatar.tsx +352 -0
  33. package/src/bar-chart.tsx +1214 -0
  34. package/src/board.tsx +658 -0
  35. package/src/chart-frame.tsx +960 -0
  36. package/src/chart-legend.tsx +304 -0
  37. package/src/chart-tooltip.tsx +267 -0
  38. package/src/code-block.tsx +62 -8
  39. package/src/delta-chip.tsx +263 -0
  40. package/src/detail/__tests__/activity-pane.test.tsx +186 -0
  41. package/src/detail/__tests__/detail-chrome.test.tsx +134 -0
  42. package/src/detail/__tests__/detail-surface.test.tsx +529 -0
  43. package/src/detail/__tests__/field-row.test.tsx +357 -0
  44. package/src/detail/activity-pane.tsx +507 -0
  45. package/src/detail/calendar.tsx +355 -0
  46. package/src/detail/detail-divider.tsx +261 -0
  47. package/src/detail/detail-header.tsx +287 -0
  48. package/src/detail/detail-menu.tsx +254 -0
  49. package/src/detail/detail-surface.tsx +1110 -0
  50. package/src/detail/field-list.tsx +196 -0
  51. package/src/detail/field-row.tsx +1131 -0
  52. package/src/detail/index.ts +58 -0
  53. package/src/detail/segmented-choice.tsx +94 -0
  54. package/src/detail/types.ts +129 -0
  55. package/src/display-popover.tsx +487 -0
  56. package/src/display-store.tsx +242 -0
  57. package/src/donut-chart.tsx +988 -0
  58. package/src/dropdown-menu.tsx +290 -19
  59. package/src/filter-core/EXPORTS.md +85 -0
  60. package/src/filter-core/__tests__/columns.test.ts +159 -0
  61. package/src/filter-core/__tests__/faceting.test.ts +193 -0
  62. package/src/filter-core/__tests__/filter-fns.test.ts +519 -0
  63. package/src/filter-core/__tests__/operators.test.ts +235 -0
  64. package/src/filter-core/__tests__/state.test.ts +268 -0
  65. package/src/filter-core/__tests__/url.test.ts +350 -0
  66. package/src/filter-core/columns.ts +134 -0
  67. package/src/filter-core/date-utils.ts +38 -0
  68. package/src/filter-core/examples/task-filter-columns.ts +121 -0
  69. package/src/filter-core/faceting.ts +120 -0
  70. package/src/filter-core/filter-fns.ts +335 -0
  71. package/src/filter-core/index.ts +105 -0
  72. package/src/filter-core/operators.ts +433 -0
  73. package/src/filter-core/state.ts +280 -0
  74. package/src/filter-core/types.ts +247 -0
  75. package/src/filter-core/url.ts +261 -0
  76. package/src/filter-dropdown.tsx +12 -0
  77. package/src/filter-menu.tsx +649 -0
  78. package/src/floating-drawer.tsx +19 -1
  79. package/src/gauge-ring.tsx +435 -0
  80. package/src/hue.ts +52 -0
  81. package/src/index.ts +296 -0
  82. package/src/kbd.tsx +27 -4
  83. package/src/lib/chart.ts +866 -0
  84. package/src/lib/focus.ts +43 -1
  85. package/src/lib/layer-stack.ts +30 -3
  86. package/src/lib/remark-underline.ts +443 -0
  87. package/src/lib/series.ts +169 -0
  88. package/src/line-chart.tsx +1176 -0
  89. package/src/markdown.tsx +26 -7
  90. package/src/modal.tsx +42 -18
  91. package/src/progress-ledger.tsx +304 -0
  92. package/src/ranked-bars.tsx +386 -0
  93. package/src/segmented-pill.tsx +32 -9
  94. package/src/sortable.tsx +315 -1
  95. package/src/sparkline.tsx +416 -0
  96. package/src/stat-card.tsx +376 -0
  97. package/src/stat-strip.tsx +327 -0
  98. package/src/status.tsx +215 -0
  99. package/src/styles.css +1570 -0
  100. package/src/tabs.tsx +206 -25
  101. package/src/task-card.tsx +610 -0
  102. package/src/thread/__tests__/comment-body-hostile.test.tsx +331 -0
  103. package/src/thread/__tests__/comment-tree.test.ts +151 -0
  104. package/src/thread/__tests__/emoji.test.ts +187 -0
  105. package/src/thread/__tests__/fixtures/thread-fixture.ts +235 -0
  106. package/src/thread/__tests__/link-preview-source.test.ts +120 -0
  107. package/src/thread/__tests__/link-preview.test.tsx +600 -0
  108. package/src/thread/__tests__/markdown-format.test.ts +82 -0
  109. package/src/thread/__tests__/markdown-spec.test.ts +469 -0
  110. package/src/thread/__tests__/relative-time.test.ts +71 -0
  111. package/src/thread/__tests__/rich-composer.test.tsx +799 -0
  112. package/src/thread/__tests__/scroll-caret.test.ts +58 -0
  113. package/src/thread/__tests__/suggestion-list.test.tsx +648 -0
  114. package/src/thread/__tests__/thread-scroll-ownership.test.tsx +88 -0
  115. package/src/thread/__tests__/thread.test.tsx +662 -0
  116. package/src/thread/__tests__/use-attachments.test.tsx +679 -0
  117. package/src/thread/actions.tsx +196 -0
  118. package/src/thread/attachments.tsx +1071 -0
  119. package/src/thread/comment-body.tsx +148 -0
  120. package/src/thread/comment-tree.ts +182 -0
  121. package/src/thread/comment.tsx +915 -0
  122. package/src/thread/composer-footer.tsx +125 -0
  123. package/src/thread/composer.tsx +319 -0
  124. package/src/thread/emoji.ts +283 -0
  125. package/src/thread/index.ts +153 -0
  126. package/src/thread/link-preview.tsx +341 -0
  127. package/src/thread/markdown-format.ts +155 -0
  128. package/src/thread/markdown-spec.ts +754 -0
  129. package/src/thread/rail.tsx +372 -0
  130. package/src/thread/reactions.tsx +415 -0
  131. package/src/thread/relative-time.tsx +94 -0
  132. package/src/thread/rich-composer-impl.tsx +1601 -0
  133. package/src/thread/rich-composer.tsx +195 -0
  134. package/src/thread/scroll-caret.ts +37 -0
  135. package/src/thread/suggestion-list.tsx +182 -0
  136. package/src/thread/thread.tsx +718 -0
  137. package/src/thread/types.ts +218 -0
  138. package/src/thread/use-attachments.ts +598 -0
  139. package/src/thread/use-now.ts +73 -0
  140. package/src/thread/use-thread.ts +316 -0
  141. package/src/tokens.css +112 -0
package/src/index.ts CHANGED
@@ -71,6 +71,79 @@ export {
71
71
  // @dnd-kit/core + sortable + utilities (CLAUDE.md §1 amendment in same phase).
72
72
  export { SortableList, SortableItem, DragHandle } from './sortable'
73
73
 
74
+ // Multi-container drag — ADR-146 slice A. <SortableList> is single-container;
75
+ // a kanban needs a card to LEAVE its column, which is a droppable per column
76
+ // plus a DragOverlay. Keeps the KeyboardSensor, so cross-column movement is
77
+ // reachable without a pointer.
78
+ export {
79
+ MultiSortableList,
80
+ SortableDropZone,
81
+ type MultiSortableListProps,
82
+ type MultiSortableMove,
83
+ type SortableContainers,
84
+ } from './sortable'
85
+
86
+ // The board kit — ADR-146 D2/D7/D13, spec'd in
87
+ // `docs/design-briefs/tasks-board-design-language.md` and its
88
+ // interface-standards addendum.
89
+ //
90
+ // ONE board primitive, TWO consumers: the Tasks lens and the Community
91
+ // roadmap. It is generic over its card BODY (`renderCard`), never over its
92
+ // data — a Community card carries votes where a Tasks card carries a ledger.
93
+ // Community's fixture-backed `components/ui/community/board.tsx` is deleted in
94
+ // the same change.
95
+ //
96
+ // `hueClass()` arms the derived tint ladder (`.hue` + `.hue-<key>` in
97
+ // styles.css), which mixes a --folder-* hue INTO --surface-card with
98
+ // color-mix so every rung is opaque in both themes by construction. `red` is
99
+ // excluded: --folder-red is byte-identical to --accent in light mode.
100
+ export {
101
+ BOARD_HUE_KEYS,
102
+ hueClass,
103
+ hueForKey,
104
+ type BoardHueKey,
105
+ } from './hue'
106
+ export {
107
+ Board,
108
+ BoardColumn,
109
+ type BoardProps,
110
+ type BoardColumnProps,
111
+ type BoardColumnSpec,
112
+ type BoardCardContext,
113
+ type BoardItemLeadContext,
114
+ } from './board'
115
+ export {
116
+ TaskCard,
117
+ type TaskCardProps,
118
+ type TaskCardAvatar,
119
+ type TaskCardCount,
120
+ type TaskCardDate,
121
+ type TaskCardDragProps,
122
+ type TaskCardMedia,
123
+ } from './task-card'
124
+ export {
125
+ ProgressLedger,
126
+ ledgerProgress,
127
+ type ProgressLedgerProps,
128
+ type LedgerCell,
129
+ type LedgerProgress,
130
+ type LedgerSegment,
131
+ } from './progress-ledger'
132
+ // The status vocabulary (header-primitives §2). `StatusRing` renders a REAL
133
+ // percent — the one `ledgerProgress()` computes, so a ring and the ledger it
134
+ // sits beside cannot disagree; `StatusGlyph` covers the discrete states, in
135
+ // lucide rather than the source's six hand-written inline SVGs.
136
+ export {
137
+ BOARD_STATUS_KEYS,
138
+ STATUS_GLYPHS,
139
+ STATUS_LABELS,
140
+ StatusGlyph,
141
+ StatusRing,
142
+ type BoardStatusKey,
143
+ type StatusGlyphProps,
144
+ type StatusRingProps,
145
+ } from './status'
146
+
74
147
  // EmptyState — promoted post-phase-15 (ADR-019). 4-consumer trigger:
75
148
  // Products / Personas / Competitors / Assets lenses all forked their own
76
149
  // full-area empty-state pattern. Canonical shape derived from the Phase
@@ -379,6 +452,25 @@ export {
379
452
  type ShellStatTone,
380
453
  } from './shell'
381
454
 
455
+ // Avatar / AvatarGroup — a person. Promoted in ADR-147 D14, collapsing four
456
+ // forks (task-card's AvatarStack, community/primitives, its byte-identical
457
+ // admin clone, and the inline one in folders/folder-row) that disagreed on
458
+ // hash, initials cap, geometry and colour. `initials()` and
459
+ // `avatarTintForKey()` are the one derivation each, exported so a caller that
460
+ // needs the monogram or the hue outside an avatar does not re-derive it.
461
+ export {
462
+ Avatar,
463
+ AvatarGroup,
464
+ AVATAR_TINTS,
465
+ asAvatarTint,
466
+ avatarTintForKey,
467
+ initials,
468
+ type AvatarProps,
469
+ type AvatarGroupProps,
470
+ type AvatarSize,
471
+ type AvatarTint,
472
+ } from './avatar'
473
+
382
474
  // FolderCard — drive-style folder tile (colour-keyed swatch + name +
383
475
  // count + hover checkbox / menu slot). Promoted in ADR-035 (Assets
384
476
  // lens redesign); a card surface, so it owns the internal surface
@@ -526,3 +618,207 @@ export type {
526
618
  PreviewConfiguration,
527
619
  } from './meta-previews/types'
528
620
  export { PLACEMENT_CONFIGS } from './meta-previews/types'
621
+
622
+ // Board filter model — pure TypeScript, no React. See src/filter-core/index.ts.
623
+ export * from './filter-core'
624
+
625
+ // FilterMenu + FilterChips — the UI layer over filter-core (header-primitives
626
+ // §5). Two-step field-then-values picker with faceted counts, and the active
627
+ // filters as removable, editable chips. The host owns FiltersState and is
628
+ // expected to keep it in the URL, which is what makes a filtered view a
629
+ // shareable link.
630
+ export {
631
+ FilterMenu,
632
+ FilterChipBar,
633
+ type FilterMenuProps,
634
+ type FilterChipBarProps,
635
+ type FilterOptionIconRenderer,
636
+ type FilterFieldIconRenderer,
637
+ } from './filter-menu'
638
+
639
+ // The Display popover and its row primitives (header-primitives §4) — the
640
+ // boundary the source never drew. Every control here is real or absent;
641
+ // PopoverFooterActions renders no primary unless one is supplied.
642
+ export {
643
+ DisplayPopover,
644
+ OptionRow,
645
+ SelectRow,
646
+ ToggleRow,
647
+ ChipToggleGroup,
648
+ SectionHeading,
649
+ PopoverFooterActions,
650
+ type DisplayPopoverProps,
651
+ type DisplayPopoverSectionProps,
652
+ type OptionRowProps,
653
+ type SelectRowProps,
654
+ type ToggleRowProps,
655
+ type ChipToggleGroupProps,
656
+ type ChipToggleItem,
657
+ type SectionHeadingProps,
658
+ type PopoverFooterActionsProps,
659
+ type PopoverFooterAction,
660
+ } from './display-popover'
661
+
662
+ // createDisplayStore — one factory for per-scope display settings, passed
663
+ // down by CONTEXT rather than read from a module singleton (the trap
664
+ // header-primitives §4 names: their cards subscribe to a global store, so two
665
+ // boards with different settings cannot coexist).
666
+ export {
667
+ createDisplayStore,
668
+ type DisplayStore,
669
+ type DisplayController,
670
+ type DisplaySettings,
671
+ type DisplayValue,
672
+ type DisplayAllowed,
673
+ type DisplayMigrations,
674
+ type DisplayProviderProps,
675
+ } from './display-store'
676
+ // ── ADR-146 — the analytics primitive set ─────────────────────────────
677
+ //
678
+ // Promoted as ONE block (ADR-146 D5). The trigger was not a missing chart:
679
+ // it was ~26 forked stat tiles, 3 independent delta chips, and 7 hand-written
680
+ // SVG charts sitting in `design-system/spec/shell-charts.tsx` that no product
681
+ // lens could reach — while `--series-1..8` sat in `theme-v2.css` with zero
682
+ // consumers. Each primitive below carries a MEASURED consumer count in its
683
+ // own docstring — measured 2026-09-06, gallery demos excluded. Only
684
+ // `StatCard` clears the ADR-008 D3 two-consumer gate today; the rest are
685
+ // shipped ahead of their consumers, which is a deliberate, recorded debt, not
686
+ // a met gate. The per-primitive ledger and the named surface that should
687
+ // become each one's second consumer live in
688
+ // `docs/follow-ups/_pending/adr-146-consumer-gate.md`. The ~26 forked tiles
689
+ // are NOT rewritten here (ADR-146 D13).
690
+ //
691
+ // Three rules that govern every export in this block:
692
+ // D7 a chart is MONOCHROME until it earns a palette — the accent's scarcity
693
+ // is the point, and bar length already encodes what bar colour would.
694
+ // D8 series colour is a frozen literal lookup, never a constructed
695
+ // `--series-${i}`. A name that misses is invalid CSS the browser
696
+ // silently discards, with every gate green.
697
+ // D10 identity is never colour alone, and text wears text tokens, never a
698
+ // series colour. The empty / loading / error states and the table view
699
+ // come from `ChartFrame`, so — measured 2026-09-06, not asserted — only
700
+ // `LineChart`, `AreaChart` and `BarChart` carry them. `DonutChart`,
701
+ // `RankedBars`, `Sparkline` and `GaugeRing` do NOT compose the frame (a
702
+ // donut has no axes; ranked bars are their own rows), so they have no
703
+ // table view. Their data does reach assistive tech another way — the
704
+ // donut's legend is a label+value+percentage list and RankedBars is a
705
+ // labelled `<ul>` — but D10.5 says "every chart", and four of seven is
706
+ // not every. Tracked as a deviation in the ADR-146 completion report.
707
+ //
708
+ // Stat layer — DeltaChip replaces the 3 forks (admin/stat-tile.tsx:10,
709
+ // shell-preview.tsx:254, community/primitives.tsx:117); StatCard is the KPI
710
+ // tile WITH a delta slot, the slot whose absence caused the forks; StatStrip
711
+ // is one card divided by hairlines, which is a different object from a grid
712
+ // of StatCards and is why budget-flighting's GlobalHeader forked.
713
+ export { DeltaChip, type DeltaChipProps, type DeltaDirection, type DeltaFormat } from './delta-chip'
714
+ export { StatCard, type StatCardProps, type StatCardSize, type StatCardFooterLink } from './stat-card'
715
+ export { StatStrip, type StatStripProps, type StatStripCell } from './stat-strip'
716
+
717
+ // Chart chrome — the frame every chart draws inside, the legend that is the
718
+ // only place a series hue may sit beside text, and the readout that positions
719
+ // by transform so it can never reflow the plot.
720
+ export {
721
+ ChartFrame,
722
+ type ChartFrameProps,
723
+ type ChartFrameState,
724
+ type ChartFrameView,
725
+ type ChartTableData,
726
+ type ChartTableRow,
727
+ } from './chart-frame'
728
+ export { ChartLegend, type ChartLegendProps, type ChartLegendItem } from './chart-legend'
729
+ export { ChartTooltip, tooltipPosition, type ChartTooltipProps, type ChartTooltipRow } from './chart-tooltip'
730
+
731
+ // The series palette (ADR-146 D2/D8). Re-exported through `chart-legend.tsx`
732
+ // so this block stays one import surface and no consumer reaches into `lib/`.
733
+ // `lib/series.ts` remains the canonical definition. Callers pass a SLOT
734
+ // INDEX — never a colour, and never a token name.
735
+ export {
736
+ SERIES,
737
+ SERIES_SCATTER,
738
+ SERIES_SLOT_COUNT,
739
+ SCATTER_SLOT_COUNT,
740
+ OTHER_SLOT_COLOR,
741
+ seriesColor,
742
+ scatterColor,
743
+ paletteColor,
744
+ slotColor,
745
+ isSeriesSlot,
746
+ isScatterSlot,
747
+ type SeriesSlot,
748
+ type ScatterSlot,
749
+ type SeriesPalette,
750
+ type ChartSlot,
751
+ } from './chart-legend'
752
+
753
+ // Chart layer. Every one takes its data as `{ label, value }[]` and its series
754
+ // identity as a slot index; none of them accepts a colour.
755
+ export {
756
+ LineChart,
757
+ AreaChart,
758
+ type LineChartProps,
759
+ type LineChartSeries,
760
+ type AreaChartProps,
761
+ } from './line-chart'
762
+ export {
763
+ BarChart,
764
+ type BarChartProps,
765
+ type BarChartDatum,
766
+ type BarChartSeries,
767
+ type BarChartOrientation,
768
+ type BarChartMode,
769
+ type BarChartEmphasis,
770
+ } from './bar-chart'
771
+ export {
772
+ DonutChart,
773
+ foldDonutData,
774
+ withMinimumArc,
775
+ DONUT_OTHER_KEY,
776
+ type DonutChartProps,
777
+ type DonutChartDatum,
778
+ type DonutSlice,
779
+ type DonutFold,
780
+ type DonutGapSurface,
781
+ } from './donut-chart'
782
+ export { RankedBars, type RankedBarsProps, type RankedBarsItem, type RankedBarsSort } from './ranked-bars'
783
+ export { Sparkline, type SparklineProps, type SparklineVariant } from './sparkline'
784
+ export { GaugeRing, type GaugeRingProps, type GaugeBand, type GaugeTone } from './gauge-ring'
785
+
786
+ // Chart math (ADR-146 D6) — the scale / tick / path / arc arithmetic that was
787
+ // inlined in seven places, now one tested module. `niceTicks` is the piece
788
+ // with no ancestor in the repo: gridlines were the literal list
789
+ // [0.25, 0.5, 0.75] and axis labels were hardcoded strings. Pure functions;
790
+ // they produce numbers and path data and never name a colour or a token.
791
+ export {
792
+ linearScale,
793
+ bandScale,
794
+ niceTicks,
795
+ linePath,
796
+ areaPath,
797
+ arcGeometry,
798
+ arcSegments,
799
+ ringDash,
800
+ clampPct,
801
+ normalizeToMax,
802
+ stackTotals,
803
+ stackFractions,
804
+ monthDomain,
805
+ type NumericInput,
806
+ type Point,
807
+ type Extent,
808
+ type ScaleFn,
809
+ type BandScale,
810
+ type ArcGeometry,
811
+ type ArcSegment,
812
+ type RingDash,
813
+ } from './lib/chart'
814
+
815
+ // ── Item detail (tasks-item-detail-full.md) ─────────────────────────────────
816
+ // The three-mode detail frame, its slotted header and ellipsis menu, the
817
+ // Notion-style field rows, and the activity pane. Composed by a lens; owns no
818
+ // fetch, no entity and no board.
819
+ export * from './detail'
820
+
821
+ // ── Thread (ADR-147) ────────────────────────────────────────────────────────
822
+ // A headless comment/social core plus one styled skin, bound to an arbitrary
823
+ // entity rather than to a chat room. Owns no fetch client and no base URL.
824
+ export * from './thread'
package/src/kbd.tsx CHANGED
@@ -20,17 +20,40 @@ export interface KbdProps {
20
20
  children: ReactNode
21
21
  /** Optional size — defaults to 'md'. */
22
22
  size?: 'sm' | 'md'
23
+ /**
24
+ * Which surface this sits on. `neutral` is a normal page/card surface;
25
+ * `on-accent` is inside a filled accent control (a primary button's shortcut
26
+ * hint).
27
+ *
28
+ * This exists because the neutral palette is illegible on an accent fill and
29
+ * fails quietly rather than loudly. `--text-tertiary` ink and a `--border`
30
+ * hairline are tuned for a light-neutral ground; dropped onto `--accent` they
31
+ * read as grey-on-red mush, which is exactly what shipped in the thread
32
+ * composer before this prop existed — and it forked this primitive inline to
33
+ * do it, so the bug was invisible here.
34
+ */
35
+ tone?: 'neutral' | 'on-accent'
23
36
  }
24
37
 
25
- export function Kbd({ children, size = 'md' }: KbdProps) {
38
+ export function Kbd({ children, size = 'md', tone = 'neutral' }: KbdProps) {
39
+ const onAccent = tone === 'on-accent'
26
40
  const style: CSSProperties = {
27
41
  display: 'inline-flex',
28
42
  alignItems: 'center',
29
43
  justifyContent: 'center',
30
44
  gap: '0.125rem',
31
- background: 'rgb(var(--surface-overlay-soft))',
32
- border: '1px solid rgb(var(--border))',
33
- color: 'rgb(var(--text-tertiary))',
45
+ // On an accent fill the INK stays at full strength and the container does
46
+ // the quieting. Fading the text instead is the tempting move and it is
47
+ // wrong: white at 85% over --accent measures 4.33:1, under AA, while full
48
+ // white is 5.64:1. The translucent fill also lightens the local ground, so
49
+ // it raises the text's contrast rather than lowering it.
50
+ background: onAccent
51
+ ? 'rgb(var(--accent-foreground) / 0.16)'
52
+ : 'rgb(var(--surface-overlay-soft))',
53
+ border: `1px solid ${
54
+ onAccent ? 'rgb(var(--accent-foreground) / 0.4)' : 'rgb(var(--border))'
55
+ }`,
56
+ color: onAccent ? 'rgb(var(--accent-foreground))' : 'rgb(var(--text-tertiary))',
34
57
  fontFamily: 'var(--font-mono)',
35
58
  fontSize: size === 'sm' ? '10.5px' : '11.5px',
36
59
  padding: size === 'sm' ? '1px 6px' : '2px 8px',