@carissa-io/theme-default 0.3.13 → 0.3.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/DESIGN.md +26 -0
- package/README.md +1 -1
- package/dist/index.css +301 -6
- package/package.json +31 -6
- package/scss/index.scss +95 -2
package/DESIGN.md
CHANGED
|
@@ -270,6 +270,16 @@ The close button is a plain "x" in `--c-muted`, `--c-text` on hover, with the us
|
|
|
270
270
|
components, and it is the same in both modes (it dims whatever mode the page is in). The box fades in and rises 0.5rem in `$transition-duration`; with reduced motion it
|
|
271
271
|
just appears.
|
|
272
272
|
|
|
273
|
+
**Scroll edges (Modal and Drawer).** The body scrolls between the header and the footer, so a long body used to be cut flush against the title and the buttons with nothing
|
|
274
|
+
to show where the scroll area ends. The theme draws that edge: a **1px `--c-disabled-border` line** under the header and over the footer (the footer line exists only
|
|
275
|
+
when there is a footer), plus a fixed 0.5rem gap between each line and the header or footer content (the components' default, left as it is). The line is the quiet
|
|
276
|
+
neutral border, not `--c-muted` (the Divider's 5.74:1 line would compete with the content and with the box border): on `--c-background` it is **1.48:1 in light**
|
|
277
|
+
(`#d4d4d4` on `#fff`) and **1.91:1 in dark** (`#404040` on `#0a0a0a`). It is a decorative separator (the scroll position and the content are exposed by the scrollable region
|
|
278
|
+
itself), so the 3:1 non-text minimum does not apply; the test only requires it to be distinguishable from the background (above 1.1:1) and records the two ratios,
|
|
279
|
+
in the same spirit as the Progress track (a faint guide, 1.3:1). It is a custom property, so dark mode needs no extra rule. The unscrolled layout is the same as before:
|
|
280
|
+
the header keeps 1.25rem above and 0.5rem below its content, and the body keeps the remaining 0.75rem (1.25rem less the 0.5rem gap) on each side, so the distance
|
|
281
|
+
between the title and the content is still 1.25rem, now with the line inside it; a body without a header or without a footer keeps the whole 1.25rem on that side.
|
|
282
|
+
|
|
273
283
|
## Toast
|
|
274
284
|
From [components-toast](components/components-toast): the fixed region of toasts (24rem wide, 1rem from the edges, 0.75rem between toasts, above the page content) and its six
|
|
275
285
|
placements. The look of each toast is the Alert's (see above), so its colors, roles and contrast are the Alert's in both modes. The action is a bold, underlined
|
|
@@ -359,6 +369,7 @@ and `--c-text` for the current page (`aria-current="page"`). The content collaps
|
|
|
359
369
|
From [components-drawer](components/components-drawer): `Drawer`, the Modal's box as a panel on an edge of the screen (`start`, `end`, `top`, `bottom`; `sm` 20rem, `md` 28rem, `lg` 40rem). It is `--c-background` with `--c-text` (17.93:1 / 18.16:1), a 1px `--c-muted` border
|
|
360
370
|
(the edge that still reads in dark), square, with the Modal's layered shadow and the same padding (1.5rem by 1.25rem) and close button (`--c-muted`, `--c-text` on hover). The **backdrop** is `rgb(0 0 0 / 0.5)` in both modes, with the shadow the only literal color of the block.
|
|
361
371
|
The panel slides in over `$transition-duration`; with reduced motion it just appears.
|
|
372
|
+
The header and footer lines and the 0.5rem gaps are the Modal's (see [Modal](#modal), scroll edges): 1px `--c-disabled-border`, 1.48:1 light and 1.91:1 dark on `--c-background`.
|
|
362
373
|
|
|
363
374
|
## Menu
|
|
364
375
|
From [components-menu](components/components-menu): `Menu`, `MenuItem`, `MenuSeparator` and `MenuLabel`. The panel is the Popover's (`--c-background`, a 1px `--c-muted` border, flat). Items are `--c-text` with 0.625rem of block and 0.75rem of side padding, and hover and keyboard focus share a `--c-surface-active`
|
|
@@ -440,6 +451,21 @@ From [components-theme-switch](components/components-theme-switch): `ThemeSwitch
|
|
|
440
451
|
## Icon
|
|
441
452
|
From [components-icon](components/components-icon): `Icon`. No colour of its own: the stroke is `currentColor`, so an icon has the contrast of the text it sits in (17.93:1 / 18.16:1 for `--c-text`, 5.74:1 / 7.85:1 for `--c-muted`, both above the 3:1 non-text minimum). Sizes are pinned in rem (1, 1.25, 1.5 and 2rem) so they do not drift with the font size around them. A decorative icon is `aria-hidden`; a lone one needs a `label`.
|
|
442
453
|
|
|
454
|
+
## AI label
|
|
455
|
+
From [components-ai-label](components/components-ai-label): `AiLabel`. The mark is the neutral Badge (`--c-surface` with a `--c-muted` border, `--c-text` text at 16.44:1, see [Badge](#badge)); the optional details line is `--c-muted` text (5.74:1 / 7.85:1 on the background, 5.27:1 / 7.11:1 on `--c-surface`) at the caption size next to a `sm` mark and the small size next to a `md` one, with 0.5rem between the two. It is text beside the mark: nothing opens and nothing needs a keyboard.
|
|
456
|
+
|
|
457
|
+
## Thinking indicator
|
|
458
|
+
From [components-thinking-indicator](components/components-thinking-indicator): `ThinkingIndicator`. Three 0.375rem dots in `currentColor` of an indicator whose text is `--c-muted` (5.74:1 / 7.85:1 on the background, 5.27:1 / 7.11:1 on `--c-surface`), with the label in the small body size. The dots are decorative (the label is the accessible text), so their pulsing opacity (0.25 to 1) carries no contrast requirement; they keep the component's per-state timing (`queued` slowest, `working` fastest) and stand still at 0.6 opacity under `prefers-reduced-motion`. The dots are round, the only round shape of the set: they are not a control.
|
|
459
|
+
|
|
460
|
+
## Streaming text
|
|
461
|
+
From [components-streaming-text](components/components-streaming-text): `StreamingText`. The text is `--c-text` (17.93:1 / 18.16:1 on the background, 16.44:1 on `--c-surface`) at the body line height (1.5). The caret is a 0.125em wide square bar in `currentColor`, so it always has the contrast of the text it follows and follows both modes with no colour of its own; it blinks at 1s and is steady under `prefers-reduced-motion`. The caret is `aria-hidden` and the text never announces itself.
|
|
462
|
+
|
|
463
|
+
## Message
|
|
464
|
+
From [components-message](components/components-message): `Message`. The roles are told apart by more than colour: the **user's** message sits at the end of the column on a `--c-surface-active` bubble, the **assistant's** at the start on a `--c-surface` bubble with a 1px `--c-surface-active` border, and the **system's** is centred, unframed and `--c-muted`; every message also shows its author name as a bold caption in `--c-muted` (a visible text cue that does not depend on colour or alignment). Contrast: `--c-text` is 14.23:1 / 13.88:1 on the user bubble and 16.44:1 / 16.44:1 on the assistant one; the name is 4.56:1 / 6.00:1 on the user bubble and 5.27:1 / 7.11:1 on the assistant one; the system text is 5.74:1 / 7.85:1 on the background. The bubbles are square, like the cards, with 0.75rem 1rem of padding, and the bubble fills sit at 1.26:1 / 1.31:1 (`--c-surface-active`) and 1.09:1 / 1.10:1 (`--c-surface`) against the background, so they are a quiet cue and never the only one. A **stopped** note is `--c-muted` text. A **failed** note is a sentence (the mapped error code, never the server's text) in `--c-error` (4.53:1 / 7.16:1) inside a 1px `--c-error` frame (3:1 or more as a graphic) on a `--c-background` fill, so the raw light `error` is not set on the grey bubble, where it would be 4.15:1; it is not colour alone because the sentence says what happened. Actions sit under the content, 0.25rem apart.
|
|
465
|
+
|
|
466
|
+
## Message list
|
|
467
|
+
From [components-message-list](components/components-message-list): `MessageList`. A scrolling log with no fill of its own: it sits on the page background and the bubbles carry the contrast. Messages are 1rem apart inside 1rem of padding. The log takes keyboard focus so it can be scrolled, and its ring is the theme's 1px `--c-focus` outline drawn inside the box (21:1 / 19.8:1 on the background). The "Jump to latest" button is the secondary Button (see [Buttons](#buttons)) centred on the bottom edge and floating 1rem above it; it appears only when the reader scrolled up. The `empty` slot is an `EmptyState` with 2rem of padding (keep the list on `--c-background`, see [Empty state](#empty-state)). No scroll shadow: the component has no variable for it.
|
|
468
|
+
|
|
443
469
|
## Keyboard focus (all controls)
|
|
444
470
|
One rule keeps the controls coherent: **an outlined control thickens its own border from 1px to 2px, black** (text fields,
|
|
445
471
|
select, combobox, date picker, textarea, upload, empty checkbox, off switch, radio, secondary and ghost buttons); **a filled
|
package/README.md
CHANGED
|
@@ -142,7 +142,7 @@ it: check the names against the theme's `scss/_tokens.scss` before you switch.
|
|
|
142
142
|
|
|
143
143
|
## What it configures
|
|
144
144
|
`components-input`, `-button`, `-checkbox`, `-switch`, `-radio-group`, `-slider`, `-popover`, `-listbox`, `-select`,
|
|
145
|
-
`-combobox`, `-upload`, `-calendar`, `-date-picker`, `-search`, `-typography`, `-card`, `-alert`, `-spinner`, `-modal`, `-toast`, `-divider`, `-badge`, `-tag`, `-link`, `-avatar`, `-skeleton`, `-progress`, `-tooltip`, `-prose`, `-tabs`, `-accordion`, `-breadcrumb`, `-pagination`, `-stepper`, `-sidebar`, `-navbar`, `-drawer`, `-menu`, `-table`, `-list`, `-description-list`, `-stat`, `-empty-state`, `-timeline`, `-tree`, `-code`, `-field`, `-number-input`, `-otp-input`, `-phone`, `-tag-input`, `-time-picker`, `-date-range`, `-rating`, `-color-picker`, `-async-autocomplete`, `-section`, `-faq`, `-carousel`, `-visually-hidden`, `-live-region`, `-theme-switch` and `-
|
|
145
|
+
`-combobox`, `-upload`, `-calendar`, `-date-picker`, `-search`, `-typography`, `-card`, `-alert`, `-spinner`, `-modal`, `-toast`, `-divider`, `-badge`, `-tag`, `-link`, `-avatar`, `-skeleton`, `-progress`, `-tooltip`, `-prose`, `-tabs`, `-accordion`, `-breadcrumb`, `-pagination`, `-stepper`, `-sidebar`, `-navbar`, `-drawer`, `-menu`, `-table`, `-list`, `-description-list`, `-stat`, `-empty-state`, `-timeline`, `-tree`, `-code`, `-field`, `-number-input`, `-otp-input`, `-phone`, `-tag-input`, `-time-picker`, `-date-range`, `-rating`, `-color-picker`, `-async-autocomplete`, `-section`, `-faq`, `-carousel`, `-visually-hidden`, `-live-region`, `-theme-switch`, `-icon`, `-ai-label`, `-thinking-indicator`, `-streaming-text`, `-message` and `-message-list`. `components-email`, `-password`, `-url` and `-textarea`
|
|
146
146
|
are styled through the input.
|
|
147
147
|
|
|
148
148
|
The checkbox's mixed state (`indeterminate`, from the next `components-checkbox` release, class `c-checkbox--indeterminate`) is the checked box with a 10px dash in `--c-on-primary`; on an older checkbox the rule is simply unused.
|
package/dist/index.css
CHANGED
|
@@ -1651,7 +1651,8 @@
|
|
|
1651
1651
|
gap: 1rem;
|
|
1652
1652
|
align-items: flex-start;
|
|
1653
1653
|
justify-content: space-between;
|
|
1654
|
-
padding: 1.25rem 1.5rem 0;
|
|
1654
|
+
padding: 1.25rem 1.5rem 0.5rem;
|
|
1655
|
+
border-bottom: 1px solid var(--c-disabled-border);
|
|
1655
1656
|
}
|
|
1656
1657
|
|
|
1657
1658
|
.c-modal__heading {
|
|
@@ -1692,9 +1693,17 @@
|
|
|
1692
1693
|
.c-modal__body {
|
|
1693
1694
|
flex: 1 1 auto;
|
|
1694
1695
|
min-height: 0;
|
|
1695
|
-
padding: 1.
|
|
1696
|
+
padding-inline: 1.5rem;
|
|
1697
|
+
padding-top: max(0px, 1.25rem - 0.5rem);
|
|
1698
|
+
padding-bottom: max(0px, 1.25rem - 0.5rem);
|
|
1696
1699
|
overflow-y: auto;
|
|
1697
1700
|
}
|
|
1701
|
+
.c-modal__body:first-child {
|
|
1702
|
+
padding-top: 1.25rem;
|
|
1703
|
+
}
|
|
1704
|
+
.c-modal__body:last-child {
|
|
1705
|
+
padding-bottom: 1.25rem;
|
|
1706
|
+
}
|
|
1698
1707
|
|
|
1699
1708
|
.c-modal__footer {
|
|
1700
1709
|
display: flex;
|
|
@@ -1702,7 +1711,8 @@
|
|
|
1702
1711
|
flex-wrap: wrap;
|
|
1703
1712
|
gap: 1rem;
|
|
1704
1713
|
justify-content: flex-end;
|
|
1705
|
-
padding: 0 1.5rem 1.25rem;
|
|
1714
|
+
padding: 0.5rem 1.5rem 1.25rem;
|
|
1715
|
+
border-top: 1px solid var(--c-disabled-border);
|
|
1706
1716
|
}
|
|
1707
1717
|
|
|
1708
1718
|
@keyframes c-toast-enter {
|
|
@@ -3563,7 +3573,8 @@ hr.c-divider {
|
|
|
3563
3573
|
gap: 1rem;
|
|
3564
3574
|
align-items: flex-start;
|
|
3565
3575
|
justify-content: space-between;
|
|
3566
|
-
padding: 1.25rem 1.5rem 0;
|
|
3576
|
+
padding: 1.25rem 1.5rem 0.5rem;
|
|
3577
|
+
border-bottom: 1px solid var(--c-disabled-border);
|
|
3567
3578
|
}
|
|
3568
3579
|
|
|
3569
3580
|
.c-drawer__heading {
|
|
@@ -3604,9 +3615,17 @@ hr.c-divider {
|
|
|
3604
3615
|
.c-drawer__body {
|
|
3605
3616
|
flex: 1 1 auto;
|
|
3606
3617
|
min-height: 0;
|
|
3607
|
-
padding: 1.
|
|
3618
|
+
padding-inline: 1.5rem;
|
|
3619
|
+
padding-top: max(0px, 1.25rem - 0.5rem);
|
|
3620
|
+
padding-bottom: max(0px, 1.25rem - 0.5rem);
|
|
3608
3621
|
overflow-y: auto;
|
|
3609
3622
|
}
|
|
3623
|
+
.c-drawer__body:first-child {
|
|
3624
|
+
padding-top: 1.25rem;
|
|
3625
|
+
}
|
|
3626
|
+
.c-drawer__body:last-child {
|
|
3627
|
+
padding-bottom: 1.25rem;
|
|
3628
|
+
}
|
|
3610
3629
|
|
|
3611
3630
|
.c-drawer__footer {
|
|
3612
3631
|
display: flex;
|
|
@@ -3614,7 +3633,8 @@ hr.c-divider {
|
|
|
3614
3633
|
flex-wrap: wrap;
|
|
3615
3634
|
gap: 1rem;
|
|
3616
3635
|
justify-content: flex-end;
|
|
3617
|
-
padding: 0 1.5rem 1.25rem;
|
|
3636
|
+
padding: 0.5rem 1.5rem 1.25rem;
|
|
3637
|
+
border-top: 1px solid var(--c-disabled-border);
|
|
3618
3638
|
}
|
|
3619
3639
|
|
|
3620
3640
|
.c-menu {
|
|
@@ -5436,3 +5456,278 @@ button.c-theme-switch:focus-visible {
|
|
|
5436
5456
|
width: 2rem;
|
|
5437
5457
|
height: 2rem;
|
|
5438
5458
|
}
|
|
5459
|
+
|
|
5460
|
+
.c-ai-label {
|
|
5461
|
+
display: inline-flex;
|
|
5462
|
+
flex-wrap: wrap;
|
|
5463
|
+
gap: 0.5rem;
|
|
5464
|
+
align-items: center;
|
|
5465
|
+
vertical-align: middle;
|
|
5466
|
+
}
|
|
5467
|
+
|
|
5468
|
+
.c-ai-label__details {
|
|
5469
|
+
color: var(--c-muted);
|
|
5470
|
+
}
|
|
5471
|
+
|
|
5472
|
+
.c-ai-label--sm .c-ai-label__details {
|
|
5473
|
+
font-size: 0.75rem;
|
|
5474
|
+
}
|
|
5475
|
+
|
|
5476
|
+
.c-ai-label--md .c-ai-label__details {
|
|
5477
|
+
font-size: 0.875rem;
|
|
5478
|
+
}
|
|
5479
|
+
|
|
5480
|
+
@keyframes c-thinking-indicator-dot {
|
|
5481
|
+
0%, 80%, 100% {
|
|
5482
|
+
opacity: 0.25;
|
|
5483
|
+
transform: scale(0.8);
|
|
5484
|
+
}
|
|
5485
|
+
40% {
|
|
5486
|
+
opacity: 1;
|
|
5487
|
+
transform: scale(1);
|
|
5488
|
+
}
|
|
5489
|
+
}
|
|
5490
|
+
.c-thinking-indicator {
|
|
5491
|
+
--c-thinking-indicator-duration: 1.2s;
|
|
5492
|
+
display: inline-flex;
|
|
5493
|
+
gap: 0.5rem;
|
|
5494
|
+
align-items: center;
|
|
5495
|
+
font-size: 0.875rem;
|
|
5496
|
+
color: var(--c-muted);
|
|
5497
|
+
}
|
|
5498
|
+
|
|
5499
|
+
.c-thinking-indicator--queued {
|
|
5500
|
+
--c-thinking-indicator-duration: 2.4s;
|
|
5501
|
+
}
|
|
5502
|
+
|
|
5503
|
+
.c-thinking-indicator--typing {
|
|
5504
|
+
--c-thinking-indicator-duration: 1.2s;
|
|
5505
|
+
}
|
|
5506
|
+
|
|
5507
|
+
.c-thinking-indicator--reasoning {
|
|
5508
|
+
--c-thinking-indicator-duration: 1.8s;
|
|
5509
|
+
}
|
|
5510
|
+
|
|
5511
|
+
.c-thinking-indicator--working {
|
|
5512
|
+
--c-thinking-indicator-duration: 0.9s;
|
|
5513
|
+
}
|
|
5514
|
+
|
|
5515
|
+
.c-thinking-indicator__dots {
|
|
5516
|
+
display: inline-flex;
|
|
5517
|
+
gap: 0.25rem;
|
|
5518
|
+
align-items: center;
|
|
5519
|
+
}
|
|
5520
|
+
|
|
5521
|
+
.c-thinking-indicator__dot {
|
|
5522
|
+
display: block;
|
|
5523
|
+
width: 0.375rem;
|
|
5524
|
+
height: 0.375rem;
|
|
5525
|
+
background: currentColor;
|
|
5526
|
+
border-radius: 50%;
|
|
5527
|
+
opacity: 0.25;
|
|
5528
|
+
animation: c-thinking-indicator-dot var(--c-thinking-indicator-duration) ease-in-out infinite;
|
|
5529
|
+
}
|
|
5530
|
+
.c-thinking-indicator__dot:nth-child(2) {
|
|
5531
|
+
animation-delay: 0.15s;
|
|
5532
|
+
}
|
|
5533
|
+
.c-thinking-indicator__dot:nth-child(3) {
|
|
5534
|
+
animation-delay: 0.3s;
|
|
5535
|
+
}
|
|
5536
|
+
@media (prefers-reduced-motion: reduce) {
|
|
5537
|
+
.c-thinking-indicator__dot {
|
|
5538
|
+
opacity: 0.6;
|
|
5539
|
+
animation: none;
|
|
5540
|
+
}
|
|
5541
|
+
}
|
|
5542
|
+
|
|
5543
|
+
.c-thinking-indicator__label--hidden {
|
|
5544
|
+
position: absolute;
|
|
5545
|
+
width: 1px;
|
|
5546
|
+
height: 1px;
|
|
5547
|
+
padding: 0;
|
|
5548
|
+
margin: -1px;
|
|
5549
|
+
overflow: hidden;
|
|
5550
|
+
white-space: nowrap;
|
|
5551
|
+
border: 0;
|
|
5552
|
+
clip-path: inset(50%);
|
|
5553
|
+
}
|
|
5554
|
+
|
|
5555
|
+
@keyframes c-streaming-text-caret {
|
|
5556
|
+
0%, 45% {
|
|
5557
|
+
opacity: 1;
|
|
5558
|
+
}
|
|
5559
|
+
55%, 100% {
|
|
5560
|
+
opacity: 0;
|
|
5561
|
+
}
|
|
5562
|
+
}
|
|
5563
|
+
.c-streaming-text {
|
|
5564
|
+
color: var(--c-text);
|
|
5565
|
+
overflow-wrap: anywhere;
|
|
5566
|
+
}
|
|
5567
|
+
|
|
5568
|
+
.c-streaming-text--plain {
|
|
5569
|
+
line-height: 1.5;
|
|
5570
|
+
white-space: pre-wrap;
|
|
5571
|
+
}
|
|
5572
|
+
|
|
5573
|
+
.c-streaming-text__caret {
|
|
5574
|
+
display: inline-block;
|
|
5575
|
+
width: 0.125em;
|
|
5576
|
+
height: 1.1em;
|
|
5577
|
+
margin-inline-start: 0.125em;
|
|
5578
|
+
vertical-align: text-bottom;
|
|
5579
|
+
background: currentColor;
|
|
5580
|
+
border-radius: 0;
|
|
5581
|
+
animation: c-streaming-text-caret 1s step-end infinite;
|
|
5582
|
+
}
|
|
5583
|
+
@media (prefers-reduced-motion: reduce) {
|
|
5584
|
+
.c-streaming-text__caret {
|
|
5585
|
+
animation: none;
|
|
5586
|
+
}
|
|
5587
|
+
}
|
|
5588
|
+
|
|
5589
|
+
.c-message {
|
|
5590
|
+
box-sizing: border-box;
|
|
5591
|
+
display: flex;
|
|
5592
|
+
gap: 0.75rem;
|
|
5593
|
+
align-items: flex-start;
|
|
5594
|
+
max-width: 42rem;
|
|
5595
|
+
}
|
|
5596
|
+
|
|
5597
|
+
.c-message--user {
|
|
5598
|
+
align-self: flex-end;
|
|
5599
|
+
flex-direction: row-reverse;
|
|
5600
|
+
color: var(--c-text);
|
|
5601
|
+
}
|
|
5602
|
+
|
|
5603
|
+
.c-message--assistant {
|
|
5604
|
+
align-self: flex-start;
|
|
5605
|
+
color: var(--c-text);
|
|
5606
|
+
}
|
|
5607
|
+
|
|
5608
|
+
.c-message--system {
|
|
5609
|
+
align-self: center;
|
|
5610
|
+
font-size: 0.875rem;
|
|
5611
|
+
color: var(--c-muted);
|
|
5612
|
+
}
|
|
5613
|
+
|
|
5614
|
+
.c-message__avatar {
|
|
5615
|
+
flex: none;
|
|
5616
|
+
}
|
|
5617
|
+
|
|
5618
|
+
.c-message__body {
|
|
5619
|
+
box-sizing: border-box;
|
|
5620
|
+
display: flex;
|
|
5621
|
+
flex: 0 1 auto;
|
|
5622
|
+
flex-direction: column;
|
|
5623
|
+
gap: 0.5rem;
|
|
5624
|
+
min-width: 0;
|
|
5625
|
+
padding: 0.75rem 1rem;
|
|
5626
|
+
border: 1px solid transparent;
|
|
5627
|
+
border-radius: 0;
|
|
5628
|
+
}
|
|
5629
|
+
|
|
5630
|
+
.c-message--user .c-message__body {
|
|
5631
|
+
background: var(--c-surface-active);
|
|
5632
|
+
border-color: var(--c-surface-active);
|
|
5633
|
+
}
|
|
5634
|
+
|
|
5635
|
+
.c-message--assistant .c-message__body {
|
|
5636
|
+
background: var(--c-surface);
|
|
5637
|
+
border-color: var(--c-surface-active);
|
|
5638
|
+
}
|
|
5639
|
+
|
|
5640
|
+
.c-message--system .c-message__body {
|
|
5641
|
+
background: transparent;
|
|
5642
|
+
border-color: transparent;
|
|
5643
|
+
}
|
|
5644
|
+
|
|
5645
|
+
.c-message__header {
|
|
5646
|
+
display: flex;
|
|
5647
|
+
flex-wrap: wrap;
|
|
5648
|
+
gap: 0.75rem;
|
|
5649
|
+
align-items: center;
|
|
5650
|
+
}
|
|
5651
|
+
|
|
5652
|
+
.c-message__name {
|
|
5653
|
+
display: block;
|
|
5654
|
+
font-size: 0.75rem;
|
|
5655
|
+
font-weight: 700;
|
|
5656
|
+
color: var(--c-muted);
|
|
5657
|
+
}
|
|
5658
|
+
|
|
5659
|
+
.c-message__content {
|
|
5660
|
+
min-width: 0;
|
|
5661
|
+
}
|
|
5662
|
+
|
|
5663
|
+
.c-message__note {
|
|
5664
|
+
margin: 0;
|
|
5665
|
+
font-size: 0.875rem;
|
|
5666
|
+
}
|
|
5667
|
+
|
|
5668
|
+
.c-message__note--stopped {
|
|
5669
|
+
color: var(--c-muted);
|
|
5670
|
+
}
|
|
5671
|
+
|
|
5672
|
+
.c-message__note--failed {
|
|
5673
|
+
padding: 0.5rem 0.75rem;
|
|
5674
|
+
color: var(--c-error);
|
|
5675
|
+
background: var(--c-background);
|
|
5676
|
+
border: 1px solid var(--c-error);
|
|
5677
|
+
border-radius: 0;
|
|
5678
|
+
}
|
|
5679
|
+
|
|
5680
|
+
.c-message__actions {
|
|
5681
|
+
display: flex;
|
|
5682
|
+
flex-wrap: wrap;
|
|
5683
|
+
gap: 0.25rem;
|
|
5684
|
+
margin-top: 0.25rem;
|
|
5685
|
+
}
|
|
5686
|
+
|
|
5687
|
+
.c-message-list {
|
|
5688
|
+
position: relative;
|
|
5689
|
+
box-sizing: border-box;
|
|
5690
|
+
display: flex;
|
|
5691
|
+
flex-direction: column;
|
|
5692
|
+
height: 100%;
|
|
5693
|
+
min-height: 0;
|
|
5694
|
+
}
|
|
5695
|
+
|
|
5696
|
+
.c-message-list__log {
|
|
5697
|
+
box-sizing: border-box;
|
|
5698
|
+
flex: 1 1 auto;
|
|
5699
|
+
min-height: 0;
|
|
5700
|
+
padding: 1rem;
|
|
5701
|
+
overflow-y: auto;
|
|
5702
|
+
overscroll-behavior: contain;
|
|
5703
|
+
overflow-anchor: none;
|
|
5704
|
+
background: transparent;
|
|
5705
|
+
}
|
|
5706
|
+
.c-message-list__log:focus-visible {
|
|
5707
|
+
outline: 1px solid var(--c-focus);
|
|
5708
|
+
outline-offset: -2px;
|
|
5709
|
+
}
|
|
5710
|
+
|
|
5711
|
+
.c-message-list__content {
|
|
5712
|
+
display: flex;
|
|
5713
|
+
flex-direction: column;
|
|
5714
|
+
gap: 1rem;
|
|
5715
|
+
}
|
|
5716
|
+
|
|
5717
|
+
.c-message-list__empty {
|
|
5718
|
+
padding: 2rem;
|
|
5719
|
+
}
|
|
5720
|
+
|
|
5721
|
+
.c-message-list__jump {
|
|
5722
|
+
position: absolute;
|
|
5723
|
+
right: 0;
|
|
5724
|
+
bottom: 1rem;
|
|
5725
|
+
left: 0;
|
|
5726
|
+
z-index: 1;
|
|
5727
|
+
display: flex;
|
|
5728
|
+
justify-content: center;
|
|
5729
|
+
pointer-events: none;
|
|
5730
|
+
}
|
|
5731
|
+
.c-message-list__jump > * {
|
|
5732
|
+
pointer-events: auto;
|
|
5733
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@carissa-io/theme-default",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.15",
|
|
4
4
|
"description": "Carissa UI: the default theme (Swiss minimalism) as SCSS variable overrides of the Carissa components, with a compiled CSS build",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"style": "dist/index.css",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"@carissa-io/components-card": "^0.1.0",
|
|
57
57
|
"@carissa-io/components-alert": "^0.1.0",
|
|
58
58
|
"@carissa-io/components-spinner": "^0.1.0",
|
|
59
|
-
"@carissa-io/components-modal": "^0.1.
|
|
59
|
+
"@carissa-io/components-modal": "^0.1.2",
|
|
60
60
|
"@carissa-io/components-toast": "^0.1.0",
|
|
61
61
|
"@carissa-io/components-divider": "^0.1.0",
|
|
62
62
|
"@carissa-io/components-badge": "^0.1.0",
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
"@carissa-io/components-stepper": "^0.1.0",
|
|
75
75
|
"@carissa-io/components-sidebar": "^0.1.0",
|
|
76
76
|
"@carissa-io/components-navbar": "^0.1.0",
|
|
77
|
-
"@carissa-io/components-drawer": "^0.1.
|
|
77
|
+
"@carissa-io/components-drawer": "^0.1.2",
|
|
78
78
|
"@carissa-io/components-menu": "^0.1.0",
|
|
79
79
|
"@carissa-io/components-table": "^0.1.0",
|
|
80
80
|
"@carissa-io/components-list": "^0.1.0",
|
|
@@ -100,7 +100,12 @@
|
|
|
100
100
|
"@carissa-io/components-visually-hidden": "^0.1.0",
|
|
101
101
|
"@carissa-io/components-live-region": "^0.1.0",
|
|
102
102
|
"@carissa-io/components-theme-switch": "^0.1.0",
|
|
103
|
-
"@carissa-io/components-icon": "^0.1.0"
|
|
103
|
+
"@carissa-io/components-icon": "^0.1.0",
|
|
104
|
+
"@carissa-io/components-ai-label": "^0.1.0",
|
|
105
|
+
"@carissa-io/components-thinking-indicator": "^0.1.0",
|
|
106
|
+
"@carissa-io/components-streaming-text": "^0.1.0",
|
|
107
|
+
"@carissa-io/components-message": "^0.1.0",
|
|
108
|
+
"@carissa-io/components-message-list": "^0.1.0"
|
|
104
109
|
},
|
|
105
110
|
"peerDependenciesMeta": {
|
|
106
111
|
"@carissa-io/components-input": {
|
|
@@ -303,10 +308,26 @@
|
|
|
303
308
|
},
|
|
304
309
|
"@carissa-io/components-icon": {
|
|
305
310
|
"optional": true
|
|
311
|
+
},
|
|
312
|
+
"@carissa-io/components-ai-label": {
|
|
313
|
+
"optional": true
|
|
314
|
+
},
|
|
315
|
+
"@carissa-io/components-thinking-indicator": {
|
|
316
|
+
"optional": true
|
|
317
|
+
},
|
|
318
|
+
"@carissa-io/components-streaming-text": {
|
|
319
|
+
"optional": true
|
|
320
|
+
},
|
|
321
|
+
"@carissa-io/components-message": {
|
|
322
|
+
"optional": true
|
|
323
|
+
},
|
|
324
|
+
"@carissa-io/components-message-list": {
|
|
325
|
+
"optional": true
|
|
306
326
|
}
|
|
307
327
|
},
|
|
308
328
|
"devDependencies": {
|
|
309
329
|
"@carissa-io/components-accordion": "^0.1.0",
|
|
330
|
+
"@carissa-io/components-ai-label": "^0.1.0",
|
|
310
331
|
"@carissa-io/components-alert": "^0.1.0",
|
|
311
332
|
"@carissa-io/components-async-autocomplete": "^0.1.0",
|
|
312
333
|
"@carissa-io/components-avatar": "^0.1.0",
|
|
@@ -324,7 +345,7 @@
|
|
|
324
345
|
"@carissa-io/components-date-range": "^0.1.0",
|
|
325
346
|
"@carissa-io/components-description-list": "^0.1.0",
|
|
326
347
|
"@carissa-io/components-divider": "^0.1.0",
|
|
327
|
-
"@carissa-io/components-drawer": "^0.1.
|
|
348
|
+
"@carissa-io/components-drawer": "^0.1.2",
|
|
328
349
|
"@carissa-io/components-empty-state": "^0.1.0",
|
|
329
350
|
"@carissa-io/components-faq": "^0.1.0",
|
|
330
351
|
"@carissa-io/components-field": "^0.1.0",
|
|
@@ -335,7 +356,9 @@
|
|
|
335
356
|
"@carissa-io/components-listbox": "^0.1.1",
|
|
336
357
|
"@carissa-io/components-live-region": "^0.1.0",
|
|
337
358
|
"@carissa-io/components-menu": "^0.1.0",
|
|
338
|
-
"@carissa-io/components-
|
|
359
|
+
"@carissa-io/components-message": "^0.1.0",
|
|
360
|
+
"@carissa-io/components-message-list": "^0.1.0",
|
|
361
|
+
"@carissa-io/components-modal": "^0.1.2",
|
|
339
362
|
"@carissa-io/components-navbar": "^0.1.0",
|
|
340
363
|
"@carissa-io/components-number-input": "^0.1.0",
|
|
341
364
|
"@carissa-io/components-otp-input": "^0.1.0",
|
|
@@ -355,12 +378,14 @@
|
|
|
355
378
|
"@carissa-io/components-spinner": "^0.1.0",
|
|
356
379
|
"@carissa-io/components-stat": "^0.1.0",
|
|
357
380
|
"@carissa-io/components-stepper": "^0.1.0",
|
|
381
|
+
"@carissa-io/components-streaming-text": "^0.1.0",
|
|
358
382
|
"@carissa-io/components-switch": "^0.1.1",
|
|
359
383
|
"@carissa-io/components-table": "^0.1.0",
|
|
360
384
|
"@carissa-io/components-tabs": "^0.1.0",
|
|
361
385
|
"@carissa-io/components-tag": "^0.1.0",
|
|
362
386
|
"@carissa-io/components-tag-input": "^0.1.0",
|
|
363
387
|
"@carissa-io/components-theme-switch": "^0.1.0",
|
|
388
|
+
"@carissa-io/components-thinking-indicator": "^0.1.0",
|
|
364
389
|
"@carissa-io/components-time-picker": "^0.1.0",
|
|
365
390
|
"@carissa-io/components-timeline": "^0.1.0",
|
|
366
391
|
"@carissa-io/components-toast": "^0.1.0",
|
package/scss/index.scss
CHANGED
|
@@ -655,7 +655,8 @@
|
|
|
655
655
|
// Modal: a box on the page background with a 1px muted border (the edge that still reads in dark, where a shadow is almost
|
|
656
656
|
// invisible), the theme radius, and the same 1.5rem / 1.25rem padding as Card. The backdrop is the one literal color: black
|
|
657
657
|
// at 50%, the same in both modes. Its index forwards the typography styles, already loaded and configured above, so this
|
|
658
|
-
// block goes after the Typography one (and after Card, which forwards it too).
|
|
658
|
+
// block goes after the Typography one (and after Card, which forwards it too). The scroll edges: a 1px --c-disabled-border line
|
|
659
|
+
// under the header and over the footer (the clip edge of the scrolling body), with the component's default 0.5rem gaps.
|
|
659
660
|
@use '@carissa-io/components-modal/scss' as modal with (
|
|
660
661
|
$c-modal-background: $var-background,
|
|
661
662
|
$c-modal-color: $var-text,
|
|
@@ -666,6 +667,10 @@
|
|
|
666
667
|
$c-modal-padding-x: 1.5rem,
|
|
667
668
|
$c-modal-padding-y: 1.25rem,
|
|
668
669
|
$c-modal-gap: 1rem,
|
|
670
|
+
$c-modal-header-divider-width: 1px,
|
|
671
|
+
$c-modal-header-divider-color: $var-disabled-border,
|
|
672
|
+
$c-modal-footer-divider-width: 1px,
|
|
673
|
+
$c-modal-footer-divider-color: $var-disabled-border,
|
|
669
674
|
$c-modal-margin: 1rem,
|
|
670
675
|
$c-modal-width-sm: 24rem,
|
|
671
676
|
$c-modal-width-md: 32rem,
|
|
@@ -1141,7 +1146,7 @@
|
|
|
1141
1146
|
// Drawer: the Modal's box as a panel on the edge: --c-background with --c-text, a 1px --c-muted border (the edge that still
|
|
1142
1147
|
// reads in dark), the same padding and the same close button. The backdrop is the one literal color, black at 50% in both
|
|
1143
1148
|
// modes, and so is the shadow. Its index forwards the typography styles, already loaded and configured above: this block
|
|
1144
|
-
// goes after the Typography one.
|
|
1149
|
+
// goes after the Typography one. The scroll edges are the Modal's: 1px --c-disabled-border lines, default 0.5rem gaps.
|
|
1145
1150
|
@use '@carissa-io/components-drawer/scss' as drawer with (
|
|
1146
1151
|
$c-drawer-background: $var-background,
|
|
1147
1152
|
$c-drawer-color: $var-text,
|
|
@@ -1152,6 +1157,10 @@
|
|
|
1152
1157
|
$c-drawer-padding-x: 1.5rem,
|
|
1153
1158
|
$c-drawer-padding-y: 1.25rem,
|
|
1154
1159
|
$c-drawer-gap: 1rem,
|
|
1160
|
+
$c-drawer-header-divider-width: 1px,
|
|
1161
|
+
$c-drawer-header-divider-color: $var-disabled-border,
|
|
1162
|
+
$c-drawer-footer-divider-width: 1px,
|
|
1163
|
+
$c-drawer-footer-divider-color: $var-disabled-border,
|
|
1155
1164
|
$c-drawer-size-sm: 20rem,
|
|
1156
1165
|
$c-drawer-size-md: 28rem,
|
|
1157
1166
|
$c-drawer-size-lg: 40rem,
|
|
@@ -1716,3 +1725,87 @@
|
|
|
1716
1725
|
$c-icon-size-lg: 1.5rem,
|
|
1717
1726
|
$c-icon-size-xl: 2rem
|
|
1718
1727
|
);
|
|
1728
|
+
|
|
1729
|
+
// AI label: the mark is a neutral Badge (configured above; the ai-label index forwards its styles, so this block comes after
|
|
1730
|
+
// the Badge one) and the optional details line is --c-muted text (5.74:1 / 7.85:1 on the background, 5.27:1 / 7.11:1 on
|
|
1731
|
+
// --c-surface) in the theme's caption and small sizes. It reads as text beside the mark: nothing opens.
|
|
1732
|
+
@use '@carissa-io/components-ai-label/scss' as ai-label with (
|
|
1733
|
+
$c-ai-label-gap: 0.5rem,
|
|
1734
|
+
$c-ai-label-details-color: $var-muted,
|
|
1735
|
+
$c-ai-label-details-font-size-sm: $font-size-caption,
|
|
1736
|
+
$c-ai-label-details-font-size-md: $font-size-small
|
|
1737
|
+
);
|
|
1738
|
+
|
|
1739
|
+
// Thinking indicator: the three dots are the text colour of the indicator, --c-muted (5.74:1 / 7.85:1 on the background; the
|
|
1740
|
+
// dots are decorative, the label carries the meaning), and they keep the component's own timing; the animation stops under
|
|
1741
|
+
// prefers-reduced-motion. The label is the theme's small body text in the same --c-muted.
|
|
1742
|
+
@use '@carissa-io/components-thinking-indicator/scss' as thinking-indicator with (
|
|
1743
|
+
$c-thinking-indicator-gap: 0.5rem,
|
|
1744
|
+
$c-thinking-indicator-color: $var-muted,
|
|
1745
|
+
$c-thinking-indicator-font-size: $font-size-small,
|
|
1746
|
+
$c-thinking-indicator-dot-color: currentColor
|
|
1747
|
+
);
|
|
1748
|
+
|
|
1749
|
+
// Streaming text: the answer is --c-text (17.93:1 / 18.16:1 on the background) at the theme's body line height. The caret is a
|
|
1750
|
+
// thin square bar in currentColor, so it always has the contrast of the text it follows, in both modes; it is steady under
|
|
1751
|
+
// prefers-reduced-motion. No other block forwards it.
|
|
1752
|
+
@use '@carissa-io/components-streaming-text/scss' as streaming-text with (
|
|
1753
|
+
$c-streaming-text-color: $var-text,
|
|
1754
|
+
$c-streaming-text-line-height: $line-height-normal,
|
|
1755
|
+
$c-streaming-text-caret-color: currentColor,
|
|
1756
|
+
$c-streaming-text-caret-width: 0.125em,
|
|
1757
|
+
$c-streaming-text-caret-radius: 0
|
|
1758
|
+
);
|
|
1759
|
+
|
|
1760
|
+
// Message: the roles differ by more than colour. The user's message sits at the end of the column on a --c-surface-active bubble
|
|
1761
|
+
// (--c-text 14.23:1 / 13.88:1), the assistant's at the start on --c-surface (16.44:1 / 16.44:1) and the system's is centred, muted
|
|
1762
|
+
// (--c-muted 5.74:1 / 7.85:1 on the background) and unframed; every message also shows its author name, a bold caption in --c-muted
|
|
1763
|
+
// (5.27:1 / 7.11:1 on --c-surface, 4.56:1 / 6.00:1 on --c-surface-active). Bubbles are square like the cards. A stopped note is
|
|
1764
|
+
// --c-muted text; a failed one is --c-error text in a 1px --c-error frame on --c-background (4.53:1 / 7.16:1), a sentence and a frame,
|
|
1765
|
+
// never colour alone. No other block forwards it.
|
|
1766
|
+
@use '@carissa-io/components-message/scss' as message with (
|
|
1767
|
+
$c-message-gap: 0.75rem,
|
|
1768
|
+
$c-message-max-width: 42rem,
|
|
1769
|
+
$c-message-padding-y: 0.75rem,
|
|
1770
|
+
$c-message-padding-x: 1rem,
|
|
1771
|
+
$c-message-radius: $radius,
|
|
1772
|
+
$c-message-border-width: 1px,
|
|
1773
|
+
$c-message-body-gap: 0.5rem,
|
|
1774
|
+
$c-message-user-color: $var-text,
|
|
1775
|
+
$c-message-user-background: $var-surface-active,
|
|
1776
|
+
$c-message-user-border-color: $var-surface-active,
|
|
1777
|
+
$c-message-assistant-color: $var-text,
|
|
1778
|
+
$c-message-assistant-background: $var-surface,
|
|
1779
|
+
$c-message-assistant-border-color: $var-surface-active,
|
|
1780
|
+
$c-message-system-color: $var-muted,
|
|
1781
|
+
$c-message-system-background: transparent,
|
|
1782
|
+
$c-message-system-border-color: transparent,
|
|
1783
|
+
$c-message-system-font-size: $font-size-small,
|
|
1784
|
+
$c-message-name-color: $var-muted,
|
|
1785
|
+
$c-message-name-font-size: $font-size-caption,
|
|
1786
|
+
$c-message-name-font-weight: $font-weight-bold,
|
|
1787
|
+
$c-message-header-gap: 0.75rem,
|
|
1788
|
+
$c-message-note-font-size: $font-size-small,
|
|
1789
|
+
$c-message-stopped-color: $var-muted,
|
|
1790
|
+
$c-message-failed-color: $var-error,
|
|
1791
|
+
$c-message-failed-background: $var-background,
|
|
1792
|
+
$c-message-failed-border-color: $var-error,
|
|
1793
|
+
$c-message-failed-radius: $radius,
|
|
1794
|
+
$c-message-failed-padding: 0.5rem 0.75rem,
|
|
1795
|
+
$c-message-actions-gap: 0.25rem,
|
|
1796
|
+
$c-message-actions-margin-top: 0.25rem
|
|
1797
|
+
);
|
|
1798
|
+
|
|
1799
|
+
// Message list: no fill of its own (it sits on the page background, so the bubbles above carry the contrast). The log takes
|
|
1800
|
+
// keyboard focus, so it gets the theme's 1px --c-focus ring drawn inside (21:1 / 19.8:1). The "Jump to latest" button is the
|
|
1801
|
+
// secondary Button (configured above; the list index forwards its styles, so this block comes after the Button, Live region
|
|
1802
|
+
// and Icon ones) floating 1rem above the bottom edge, centred. The empty state is the EmptyState's (configured above).
|
|
1803
|
+
@use '@carissa-io/components-message-list/scss' as message-list with (
|
|
1804
|
+
$c-message-list-padding: 1rem,
|
|
1805
|
+
$c-message-list-gap: 1rem,
|
|
1806
|
+
$c-message-list-focus-outline: $focus-width solid $var-focus,
|
|
1807
|
+
$c-message-list-focus-outline-offset: -2px,
|
|
1808
|
+
$c-message-list-empty-padding: 2rem,
|
|
1809
|
+
$c-message-list-jump-bottom: 1rem,
|
|
1810
|
+
$c-message-list-jump-z-index: 1
|
|
1811
|
+
);
|