@salemcobalt/ui 0.2.0-rc.13 → 0.2.0-rc.15

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/styles.css CHANGED
@@ -1,4 +1,4 @@
1
- /* @salemcobalt/ui 0.2.0-rc.13 — requires @salemcobalt/tokens/css. */
1
+ /* @salemcobalt/ui 0.2.0-rc.15 — requires @salemcobalt/tokens/css. */
2
2
  @layer sc {
3
3
  /* ---- base.css ---- */
4
4
  /* Shared: focus ring, reduced motion. Component files follow. */
@@ -73,6 +73,16 @@
73
73
  line-height: var(--sc-font-line-height-tight);
74
74
  letter-spacing: var(--sc-font-tracking-tight);
75
75
  }
76
+ /* Overline: a section label. 12px uppercase mono with wide tracking; muted unless a tone is set. */
77
+ .sc-heading[data-size='overline'] {
78
+ font-family: var(--sc-font-family-mono);
79
+ font-size: var(--sc-font-size-xs);
80
+ font-weight: var(--sc-font-weight-medium);
81
+ line-height: var(--sc-font-line-height-snug);
82
+ letter-spacing: var(--sc-font-tracking-wider);
83
+ text-transform: uppercase;
84
+ text-wrap: wrap;
85
+ }
76
86
  .sc-heading[data-truncate] {
77
87
  overflow: hidden;
78
88
  text-overflow: ellipsis;
@@ -117,6 +127,9 @@
117
127
  .sc-text[data-numeric] {
118
128
  font-variant-numeric: tabular-nums;
119
129
  }
130
+ .sc-text[data-family='mono'] {
131
+ font-family: var(--sc-font-family-mono);
132
+ }
120
133
  .sc-text[data-truncate=''] {
121
134
  overflow: hidden;
122
135
  text-overflow: ellipsis;
@@ -367,6 +380,13 @@
367
380
  .sc-button[data-loading] > .sc-button__shortcut {
368
381
  opacity: 0;
369
382
  }
383
+ /* No hint where there is no fine pointer (phones, tablets without a trackpad): touch users rarely have the keys,
384
+ and the hint costs width. A tablet with a trackpad (any-pointer: fine) keeps it. `aria-keyshortcuts` stays. */
385
+ @media not all and (any-pointer: fine) {
386
+ .sc-button__shortcut {
387
+ display: none;
388
+ }
389
+ }
370
390
  @keyframes sc-spin {
371
391
  to {
372
392
  rotate: 1turn;
@@ -627,6 +647,26 @@
627
647
  border-color: var(--sc-color-accent-default);
628
648
  box-shadow: inset 0 0 0 1px var(--sc-color-accent-default);
629
649
  }
650
+ /* Plain: a quiet row. No surface or shadow; interactive hover is a wash (no border or elevation, so a long list
651
+ does not flicker); selected is the accent wash with a 1px accent border (3:1, the selection cue). */
652
+ .sc-card[data-variant='plain'] {
653
+ background: transparent;
654
+ border-color: transparent;
655
+ }
656
+ .sc-card[data-variant='plain'][data-interactive]:hover {
657
+ background: var(--sc-color-surface-hover);
658
+ border-color: transparent;
659
+ box-shadow: none;
660
+ }
661
+ .sc-card[data-variant='plain'][data-interactive]:active {
662
+ background: var(--sc-color-surface-active);
663
+ }
664
+ .sc-card[data-variant='plain'][data-selected],
665
+ .sc-card[data-variant='plain'][data-selected]:hover {
666
+ background: var(--sc-color-accent-wash);
667
+ border-color: var(--sc-color-accent-border);
668
+ box-shadow: none;
669
+ }
630
670
  @media (prefers-reduced-motion: reduce) {
631
671
  .sc-card {
632
672
  transition: none;
@@ -5296,4 +5336,277 @@
5296
5336
  }
5297
5337
  }
5298
5338
 
5339
+ /* ---- score.css ---- */
5340
+ /* ---- Score ----------------------------------------------------------------- */
5341
+ /* A number on a tinted tile, or inside a ring. Tone sets the tint (--_bg), the number (--_fg) and the solid used
5342
+ for the ring arc and the selected tile (--_solid, --_on-solid). */
5343
+ .sc-score {
5344
+ --_bg: var(--sc-color-accent-subtle);
5345
+ --_fg: var(--sc-color-accent-text);
5346
+ --_solid: var(--sc-color-accent-default);
5347
+ --_on-solid: var(--sc-color-text-on-accent);
5348
+ --_s: var(--sc-size-score-sm);
5349
+ position: relative;
5350
+ display: inline-grid;
5351
+ place-items: center;
5352
+ flex: none;
5353
+ box-sizing: border-box;
5354
+ inline-size: var(--_s);
5355
+ block-size: var(--_s);
5356
+ border-radius: var(--sc-radius-lg);
5357
+ background: var(--_bg);
5358
+ color: var(--_fg);
5359
+ font-family: var(--sc-font-family-sans);
5360
+ font-size: var(--sc-font-size-sm);
5361
+ font-weight: var(--sc-font-weight-semibold);
5362
+ font-variant-numeric: tabular-nums;
5363
+ line-height: 1;
5364
+ vertical-align: middle;
5365
+ transition:
5366
+ background-color var(--sc-duration-fast) var(--sc-ease-standard),
5367
+ color var(--sc-duration-fast) var(--sc-ease-standard);
5368
+ }
5369
+ .sc-score[data-size='md'] {
5370
+ --_s: var(--sc-size-score-md);
5371
+ border-radius: var(--sc-radius-xl);
5372
+ font-size: var(--sc-font-size-lg);
5373
+ }
5374
+ .sc-score[data-tone='neutral'] {
5375
+ /* surface.active, so the tile still shows on a hovered row (surface.hover). Selected turns accent. */
5376
+ --_bg: var(--sc-color-surface-active);
5377
+ --_fg: var(--sc-color-text-muted);
5378
+ --_solid: var(--sc-color-text-muted);
5379
+ }
5380
+ .sc-score[data-tone='success'] {
5381
+ --_bg: var(--sc-color-success-subtle);
5382
+ --_fg: var(--sc-color-success-text);
5383
+ --_solid: var(--sc-color-success-solid);
5384
+ --_on-solid: var(--sc-color-text-on-status);
5385
+ }
5386
+ .sc-score[data-tone='warning'] {
5387
+ --_bg: var(--sc-color-warning-subtle);
5388
+ --_fg: var(--sc-color-warning-text);
5389
+ --_solid: var(--sc-color-warning-solid);
5390
+ --_on-solid: var(--sc-color-text-on-status);
5391
+ }
5392
+ .sc-score[data-tone='danger'] {
5393
+ --_bg: var(--sc-color-danger-subtle);
5394
+ --_fg: var(--sc-color-danger-text);
5395
+ --_solid: var(--sc-color-danger-solid);
5396
+ --_on-solid: var(--sc-color-text-on-status);
5397
+ }
5398
+ .sc-score__body {
5399
+ display: grid;
5400
+ justify-items: center;
5401
+ gap: var(--sc-spacing-3xs);
5402
+ }
5403
+ .sc-score__caption {
5404
+ font-family: var(--sc-font-family-mono);
5405
+ font-size: var(--sc-font-size-xs);
5406
+ font-weight: var(--sc-font-weight-medium);
5407
+ letter-spacing: var(--sc-font-tracking-wide);
5408
+ text-transform: uppercase;
5409
+ color: var(--sc-color-text-muted);
5410
+ }
5411
+ /* Selected: the tile goes solid in its tone (neutral goes accent), inside a selected row or on `selected`. */
5412
+ .sc-score[data-variant='tile'][data-selected],
5413
+ .sc-card[data-selected] .sc-score[data-variant='tile'],
5414
+ [aria-pressed='true'] .sc-score[data-variant='tile'],
5415
+ [aria-selected='true'] .sc-score[data-variant='tile'] {
5416
+ background: var(--_solid);
5417
+ color: var(--_on-solid);
5418
+ }
5419
+ .sc-score[data-variant='tile'][data-tone='neutral'][data-selected],
5420
+ .sc-card[data-selected] .sc-score[data-variant='tile'][data-tone='neutral'],
5421
+ [aria-pressed='true'] .sc-score[data-variant='tile'][data-tone='neutral'],
5422
+ [aria-selected='true'] .sc-score[data-variant='tile'][data-tone='neutral'] {
5423
+ background: var(--sc-color-accent-default);
5424
+ color: var(--sc-color-text-on-accent);
5425
+ }
5426
+ .sc-score[data-variant='tile'][data-selected] .sc-score__caption,
5427
+ .sc-card[data-selected] .sc-score[data-variant='tile'] .sc-score__caption,
5428
+ [aria-pressed='true'] .sc-score[data-variant='tile'] .sc-score__caption,
5429
+ [aria-selected='true'] .sc-score[data-variant='tile'] .sc-score__caption {
5430
+ color: inherit;
5431
+ }
5432
+ /* Ring: the number in the tone's text colour over a donut. The SVG is drawn for the 64px ring token with a 6px
5433
+ stroke (r = 29 in Score.tsx); the arc length comes from --sc-score-fill (0–100, set inline). */
5434
+ .sc-score[data-variant='ring'] {
5435
+ --_s: var(--sc-size-score-ring);
5436
+ border-radius: var(--sc-radius-full);
5437
+ background: transparent;
5438
+ font-size: var(--sc-font-size-lg);
5439
+ }
5440
+ .sc-score__ring {
5441
+ position: absolute;
5442
+ inset: 0;
5443
+ inline-size: 100%;
5444
+ block-size: 100%;
5445
+ rotate: -90deg;
5446
+ overflow: visible;
5447
+ }
5448
+ .sc-score__track,
5449
+ .sc-score__arc {
5450
+ fill: none;
5451
+ stroke-width: var(--sc-size-score-ring-stroke);
5452
+ }
5453
+ .sc-score__track {
5454
+ stroke: var(--sc-color-surface-active);
5455
+ }
5456
+ .sc-score__arc {
5457
+ stroke: var(--_solid);
5458
+ stroke-linecap: round;
5459
+ stroke-dasharray: 100;
5460
+ stroke-dashoffset: calc(100 - var(--sc-score-fill, 0));
5461
+ /* Moves only when the value changes; the first render draws it in place. */
5462
+ transition: stroke-dashoffset var(--sc-duration-slow) var(--sc-ease-enter);
5463
+ }
5464
+ .sc-score[data-variant='ring'] .sc-score__body {
5465
+ position: relative;
5466
+ }
5467
+ @media (prefers-reduced-motion: reduce) {
5468
+ .sc-score,
5469
+ .sc-score__arc {
5470
+ transition: none;
5471
+ }
5472
+ }
5473
+
5474
+ /* ---- reason-list.css ---- */
5475
+ /* ---- ReasonList ------------------------------------------------------------ */
5476
+ /* Marker shape per tone: for = filled square, against = bar, gap = hollow circle. Markers use the tone's solid,
5477
+ 3:1 on every surface; the shape carries the meaning on its own (WCAG 1.4.1). */
5478
+ .sc-reason-list {
5479
+ --_m: 9px;
5480
+ --_marker: var(--sc-color-success-solid);
5481
+ display: grid;
5482
+ gap: var(--sc-spacing-xs);
5483
+ margin: 0;
5484
+ padding: 0;
5485
+ list-style: none;
5486
+ font-family: var(--sc-font-family-sans);
5487
+ font-size: var(--sc-font-size-sm);
5488
+ line-height: var(--sc-font-line-height-ui);
5489
+ color: var(--sc-color-text-muted);
5490
+ }
5491
+ .sc-reason-list[data-size='sm'] {
5492
+ --_m: 7px;
5493
+ gap: var(--sc-spacing-2xs);
5494
+ font-size: var(--sc-font-size-xs);
5495
+ }
5496
+ .sc-reason-list[data-divider] {
5497
+ padding-block-start: var(--sc-spacing-xs);
5498
+ border-block-start: var(--sc-border-width-hairline) dashed var(--sc-color-border-default);
5499
+ }
5500
+ .sc-reason-list[data-tone='against'] {
5501
+ --_marker: var(--sc-color-danger-solid);
5502
+ }
5503
+ .sc-reason-list[data-tone='gap'] {
5504
+ --_marker: var(--sc-color-warning-solid);
5505
+ }
5506
+ .sc-reason-list__item {
5507
+ position: relative;
5508
+ padding-inline-start: calc(var(--_m) + var(--sc-spacing-xs));
5509
+ }
5510
+ /* Centred on the first line: half the line box less half the marker. */
5511
+ .sc-reason-list__item::before {
5512
+ content: '';
5513
+ position: absolute;
5514
+ inset-inline-start: 0;
5515
+ inset-block-start: 0.45em;
5516
+ inset-block-start: calc((1lh - var(--_m)) / 2);
5517
+ box-sizing: border-box;
5518
+ inline-size: var(--_m);
5519
+ block-size: var(--_m);
5520
+ border-radius: var(--sc-radius-xs);
5521
+ background: var(--_marker);
5522
+ }
5523
+ .sc-reason-list[data-tone='against'] > .sc-reason-list__item::before {
5524
+ inset-block-start: 0.6em;
5525
+ inset-block-start: calc((1lh - var(--_m) / 3) / 2);
5526
+ block-size: calc(var(--_m) / 3);
5527
+ border-radius: var(--sc-radius-full);
5528
+ }
5529
+ .sc-reason-list[data-tone='gap'] > .sc-reason-list__item::before {
5530
+ background: transparent;
5531
+ border: var(--sc-border-width-focus) solid var(--_marker);
5532
+ border-radius: var(--sc-radius-full);
5533
+ }
5534
+ .sc-reason-list__item :where(strong, b) {
5535
+ font-weight: var(--sc-font-weight-semibold);
5536
+ color: var(--sc-color-text-default);
5537
+ }
5538
+
5539
+ /* ---- word-diff.css ---- */
5540
+ /* ---- WordDiff -------------------------------------------------------------- */
5541
+ /* Strike-through and underline carry the meaning; the tint only groups the words. Both lines are 3:1 on their tint
5542
+ (diff.*-stroke on diff.*-wash) in light and dark. */
5543
+ .sc-word-diff {
5544
+ margin: 0;
5545
+ font-family: var(--sc-font-family-sans);
5546
+ font-size: var(--sc-font-size-sm);
5547
+ line-height: var(--sc-font-line-height-normal);
5548
+ color: var(--sc-color-text-default);
5549
+ white-space: pre-wrap;
5550
+ overflow-wrap: anywhere;
5551
+ }
5552
+ .sc-word-diff[data-size='md'] {
5553
+ font-size: var(--sc-font-size-md);
5554
+ }
5555
+ p.sc-word-diff,
5556
+ div.sc-word-diff {
5557
+ max-inline-size: var(--sc-font-measure);
5558
+ }
5559
+ .sc-word-diff__added,
5560
+ .sc-word-diff__removed {
5561
+ padding-inline: var(--sc-spacing-3xs);
5562
+ border-radius: var(--sc-radius-xs);
5563
+ text-decoration-thickness: var(--sc-border-width-focus);
5564
+ box-decoration-break: clone;
5565
+ -webkit-box-decoration-break: clone;
5566
+ }
5567
+ .sc-word-diff__added {
5568
+ background: var(--sc-color-diff-added-wash);
5569
+ color: var(--sc-color-text-default);
5570
+ text-decoration-line: underline;
5571
+ text-decoration-color: var(--sc-color-diff-added-stroke);
5572
+ text-underline-offset: 0.2em;
5573
+ }
5574
+ .sc-word-diff__removed {
5575
+ background: var(--sc-color-diff-removed-wash);
5576
+ color: var(--sc-color-text-muted);
5577
+ text-decoration-line: line-through;
5578
+ text-decoration-color: var(--sc-color-diff-removed-stroke);
5579
+ }
5580
+
5581
+ /* ---- quote.css ---- */
5582
+ /* ---- Quote ----------------------------------------------------------------- */
5583
+ /* Label and words on one line, on the accent wash with the accent border (both from the plain Card selected
5584
+ state), so an echoed instruction reads as "yours" next to what changed. */
5585
+ .sc-quote {
5586
+ box-sizing: border-box;
5587
+ margin: 0;
5588
+ padding: var(--sc-spacing-xs) var(--sc-spacing-sm);
5589
+ border: var(--sc-border-width-hairline) solid var(--sc-color-accent-border);
5590
+ border-radius: var(--sc-radius-lg);
5591
+ background: var(--sc-color-accent-wash);
5592
+ font-family: var(--sc-font-family-sans);
5593
+ font-size: var(--sc-font-size-sm);
5594
+ line-height: var(--sc-font-line-height-ui);
5595
+ color: var(--sc-color-text-muted);
5596
+ }
5597
+ .sc-quote__label {
5598
+ display: inline;
5599
+ margin-inline-end: var(--sc-spacing-xs);
5600
+ font-family: var(--sc-font-family-mono);
5601
+ font-size: var(--sc-font-size-xs);
5602
+ font-weight: var(--sc-font-weight-medium);
5603
+ letter-spacing: var(--sc-font-tracking-wider);
5604
+ text-transform: uppercase;
5605
+ color: var(--sc-color-accent-text);
5606
+ }
5607
+ .sc-quote__text {
5608
+ display: inline;
5609
+ margin: 0;
5610
+ }
5611
+
5299
5612
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@salemcobalt/ui",
3
- "version": "0.2.0-rc.13",
4
- "description": "React components for the Salem Cobalt design system: Button, IconButton, Icon set, BroomIcon, Badge, Card, Stack, Inline, Kbd, Dialog, FullScreenFlow, Tooltip, Menu, Popover, PriorityNav, Toolbar, Banner, Spinner, Progress, Tabs, Input, Textarea, Select, FileInput, Checkbox, Switch, Heading, Text, Table, Stat, Chip, Disclosure, EmptyState, Skeleton.",
3
+ "version": "0.2.0-rc.15",
4
+ "description": "React components for the Salem Cobalt design system: Button, IconButton, Icon set, BroomIcon, Badge, Card, Stack, Inline, Kbd, Dialog, FullScreenFlow, Tooltip, Menu, Popover, PriorityNav, Toolbar, Banner, Spinner, Progress, Tabs, Input, Textarea, Select, FileInput, Checkbox, Switch, Heading, Text, Table, Stat, Chip, Disclosure, EmptyState, Skeleton, Score, ReasonList, WordDiff, Quote.",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",
@@ -33,7 +33,7 @@
33
33
  "peerDependencies": {
34
34
  "react": "^19.0.0",
35
35
  "react-dom": "^19.0.0",
36
- "@salemcobalt/tokens": "^0.2.0-rc.13"
36
+ "@salemcobalt/tokens": "^0.2.0-rc.15"
37
37
  },
38
38
  "dependencies": {
39
39
  "@base-ui/react": "^1.9.0",
@@ -57,7 +57,7 @@
57
57
  "tsup": "^9.0.0",
58
58
  "typescript": "^5.9.3",
59
59
  "vitest": "^5.0.5",
60
- "@salemcobalt/tokens": "^0.2.0-rc.13"
60
+ "@salemcobalt/tokens": "^0.2.0-rc.15"
61
61
  },
62
62
  "publishConfig": {
63
63
  "access": "public"