@carissa-io/theme-default 0.3.15 → 0.3.16
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 +8 -0
- package/README.md +17 -1
- package/dist/index.css +16 -0
- package/package.json +1 -1
- package/scss/_modes.scss +21 -1
- package/scss/_tokens.scss +4 -0
package/DESIGN.md
CHANGED
|
@@ -49,6 +49,8 @@ Both modes ship in the same package; dark is **opt-in per app** with `data-mode`
|
|
|
49
49
|
| `warning` | `#a16207` | `#fbbf24` |
|
|
50
50
|
| `info` | `#1d4ed8` | `#60a5fa` |
|
|
51
51
|
| `focus` | `#000000` | `#ffffff` |
|
|
52
|
+
| `scrollbar-thumb` | `#737373` | `#737373` |
|
|
53
|
+
| `scrollbar-track` | `#ffffff` | `#0a0a0a` |
|
|
52
54
|
|
|
53
55
|
Decisions: dark inverts the contrast of the light theme, it does not invent a new look (near-black ground, the primary action becomes white,
|
|
54
56
|
square corners and the 1px focus ring stay). The ground is `#0a0a0a`, not pure black, so surfaces (`#171717`) can be told apart. Primary and focus
|
|
@@ -74,6 +76,7 @@ Contrast (WCAG 2.x): text 4.5:1, borders and the focus ring 3:1.
|
|
|
74
76
|
| `info` on `background` / on `surface` | 6.70 / 6.15 | 7.79 / 7.05 |
|
|
75
77
|
| `error` on `surface` | 4.15 | 6.48 |
|
|
76
78
|
| `disabled-text` on `surface` (disabled, exempt) | 2.31 | 3.78 |
|
|
79
|
+
| `scrollbar-thumb` on `scrollbar-track` / on `background` (the same colour) | 4.74 | 4.18 |
|
|
77
80
|
|
|
78
81
|
The light `error` on `surface` (4.15) is below 4.5 for text, so the Alert never sets text in the status color (only the icon and the accent border, which need 3:1).
|
|
79
82
|
|
|
@@ -81,6 +84,11 @@ Every `muted` text pairing passes AA in both modes (a test asserts it): the ligh
|
|
|
81
84
|
`surface-active`, so it is now `#666666` (5.74 / 5.27 / 4.56). The disabled states are exempt from WCAG but are listed in the backlog for a contrast review. Known gap in dark: the 0-width listbox option separator keeps the component default
|
|
82
85
|
(`#dee2e6`); it draws nothing today.
|
|
83
86
|
|
|
87
|
+
## Scrollbars
|
|
88
|
+
Two rules theme every scroll container, and no component carries a scrollbar rule: `scrollbar-color: var(--c-scrollbar-thumb) var(--c-scrollbar-track)` on `:root` (inherited, so every scroller gets it) and `scrollbar-width: thin` on `*`. The thumb is the neutral 500 (`#737373`) in both modes; the track is the page ground, equal to `background` (`#ffffff` / `#0a0a0a`), so the scrollbar is just a thumb on the page and no extra rail is drawn. The thumb passes the 3:1 non-text minimum against the track and the background (4.74 / 4.18, the same pair) and also on `surface` (4.35 / 3.78) and the `surface-active` hover fill (3.76 / 3.19); a test asserts that the track equals the background and the ratio in each mode. Known trade-off: inside a surface-coloured container (the sidebar, a card) the track shows as a strip of the page colour; a theme can override `$scrollbar-track` (and the dark role) with its surface value. The width is `thin` (the `$scrollbar-width` token), which suits the Swiss restraint and still leaves a target the pointer can grab; touch and overlay scrollbars ignore it.
|
|
89
|
+
|
|
90
|
+
Known limits: `scrollbar-width` is not an inherited property, so a `:root` declaration would thin only the page; it is declared with a universal rule instead, which has zero specificity so it never overrides a component. The rules use the standard properties only, so there is colour and thickness but no rounding, no arrows and no hover state (those need the `::-webkit-scrollbar` pseudo-elements, which the theme deliberately does not use). Support is Chrome 121+, Firefox 64+ and Safari 18.2+; older browsers keep the native bar, which stays usable. A scroller that sets its own `scrollbar-width` keeps it, whatever the order: the carousel hides its bar on purpose (`scrollbar-width: none`, a class selector) and the theme does not undo it.
|
|
91
|
+
|
|
84
92
|
## Typography
|
|
85
93
|
Configured through [components-typography](components/components-typography): `Heading` (the element comes from `level`, the look from `size`)
|
|
86
94
|
and `Text`. Neutral grotesque, no margins (spacing belongs to the layout), color from `$text`; only muted text uses `$muted`.
|
package/README.md
CHANGED
|
@@ -29,7 +29,7 @@ peer dependencies).
|
|
|
29
29
|
## Color modes
|
|
30
30
|
The theme has a light and a dark palette in one package. The palette is a set of CSS custom properties (`--c-background`, `--c-text`,
|
|
31
31
|
`--c-muted`, `--c-surface`, `--c-surface-active`, `--c-primary`, `--c-on-primary`, `--c-primary-hover`, `--c-primary-active`,
|
|
32
|
-
`--c-disabled-text`, `--c-disabled-border`, `--c-error`, `--c-success`, `--c-warning`, `--c-info`, `--c-focus`) that every component reads. **Dark is opt-in per app**: without
|
|
32
|
+
`--c-disabled-text`, `--c-disabled-border`, `--c-error`, `--c-success`, `--c-warning`, `--c-info`, `--c-focus`, `--c-scrollbar-thumb`, `--c-scrollbar-track`) that every component reads. **Dark is opt-in per app**: without
|
|
33
33
|
the attribute below the app is light, exactly as before.
|
|
34
34
|
|
|
35
35
|
An app opts in with one line in the file where it imports the theme (`App/theme.js`), setting the mode on `<html>`:
|
|
@@ -63,6 +63,19 @@ first paint: put this in the `<head>` of the page, before the stylesheet, with t
|
|
|
63
63
|
The Sass tokens above stay the static **light** values (for Sass consumers); the dark values are in `scss/_modes.scss`. The page background and
|
|
64
64
|
text color are the app's: give `body` `background: var(--c-background); color: var(--c-text)`.
|
|
65
65
|
|
|
66
|
+
## Scrollbars
|
|
67
|
+
The theme styles every scroll container with no change in any component: the page, the message list, the table wrapper, the modal and
|
|
68
|
+
drawer bodies, the select, combobox and listbox popups, the sidebar and code blocks. It is two rules: `scrollbar-color: var(--c-scrollbar-thumb)
|
|
69
|
+
var(--c-scrollbar-track)` on `:root` (the property is inherited) and `scrollbar-width: thin` on `*`, because `scrollbar-width` is not inherited and so
|
|
70
|
+
has to be declared on every element. The `*` rule has zero specificity, so any component rule or your own rule wins over it. The colors
|
|
71
|
+
are two palette roles, so they follow `data-mode`; the thickness is the `$scrollbar-width` token.
|
|
72
|
+
|
|
73
|
+
To change them in your own theme, set `$scrollbar-thumb`, `$scrollbar-track` and `$scrollbar-width` in your `scss/_tokens.scss` (and the
|
|
74
|
+
dark values of the two roles in `scss/_modes.scss`); keep the thumb at 3:1 or more against the track and against the background. The default track is the page background, so inside a surface-coloured container (the sidebar, a card) it shows as a strip of the page colour; a theme that prefers it quieter there sets `$scrollbar-track` to its surface value. An app that
|
|
75
|
+
only needs one scroller to look different overrides the two properties on that element (`scrollbar-color`, `scrollbar-width`); the carousel
|
|
76
|
+
already hides its own bar. Browsers without the standard properties (before Chrome 121, Firefox 64 or Safari 18.2) keep the native bar. See
|
|
77
|
+
[DESIGN.md](DESIGN.md) for the values and limits.
|
|
78
|
+
|
|
66
79
|
## Tokens
|
|
67
80
|
The palette and the values shared by every component are Sass variables in `scss/_tokens.scss`, the single source of
|
|
68
81
|
the theme's values (`scss/index.scss` reads them with `@use 'tokens' as *`). The file emits no CSS, so an app can read
|
|
@@ -89,6 +102,9 @@ change.
|
|
|
89
102
|
| `$success` | `#15803d` | success accent and icon (Alert) |
|
|
90
103
|
| `$warning` | `#a16207` | warning accent and icon (Alert) |
|
|
91
104
|
| `$info` | `#1d4ed8` | info accent and icon (Alert) |
|
|
105
|
+
| `$scrollbar-thumb` | `#737373` | scrollbar thumb |
|
|
106
|
+
| `$scrollbar-track` | `$white` | scrollbar track (the page ground) |
|
|
107
|
+
| `$scrollbar-width` | `thin` | scrollbar thickness |
|
|
92
108
|
| `$font-family` | `'Helvetica Neue', Helvetica, Arial, 'Liberation Sans', sans-serif` | type stack |
|
|
93
109
|
| `$font-family-mono` | `ui-monospace, 'SFMono-Regular', Menlo, Consolas, 'Liberation Mono', monospace` | monospace stack for system data and code |
|
|
94
110
|
| `$radius` | `0` | corner radius |
|
package/dist/index.css
CHANGED
|
@@ -16,6 +16,8 @@
|
|
|
16
16
|
--c-warning: #a16207;
|
|
17
17
|
--c-info: #1d4ed8;
|
|
18
18
|
--c-focus: #000;
|
|
19
|
+
--c-scrollbar-thumb: #737373;
|
|
20
|
+
--c-scrollbar-track: #fff;
|
|
19
21
|
color-scheme: light;
|
|
20
22
|
}
|
|
21
23
|
|
|
@@ -36,6 +38,8 @@
|
|
|
36
38
|
--c-warning: #a16207;
|
|
37
39
|
--c-info: #1d4ed8;
|
|
38
40
|
--c-focus: #000;
|
|
41
|
+
--c-scrollbar-thumb: #737373;
|
|
42
|
+
--c-scrollbar-track: #fff;
|
|
39
43
|
color-scheme: light;
|
|
40
44
|
}
|
|
41
45
|
|
|
@@ -56,6 +60,8 @@
|
|
|
56
60
|
--c-warning: #fbbf24;
|
|
57
61
|
--c-info: #60a5fa;
|
|
58
62
|
--c-focus: #fff;
|
|
63
|
+
--c-scrollbar-thumb: #737373;
|
|
64
|
+
--c-scrollbar-track: #0a0a0a;
|
|
59
65
|
color-scheme: dark;
|
|
60
66
|
}
|
|
61
67
|
|
|
@@ -77,9 +83,19 @@
|
|
|
77
83
|
--c-warning: #fbbf24;
|
|
78
84
|
--c-info: #60a5fa;
|
|
79
85
|
--c-focus: #fff;
|
|
86
|
+
--c-scrollbar-thumb: #737373;
|
|
87
|
+
--c-scrollbar-track: #0a0a0a;
|
|
80
88
|
color-scheme: dark;
|
|
81
89
|
}
|
|
82
90
|
}
|
|
91
|
+
:root {
|
|
92
|
+
scrollbar-color: var(--c-scrollbar-thumb) var(--c-scrollbar-track);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
* {
|
|
96
|
+
scrollbar-width: thin;
|
|
97
|
+
}
|
|
98
|
+
|
|
83
99
|
.c-input {
|
|
84
100
|
display: block;
|
|
85
101
|
font-family: "Helvetica Neue", Helvetica, Arial, "Liberation Sans", sans-serif;
|
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.16",
|
|
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",
|
package/scss/_modes.scss
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// Carissa Default theme color modes: the light and dark palettes, emitted as CSS custom properties (`--c-<role>`).
|
|
2
|
-
// Loading this partial emits the CSS below (`@use 'modes' as *` in index.scss)
|
|
2
|
+
// Loading this partial emits the CSS below (`@use 'modes' as *` in index.scss), including the two scrollbar rules (`:root` and `*`) at the end;
|
|
3
|
+
// `_tokens.scss` stays Sass-only.
|
|
3
4
|
//
|
|
4
5
|
// no attribute light (the default)
|
|
5
6
|
// data-mode="light" light
|
|
@@ -28,6 +29,8 @@ $light: (
|
|
|
28
29
|
'warning': t.$warning,
|
|
29
30
|
'info': t.$info,
|
|
30
31
|
'focus': t.$focus-color,
|
|
32
|
+
'scrollbar-thumb': t.$scrollbar-thumb,
|
|
33
|
+
'scrollbar-track': t.$scrollbar-track,
|
|
31
34
|
);
|
|
32
35
|
|
|
33
36
|
// Dark: near-black ground, the contrast of the light theme inverted (see DESIGN.md for the ratios).
|
|
@@ -48,6 +51,8 @@ $dark: (
|
|
|
48
51
|
'warning': #fbbf24,
|
|
49
52
|
'info': #60a5fa,
|
|
50
53
|
'focus': #fff,
|
|
54
|
+
'scrollbar-thumb': #737373,
|
|
55
|
+
'scrollbar-track': #0a0a0a, // the dark background
|
|
51
56
|
);
|
|
52
57
|
|
|
53
58
|
// What the component blocks read: `var(--c-<role>)`, one per role.
|
|
@@ -67,6 +72,8 @@ $var-success: var(--c-success);
|
|
|
67
72
|
$var-warning: var(--c-warning);
|
|
68
73
|
$var-info: var(--c-info);
|
|
69
74
|
$var-focus: var(--c-focus);
|
|
75
|
+
$var-scrollbar-thumb: var(--c-scrollbar-thumb);
|
|
76
|
+
$var-scrollbar-track: var(--c-scrollbar-track);
|
|
70
77
|
|
|
71
78
|
// The dropdown arrow of Select, Combobox and Date picker (the same roles as the `$arrow-*` tokens).
|
|
72
79
|
$var-arrow-color: $var-muted;
|
|
@@ -97,3 +104,16 @@ $var-arrow-color-disabled: $var-disabled-text;
|
|
|
97
104
|
@include palette($dark, dark);
|
|
98
105
|
}
|
|
99
106
|
}
|
|
107
|
+
|
|
108
|
+
// Scrollbars, in two rules because the two properties differ. `scrollbar-color` is inherited, so one declaration on `:root` reaches every
|
|
109
|
+
// scroll container. `scrollbar-width` is NOT inherited (only the page viewport would get it), so it is declared on every element with the
|
|
110
|
+
// universal selector. `*` has zero specificity (`:where(*)` would be the same; `*` is plain and just as supported), so it never beats a
|
|
111
|
+
// component rule: a scroller that sets its own width (the carousel hides its bar with `scrollbar-width: none`) keeps it, in any order.
|
|
112
|
+
// Standard properties only: colour and thickness, no rounding.
|
|
113
|
+
:root {
|
|
114
|
+
scrollbar-color: $var-scrollbar-thumb $var-scrollbar-track;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
* {
|
|
118
|
+
scrollbar-width: t.$scrollbar-width;
|
|
119
|
+
}
|
package/scss/_tokens.scss
CHANGED
|
@@ -21,6 +21,10 @@ $error: #dc3545;
|
|
|
21
21
|
$success: #15803d;
|
|
22
22
|
$warning: #a16207;
|
|
23
23
|
$info: #1d4ed8;
|
|
24
|
+
// Scrollbars (every scroll container inherits them from `:root`): a neutral thumb on a track that is the page ground, thin.
|
|
25
|
+
$scrollbar-thumb: #737373; // 4.74:1 on the white track and background (the neutral 500)
|
|
26
|
+
$scrollbar-track: $white; // the light background: the track is the page ground
|
|
27
|
+
$scrollbar-width: thin;
|
|
24
28
|
|
|
25
29
|
// Values shared by every component, so the whole theme moves together.
|
|
26
30
|
$font-family: ('Helvetica Neue', Helvetica, Arial, 'Liberation Sans', sans-serif);
|