kempo-css 1.3.13 → 2.1.1
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/CHANGELOG.md +21 -1
- package/CONTRIBUTING.md +17 -0
- package/README.md +2 -48
- package/dist/kempo.min.css +1 -1
- package/docs/components/ThemePropertyInput.js +2 -2
- package/docs/examples/responsive-grid.html +1 -1
- package/docs/index.html +1401 -25
- package/docs/init.js +1 -1
- package/docs/kempo.css +105 -94
- package/docs/kempo.min.css +1 -1
- package/docs/theme-editor.html +29 -74
- package/llms.txt +205 -0
- package/package.json +1 -1
- package/src/kempo.css +105 -94
- package/tests/colors.browser-test.js +3 -3
- package/tests/components.browser-test.js +0 -13
- package/tests/css_variables.browser-test.js +1 -1
- package/tests/elevation.browser-test.js +239 -0
- package/docs/docs.inc.html +0 -955
package/llms.txt
ADDED
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
# Kempo CSS
|
|
2
|
+
|
|
3
|
+
> A lightweight, modern CSS-only framework providing utility classes and semantic components for rapid web development. No JavaScript required. Supports dark mode, theming via CSS custom properties, and a comprehensive color/elevation system.
|
|
4
|
+
|
|
5
|
+
## Project
|
|
6
|
+
|
|
7
|
+
- [Documentation](https://dustinpoissant.github.io/kempo-css/): Full docs with live examples and an interactive theme editor
|
|
8
|
+
- [GitHub Repository](https://github.com/dustinpoissant/kempo-css): Source code, issues, and releases
|
|
9
|
+
- [npm Package](https://www.npmjs.com/package/kempo-css): `npm install kempo-css`
|
|
10
|
+
- License: MIT
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
```html
|
|
15
|
+
<!-- From npm -->
|
|
16
|
+
<link rel="stylesheet" href="node_modules/kempo-css/kempo.css">
|
|
17
|
+
|
|
18
|
+
<!-- From CDN (jsDelivr) -->
|
|
19
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/kempo-css/kempo.css">
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Or import in CSS/SCSS:
|
|
23
|
+
```css
|
|
24
|
+
@import 'kempo-css/kempo.css';
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Theming
|
|
28
|
+
|
|
29
|
+
All visual properties are controlled by CSS custom properties on `:root`. Override them to theme the framework. Only the base colors need to be defined — hover, text, and inverse variants are auto-calculated using `oklch` relative color syntax.
|
|
30
|
+
|
|
31
|
+
Base color variables (override to theme):
|
|
32
|
+
- `--c_bg` — page background; light-dark aware (default light: `rgb(249,249,249)`, dark: `rgb(51,51,51)`)
|
|
33
|
+
- `--c_overscroll` — overscroll/rubber-band background
|
|
34
|
+
- `--c_border` — border color; light-dark aware
|
|
35
|
+
- `--c_primary` — primary brand color (default `rgb(51,102,255)`)
|
|
36
|
+
- `--c_secondary` — secondary brand color (default `rgb(153,51,255)`)
|
|
37
|
+
- `--c_success` — success state (default `rgb(0,136,0)`)
|
|
38
|
+
- `--c_warning` — warning state (default `rgb(255,102,0)`)
|
|
39
|
+
- `--c_danger` — danger/error state (default `rgb(255,0,51)`)
|
|
40
|
+
- `--btn_bg` — default button background
|
|
41
|
+
- `--tc` — default text color; light-dark aware
|
|
42
|
+
- `--tc_dark` / `--tc_light` — always-dark / always-light text
|
|
43
|
+
- `--tc_muted` — muted/secondary text; light-dark aware
|
|
44
|
+
- `--c_overlay` — overlay backdrop color
|
|
45
|
+
|
|
46
|
+
Layout/typography variables:
|
|
47
|
+
- `--spacer` (default `1rem`) — base spacing unit; `--spacer_h` (0.5rem), `--spacer_q` (0.25rem)
|
|
48
|
+
- `--fs_base` (default `16px`) — base font size; heading sizes h1–h6 are derived from this
|
|
49
|
+
- `--container_width` (default `90rem`) — max-width for `main` and `.container`
|
|
50
|
+
- `--radius` (default `0.25rem`) — border radius
|
|
51
|
+
- `--animation_ms` (default `256ms`) — transition duration
|
|
52
|
+
- `--line-height` (default `1.35em`)
|
|
53
|
+
- `--ff_body`, `--ff_heading`, `--ff_mono` — font families
|
|
54
|
+
|
|
55
|
+
## Dark Mode
|
|
56
|
+
|
|
57
|
+
Dark mode is controlled via the `theme` attribute. Apply `theme="dark"` to force dark, `theme="light"` to force light, or `theme="auto"` to follow the system `prefers-color-scheme`.
|
|
58
|
+
|
|
59
|
+
```html
|
|
60
|
+
<html theme="dark">
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Classes
|
|
64
|
+
|
|
65
|
+
### Display
|
|
66
|
+
|
|
67
|
+
| Class | Effect |
|
|
68
|
+
|-------|--------|
|
|
69
|
+
| `.d-b` | `display: block` |
|
|
70
|
+
| `.d-ib` | `display: inline-block` |
|
|
71
|
+
| `.d-i` | `display: inline` |
|
|
72
|
+
| `.d-f` | `display: flex; flex-wrap: wrap` |
|
|
73
|
+
| `.d-if` | `display: inline-flex; flex-wrap: wrap` |
|
|
74
|
+
| `.d-g` | `display: grid` |
|
|
75
|
+
| `.d-n` | `display: none` |
|
|
76
|
+
|
|
77
|
+
Responsive prefixes: `d-` (desktop ≥1024px), `t-` (tablet 769–1023px), `m-` (mobile ≤768px).
|
|
78
|
+
Examples: `.m-d-n` hides on mobile; `.d-d-f` makes flex on desktop only.
|
|
79
|
+
|
|
80
|
+
### Flex
|
|
81
|
+
|
|
82
|
+
`.flex` / `.flex-1` through `.flex-10` — sets `flex: N N auto`. Same classes with `d-`, `t-`, `m-` prefixes for responsive variants (e.g. `.m-flex-2`).
|
|
83
|
+
|
|
84
|
+
`.flex-0` — `flex: 0 0` (no grow/shrink).
|
|
85
|
+
|
|
86
|
+
### Layout
|
|
87
|
+
|
|
88
|
+
- `main`, `.container` — centered, max-width (`--container_width`), padded wrapper
|
|
89
|
+
- `.fixed` — `position: fixed; top: 0; width: 100%; z-index: 99`; add `.scrolled` to show shadow
|
|
90
|
+
- `.full` — `display: block; width: 100%`
|
|
91
|
+
- `body.no-scroll` — prevents body scroll (use when dialogs or other overlays active)
|
|
92
|
+
|
|
93
|
+
### Rows / Columns (12-column flex grid)
|
|
94
|
+
|
|
95
|
+
- `.row` — `display: flex; flex-wrap: wrap`
|
|
96
|
+
- `.col` — `flex: 1 1` (fills remaining space)
|
|
97
|
+
- `.span-1` through `.span-12` — 12-col span widths
|
|
98
|
+
- Responsive variants: `.d-span-*` (desktop), `.t-span-*` (tablet), `.m-span-*` (mobile)
|
|
99
|
+
|
|
100
|
+
### CSS Grid Columns
|
|
101
|
+
|
|
102
|
+
- `.cols-2` through `.cols-10` — sets `grid-template-columns: repeat(N, 1fr)`
|
|
103
|
+
- Responsive variants: `.d-cols-*`, `.t-cols-*`, `.m-cols-*`
|
|
104
|
+
|
|
105
|
+
### Typography
|
|
106
|
+
|
|
107
|
+
- `.h1`–`.h6` — apply heading font size to any element
|
|
108
|
+
- `.small` — `font-size: var(--fs_small)` (0.6× base)
|
|
109
|
+
- `.large` — `font-size: var(--fs_large)` (1.5× base)
|
|
110
|
+
- `.ff-mono` — monospace font
|
|
111
|
+
- `.ta-left`, `.ta-center`, `.ta-right` — text alignment
|
|
112
|
+
- `.td-n` — `text-decoration: none`
|
|
113
|
+
- `.no-link` / `.no-link:hover` — removes link color and underline
|
|
114
|
+
- `.link` — applies link styling to non-`<a>` elements
|
|
115
|
+
|
|
116
|
+
Block elements (`p`, `h1`–`h6`, `blockquote`, `ul`, `ol`, `dl`, `pre`, `hr`, `dd`) all get `margin-bottom: var(--spacer)` by default.
|
|
117
|
+
|
|
118
|
+
### Spacing
|
|
119
|
+
|
|
120
|
+
Sizes: whole = `--spacer` (1rem), half (`h`) = `--spacer_h` (0.5rem), quarter (`q`) = `--spacer_q` (0.25rem), zero (`0`) = 0.
|
|
121
|
+
|
|
122
|
+
| Side | Padding (whole) | Padding (half) | Padding (quarter) | Padding (zero) | Margin (whole) | Margin (half) | Margin (quarter) | Margin (zero) | Margin (negative) |
|
|
123
|
+
|------|-----------------|----------------|-------------------|----------------|----------------|---------------|------------------|---------------|-------------------|
|
|
124
|
+
| All | `.p` | `.ph` | `.pq` | `.p0` | `.m` | `.mh` | `.mq` | `.m0` | `.-m` |
|
|
125
|
+
| Top | `.pt` | `.pth` | `.ptq` | `.pt0` | `.mt` | `.mth` | `.mtq` | `.mt0` | `.-mt` |
|
|
126
|
+
| Bottom | `.pb` | `.pbh` | `.pbq` | `.pb0` | `.mb` | `.mbh` | `.mbq` | `.mb0` | `.-mb` |
|
|
127
|
+
| Left | `.pl` | `.plh` | `.plq` | `.pl0` | `.ml` | `.mlh` | `.mlq` | `.ml0` | `.-ml` |
|
|
128
|
+
| Right | `.pr` | `.prh` | `.prq` | `.pr0` | `.mr` | `.mrh` | `.mrq` | `.mr0` | `.-mr` |
|
|
129
|
+
| Horizontal | `.px` | `.pxh` | `.pxq` | `.px0` | `.mx` | `.mxh` | `.mxq` | `.mx0` | `.-mx` |
|
|
130
|
+
| Vertical | `.py` | `.pyh` | `.pyq` | `.py0` | `.my` | `.myh` | `.myq` | `.my0` | `.-my` |
|
|
131
|
+
|
|
132
|
+
### Borders
|
|
133
|
+
|
|
134
|
+
- `.b` — all sides; `.bt` / `.bb` / `.bl` / `.br` — individual sides; `.bx` — horizontal; `.by` — vertical
|
|
135
|
+
- `.b0` — remove all; `.bt0` / `.bb0` / `.bl0` / `.br0` / `.bx0` / `.by0` — remove individual
|
|
136
|
+
|
|
137
|
+
### Border Radius
|
|
138
|
+
|
|
139
|
+
- `.r` — all corners; `.rt` / `.rb` / `.rl` / `.rr` — sides; `.rtl` / `.rtr` / `.rbl` / `.rbr` — individual corners
|
|
140
|
+
- `.r0` — remove all; `.rt0` / `.rb0` / `.rl0` / `.rr0` / `.rtl0` / `.rtr0` / `.rbl0` / `.rbr0` — remove individual
|
|
141
|
+
- `.round` — `border-radius: 9999rem` (pill/circle)
|
|
142
|
+
|
|
143
|
+
### Buttons
|
|
144
|
+
|
|
145
|
+
`button`, `.btn`, `input[type="button"]`, `input[type="submit"]`, and `input[type="reset"]` are all styled by default.
|
|
146
|
+
|
|
147
|
+
Semantic color variants — add to a button element:
|
|
148
|
+
- `.primary`, `.secondary`, `.success`, `.warning`, `.danger`
|
|
149
|
+
|
|
150
|
+
Other button modifiers:
|
|
151
|
+
- `.link` — transparent, no border, inherits text color and font size, used to make a button (or other element) look like a link
|
|
152
|
+
- `.no-btn` — strips all kempo styles; renders as plain inline element inheriting color/font, no border/background/padding (retains focus ring via `--focus_shadow`)
|
|
153
|
+
- `.no-style` — opts a `<button>` out of kempo styles entirely, leaving browser default button appearance
|
|
154
|
+
- `.btn-grp` — wraps buttons in an inline-flex group with joined borders
|
|
155
|
+
|
|
156
|
+
### Forms
|
|
157
|
+
|
|
158
|
+
All standard inputs are auto-styled: `input` (except buttons/radio/checkbox), `select`, `textarea`. Custom styling is also applied to `input[type="checkbox"]`, `input[type="radio"]`, `input[type="color"]`, and date/time/search inputs.
|
|
159
|
+
|
|
160
|
+
- `label` — `display: block`
|
|
161
|
+
- `label.checkbox` / `label.radio` — inline-block label for use next to checkbox/radio
|
|
162
|
+
|
|
163
|
+
### Tables
|
|
164
|
+
|
|
165
|
+
- `table` — full-width, no border-spacing, auto-styled `th`/`td` with borders and padding
|
|
166
|
+
- `.table-wrapper` — wraps a table for horizontal scroll overflow
|
|
167
|
+
|
|
168
|
+
### Background Colors
|
|
169
|
+
|
|
170
|
+
- `.bg-default` — `--c_bg` background with `--tc` text
|
|
171
|
+
- `.bg-alt` — `--c_bg__alt` (slightly darker/lighter than bg)
|
|
172
|
+
- `.bg-inv` — inverted background; also re-scopes all `--c_*` vars to their inverse variants
|
|
173
|
+
- `.bg-primary`, `.bg-secondary`, `.bg-success`, `.bg-warning`, `.bg-danger` — semantic color backgrounds with appropriate text color set automatically
|
|
174
|
+
|
|
175
|
+
### Text Colors
|
|
176
|
+
|
|
177
|
+
- `.tc-default` — default text color
|
|
178
|
+
- `.tc-inv` — inverted text color
|
|
179
|
+
- `.tc-muted` — muted text
|
|
180
|
+
- `.tc-primary`, `.tc-secondary`, `.tc-success`, `.tc-warning`, `.tc-danger` — semantic text colors; automatically switch to their inverse when inside `.bg-inv` or `.is-inv`
|
|
181
|
+
|
|
182
|
+
### Elevation
|
|
183
|
+
|
|
184
|
+
Elevation classes only set `z-index`. Combine with `.shadow` and/or `.bg-elevation` for visual depth.
|
|
185
|
+
|
|
186
|
+
- `.elevation-0` through `.elevation-10` — `z-index: 0` through `z-index: 100` (increments of 10); level 2 = page default
|
|
187
|
+
- `.shadow` + `.elevation-*` — adds `box-shadow`; inset shadow at levels 0–1, no shadow at level 2, outset shadow at levels 3–5
|
|
188
|
+
- `.bg-elevation` + `.elevation-*` — sets `background-color` to the elevation-appropriate tint (`--c_bg_elevation_0` through `--c_bg_elevation_10`)
|
|
189
|
+
- Shadows and backgrounds max out at 5, 6-10 look the same as 5 but still increase z-index.
|
|
190
|
+
|
|
191
|
+
CSS variables: `--c_bg_elevation_0`–`--c_bg_elevation_10`, `--shadow_0`–`--shadow_10` (shadow vars `__light`/`__dark` variants also exist).
|
|
192
|
+
|
|
193
|
+
### Components
|
|
194
|
+
|
|
195
|
+
- `.card` — bordered box with `--radius`, top/left/right padding, and `margin-bottom`
|
|
196
|
+
- `.icon` — `display: inline-block; width: 1.35em; vertical-align: top` for inline SVG icons
|
|
197
|
+
|
|
198
|
+
## File Structure
|
|
199
|
+
|
|
200
|
+
- `dist/kempo.min.css` — minified file for production
|
|
201
|
+
- `dist/kempo-hljs.min.css` - minified "highlight.js" styles for production
|
|
202
|
+
- `src/*` - source files for kempo-css developement
|
|
203
|
+
- `test/*` - unit tests for kempo-css developmenet
|
|
204
|
+
- `docs/*` - github pages docs
|
|
205
|
+
|
package/package.json
CHANGED
package/src/kempo.css
CHANGED
|
@@ -29,48 +29,57 @@
|
|
|
29
29
|
--input_border_width: 1px;
|
|
30
30
|
--btn_padding: var(--spacer_h) var(--spacer);
|
|
31
31
|
|
|
32
|
-
/*
|
|
32
|
+
/* Base colors — override these to theme the framework */
|
|
33
33
|
--c_bg: light-dark(rgb(249, 249, 249), rgb(51, 51, 51));
|
|
34
|
-
--c_bg__inv: light-dark(rgb(51, 51, 51), rgb(249, 249, 249));
|
|
35
|
-
--c_bg__alt: light-dark(rgb(238, 238, 238), rgb(34, 34, 34));
|
|
36
34
|
--c_overscroll: light-dark(rgb(255, 255, 255), rgb(0, 0, 0));
|
|
37
35
|
--c_border: light-dark(rgb(204, 204, 204), rgb(119, 119, 119));
|
|
38
|
-
--c_border__inv: light-dark(rgb(119, 119, 119), rgb(204, 204, 204));
|
|
39
36
|
--c_primary: rgb(51, 102, 255);
|
|
40
|
-
--c_primary__hover: rgb(17, 68, 221);
|
|
41
37
|
--c_secondary: rgb(153, 51, 255);
|
|
42
|
-
--c_secondary__hover: rgb(119, 17, 221);
|
|
43
38
|
--c_success: rgb(0, 136, 0);
|
|
44
|
-
--c_success__hover: rgb(0, 102, 0);
|
|
45
39
|
--c_warning: rgb(255, 102, 0);
|
|
46
|
-
--c_warning__hover: rgb(221, 68, 0);
|
|
47
40
|
--c_danger: rgb(255, 0, 51);
|
|
48
|
-
--
|
|
49
|
-
--c_input_accent: rgb(51, 102, 255);
|
|
50
|
-
--c_input_border: var(--c_border);
|
|
51
|
-
--c_highlight: light-dark(rgba(41, 100, 210, 0.25), rgba(0, 89, 255, 0.25));
|
|
41
|
+
--btn_bg: light-dark(rgb(221, 221, 221), rgb(170, 170, 170));
|
|
52
42
|
--tc: light-dark(rgba(0, 0, 0, 0.93), rgba(255, 255, 255, 0.93));
|
|
53
|
-
--tc_dark:
|
|
54
|
-
--tc_light:
|
|
55
|
-
--tc_inv: light-dark(rgba(255, 255, 255, 0.93), rgba(0, 0, 0, 0.93));
|
|
43
|
+
--tc_dark: rgba(0, 0, 0, 0.93);
|
|
44
|
+
--tc_light: rgba(255, 255, 255, 0.93);
|
|
56
45
|
--tc_muted: light-dark(rgba(0, 0, 0, 0.5), rgba(255, 255, 255, 0.5));
|
|
57
|
-
--tc_on_primary: light-dark(rgba(255, 255, 255, 0.93), rgba(255, 255, 255, 0.93));
|
|
58
|
-
--tc_on_secondary: light-dark(rgba(255, 255, 255, 0.93), rgba(255, 255, 255, 0.93));
|
|
59
|
-
--tc_on_success: light-dark(rgba(255, 255, 255, 0.93), rgba(255, 255, 255, 0.93));
|
|
60
|
-
--tc_on_warning: light-dark(rgba(255, 255, 255, 0.93), rgba(255, 255, 255, 0.93));
|
|
61
|
-
--tc_on_danger: light-dark(rgba(255, 255, 255, 0.93), rgba(255, 255, 255, 0.93));
|
|
62
46
|
--c_overlay: rgba(0, 0, 0, 0.5);
|
|
63
|
-
|
|
64
|
-
--
|
|
65
|
-
--
|
|
66
|
-
--
|
|
67
|
-
--
|
|
47
|
+
/* Derived colors — computed from base colors above via relative oklch syntax */
|
|
48
|
+
--c_bg__alt: oklch(from var(--c_bg) calc(l - 0.04) c h);
|
|
49
|
+
--c_bg__inv: light-dark(oklch(from var(--c_bg) calc(l - 0.73) c h), oklch(from var(--c_bg) calc(l + 0.73) c h));
|
|
50
|
+
--c_border__inv: light-dark(oklch(from var(--c_border) calc(l - 0.34) c h), oklch(from var(--c_border) calc(l + 0.34) c h));
|
|
51
|
+
--c_primary__hover: oklch(from var(--c_primary) calc(l - 0.12) c h);
|
|
52
|
+
--c_secondary__hover: oklch(from var(--c_secondary) calc(l - 0.12) c h);
|
|
53
|
+
--c_success__hover: oklch(from var(--c_success) calc(l - 0.12) c h);
|
|
54
|
+
--c_warning__hover: oklch(from var(--c_warning) calc(l - 0.12) c h);
|
|
55
|
+
--c_danger__hover: oklch(from var(--c_danger) calc(l - 0.12) c h);
|
|
56
|
+
--c_input_accent: var(--c_primary);
|
|
57
|
+
--c_input_border: var(--c_border);
|
|
58
|
+
--c_highlight: oklch(from var(--c_primary) l c h / 0.25);
|
|
59
|
+
--tc_inv: light-dark(rgba(255, 255, 255, 0.93), rgba(0, 0, 0, 0.93));
|
|
60
|
+
--tc_on_primary: rgba(255, 255, 255, 0.93);
|
|
61
|
+
--tc_on_secondary: rgba(255, 255, 255, 0.93);
|
|
62
|
+
--tc_on_success: rgba(255, 255, 255, 0.93);
|
|
63
|
+
--tc_on_warning: rgba(255, 255, 255, 0.93);
|
|
64
|
+
--tc_on_danger: rgba(255, 255, 255, 0.93);
|
|
65
|
+
/* Brand text colors: use base in light mode, lighter+desaturated in dark for readability */
|
|
66
|
+
--tc_primary: light-dark(var(--c_primary), oklch(from var(--c_primary) calc(l + 0.18) calc(c * 0.65) h));
|
|
67
|
+
--tc_secondary: light-dark(var(--c_secondary), oklch(from var(--c_secondary) calc(l + 0.18) calc(c * 0.65) h));
|
|
68
|
+
--tc_success: light-dark(var(--c_success), oklch(from var(--c_success) calc(l + 0.18) calc(c * 0.65) h));
|
|
69
|
+
--tc_warning: light-dark(var(--c_warning), oklch(from var(--c_warning) calc(l + 0.18) calc(c * 0.65) h));
|
|
70
|
+
--tc_danger: light-dark(var(--c_danger), oklch(from var(--c_danger) calc(l + 0.18) calc(c * 0.65) h));
|
|
71
|
+
/* Inverse brand text colors: always the light/readable shade (for use on dark/inverted backgrounds) */
|
|
72
|
+
--tc__inv: var(--tc_inv);
|
|
73
|
+
--tc_primary__inv: oklch(from var(--c_primary) calc(l + 0.18) calc(c * 0.65) h);
|
|
74
|
+
--tc_secondary__inv: oklch(from var(--c_secondary) calc(l + 0.18) calc(c * 0.65) h);
|
|
75
|
+
--tc_success__inv: oklch(from var(--c_success) calc(l + 0.18) calc(c * 0.65) h);
|
|
76
|
+
--tc_warning__inv: oklch(from var(--c_warning) calc(l + 0.18) calc(c * 0.65) h);
|
|
77
|
+
--tc_danger__inv: oklch(from var(--c_danger) calc(l + 0.18) calc(c * 0.65) h);
|
|
68
78
|
--btn_box_shadow: 0 0 0 transparent;
|
|
69
79
|
--btn_box_shadow__hover: 0 0 0 transparent;
|
|
70
80
|
--btn_border: transparent;
|
|
71
|
-
--
|
|
72
|
-
--
|
|
73
|
-
--btn_tc: light-dark(rgba(0, 0, 0, 0.93), rgba(0, 0, 0, 0.93));
|
|
81
|
+
--btn_bg__hover: oklch(from var(--btn_bg) calc(l - 0.08) c h);
|
|
82
|
+
--btn_tc: rgba(0, 0, 0, 0.93);
|
|
74
83
|
--btn_transparent__hover: light-dark(rgba(0, 0, 0, 0.05), rgba(255, 255, 255, 0.05));
|
|
75
84
|
--tc_link: var(--tc_primary);
|
|
76
85
|
--tc_link__hover: var(--tc_secondary);
|
|
@@ -80,34 +89,35 @@
|
|
|
80
89
|
--focus_shadow_on_primary: 0 0 2px 2px var(--tc_on_primary);
|
|
81
90
|
--input_bg: light-dark(white, var(--c_bg__alt));
|
|
82
91
|
--input_tc: light-dark(rgba(0, 0, 0, 0.93), var(--tc));
|
|
83
|
-
--drop_shadow__light: 0 0.25rem 0.5rem rgba(0, 0, 0, 0.333);
|
|
84
|
-
--drop_shadow__dark: 0 0.25rem 0.5rem rgba(0, 0, 0, 0.5);
|
|
85
|
-
--drop_shadow: var(--drop_shadow__light);
|
|
86
92
|
--date_picker_icon_filter: light-dark(invert(0), invert(1));
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
--
|
|
90
|
-
--
|
|
91
|
-
--
|
|
92
|
-
--
|
|
93
|
-
--
|
|
94
|
-
--
|
|
95
|
-
--
|
|
96
|
-
--
|
|
97
|
-
--
|
|
98
|
-
--
|
|
99
|
-
|
|
100
|
-
--
|
|
101
|
-
--
|
|
102
|
-
--
|
|
103
|
-
--
|
|
104
|
-
|
|
105
|
-
--
|
|
106
|
-
--
|
|
107
|
-
--
|
|
108
|
-
--
|
|
109
|
-
--
|
|
110
|
-
--
|
|
93
|
+
/* Elevation System - Level 2 = page level (z-index 20); 0-1 = sunk; 3-10 = raised */
|
|
94
|
+
--c_bg_elevation_0: oklch(from var(--c_bg) calc(l - 0.13) c h);
|
|
95
|
+
--c_bg_elevation_1: light-dark(oklch(from var(--c_bg) calc(l - 0.065) c h), oklch(from var(--c_bg) calc(l - 0.10) c h));
|
|
96
|
+
--c_bg_elevation_2: var(--c_bg);
|
|
97
|
+
--c_bg_elevation_3: light-dark(oklch(from var(--c_bg) calc(l + 0.01) c h), oklch(from var(--c_bg) calc(l + 0.03) c h));
|
|
98
|
+
--c_bg_elevation_4: light-dark(oklch(from var(--c_bg) calc(l + 0.02) c h), oklch(from var(--c_bg) calc(l + 0.06) c h));
|
|
99
|
+
--c_bg_elevation_5: light-dark(oklch(from var(--c_bg) calc(l + 0.03) c h), oklch(from var(--c_bg) calc(l + 0.09) c h));
|
|
100
|
+
--c_bg_elevation_6: light-dark(oklch(from var(--c_bg) calc(l + 0.04) c h), oklch(from var(--c_bg) calc(l + 0.13) c h));
|
|
101
|
+
--c_bg_elevation_7: light-dark(oklch(from var(--c_bg) calc(l + 0.05) c h), oklch(from var(--c_bg) calc(l + 0.17) c h));
|
|
102
|
+
--c_bg_elevation_8: light-dark(oklch(from var(--c_bg) calc(l + 0.06) c h), oklch(from var(--c_bg) calc(l + 0.21) c h));
|
|
103
|
+
--c_bg_elevation_9: light-dark(oklch(from var(--c_bg) calc(l + 0.07) c h), oklch(from var(--c_bg) calc(l + 0.25) c h));
|
|
104
|
+
--c_bg_elevation_10: light-dark(oklch(from var(--c_bg) calc(l + 0.08) c h), oklch(from var(--c_bg) calc(l + 0.31) c h));
|
|
105
|
+
/* Shadow config — override these to customize elevation shadows */
|
|
106
|
+
--shadow_color: black;
|
|
107
|
+
--shadow_size: 1px;
|
|
108
|
+
--shadow_base_opacity: 0.12;
|
|
109
|
+
--shadow_opacity_step: 0.04;
|
|
110
|
+
/* Computed shadows — derived from shadow config vars above */
|
|
111
|
+
--shadow_0: inset 0 calc(var(--shadow_size) * 2) calc(var(--shadow_size) * 6) oklch(from var(--shadow_color) l c h / calc(var(--shadow_base_opacity) * 2)), inset 0 calc(var(--shadow_size)) calc(var(--shadow_size) * 3) oklch(from var(--shadow_color) l c h / calc(var(--shadow_base_opacity) * 1.5));
|
|
112
|
+
--shadow_1: inset 0 calc(var(--shadow_size)) calc(var(--shadow_size) * 3) oklch(from var(--shadow_color) l c h / calc(var(--shadow_base_opacity) * 1.25)), inset 0 calc(var(--shadow_size)) calc(var(--shadow_size) * 2) oklch(from var(--shadow_color) l c h / calc(var(--shadow_base_opacity) * 0.75));
|
|
113
|
+
--shadow_3: 0 calc(var(--shadow_size)) calc(var(--shadow_size) * 2) oklch(from var(--shadow_color) l c h / var(--shadow_base_opacity));
|
|
114
|
+
--shadow_4: 0 calc(var(--shadow_size) * 2) calc(var(--shadow_size) * 4) oklch(from var(--shadow_color) l c h / calc(var(--shadow_base_opacity) + var(--shadow_opacity_step)));
|
|
115
|
+
--shadow_5: 0 calc(var(--shadow_size) * 3) calc(var(--shadow_size) * 6) oklch(from var(--shadow_color) l c h / calc(var(--shadow_base_opacity) + var(--shadow_opacity_step) * 2));
|
|
116
|
+
--shadow_6: var(--shadow_5);
|
|
117
|
+
--shadow_7: var(--shadow_5);
|
|
118
|
+
--shadow_8: var(--shadow_5);
|
|
119
|
+
--shadow_9: var(--shadow_5);
|
|
120
|
+
--shadow_10: var(--shadow_5);
|
|
111
121
|
}
|
|
112
122
|
[theme="light"] {
|
|
113
123
|
color-scheme: light;
|
|
@@ -115,12 +125,8 @@
|
|
|
115
125
|
|
|
116
126
|
[theme="dark"] {
|
|
117
127
|
color-scheme: dark;
|
|
118
|
-
--
|
|
119
|
-
--
|
|
120
|
-
--elevation_-1_shadow: var(--elevation_-1_shadow__dark);
|
|
121
|
-
--elevation_1_shadow: var(--elevation_1_shadow__dark);
|
|
122
|
-
--elevation_2_shadow: var(--elevation_2_shadow__dark);
|
|
123
|
-
--elevation_3_shadow: var(--elevation_3_shadow__dark);
|
|
128
|
+
--shadow_base_opacity: 0.30;
|
|
129
|
+
--shadow_opacity_step: 0.025;
|
|
124
130
|
}
|
|
125
131
|
|
|
126
132
|
[theme="auto"] {
|
|
@@ -128,12 +134,8 @@
|
|
|
128
134
|
}
|
|
129
135
|
@media (prefers-color-scheme: dark) {
|
|
130
136
|
[theme="auto"] {
|
|
131
|
-
--
|
|
132
|
-
--
|
|
133
|
-
--elevation_-1_shadow: var(--elevation_-1_shadow__dark);
|
|
134
|
-
--elevation_1_shadow: var(--elevation_1_shadow__dark);
|
|
135
|
-
--elevation_2_shadow: var(--elevation_2_shadow__dark);
|
|
136
|
-
--elevation_3_shadow: var(--elevation_3_shadow__dark);
|
|
137
|
+
--shadow_base_opacity: 0.30;
|
|
138
|
+
--shadow_opacity_step: 0.025;
|
|
137
139
|
}
|
|
138
140
|
}
|
|
139
141
|
|
|
@@ -1138,33 +1140,42 @@ tr:last-child td:last-child {
|
|
|
1138
1140
|
padding-right: var(--spacer);
|
|
1139
1141
|
margin-bottom: var(--spacer);
|
|
1140
1142
|
}
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
}
|
|
1144
|
-
.elevation
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
}
|
|
1148
|
-
.elevation
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
}
|
|
1152
|
-
.elevation-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
}
|
|
1156
|
-
.elevation-1 {
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
}
|
|
1160
|
-
.elevation-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
}
|
|
1164
|
-
.elevation-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
}
|
|
1143
|
+
/* elevation - z-index only, increments of 10; level 2 = page default */
|
|
1144
|
+
.elevation-0 { z-index: 0; }
|
|
1145
|
+
.elevation-1 { z-index: 10; }
|
|
1146
|
+
.elevation-2 { z-index: 20; }
|
|
1147
|
+
.elevation-3 { z-index: 30; }
|
|
1148
|
+
.elevation-4 { z-index: 40; }
|
|
1149
|
+
.elevation-5 { z-index: 50; }
|
|
1150
|
+
.elevation-6 { z-index: 60; }
|
|
1151
|
+
.elevation-7 { z-index: 70; }
|
|
1152
|
+
.elevation-8 { z-index: 80; }
|
|
1153
|
+
.elevation-9 { z-index: 90; }
|
|
1154
|
+
.elevation-10 { z-index: 100; }
|
|
1155
|
+
/* shadow - box-shadow tied to elevation; use with elevation-* class */
|
|
1156
|
+
.shadow { box-shadow: none; }
|
|
1157
|
+
.shadow.elevation-0 { box-shadow: var(--shadow_0); }
|
|
1158
|
+
.shadow.elevation-1 { box-shadow: var(--shadow_1); }
|
|
1159
|
+
.shadow.elevation-3 { box-shadow: var(--shadow_3); }
|
|
1160
|
+
.shadow.elevation-4 { box-shadow: var(--shadow_4); }
|
|
1161
|
+
.shadow.elevation-5 { box-shadow: var(--shadow_5); }
|
|
1162
|
+
.shadow.elevation-6 { box-shadow: var(--shadow_6); }
|
|
1163
|
+
.shadow.elevation-7 { box-shadow: var(--shadow_7); }
|
|
1164
|
+
.shadow.elevation-8 { box-shadow: var(--shadow_8); }
|
|
1165
|
+
.shadow.elevation-9 { box-shadow: var(--shadow_9); }
|
|
1166
|
+
.shadow.elevation-10 { box-shadow: var(--shadow_10); }
|
|
1167
|
+
/* bg-elevation - background color tied to elevation; use with elevation-* class */
|
|
1168
|
+
.bg-elevation.elevation-0 { background-color: var(--c_bg_elevation_0); }
|
|
1169
|
+
.bg-elevation.elevation-1 { background-color: var(--c_bg_elevation_1); }
|
|
1170
|
+
.bg-elevation.elevation-2 { background-color: var(--c_bg_elevation_2); }
|
|
1171
|
+
.bg-elevation.elevation-3 { background-color: var(--c_bg_elevation_3); }
|
|
1172
|
+
.bg-elevation.elevation-4 { background-color: var(--c_bg_elevation_4); }
|
|
1173
|
+
.bg-elevation.elevation-5 { background-color: var(--c_bg_elevation_5); }
|
|
1174
|
+
.bg-elevation.elevation-6 { background-color: var(--c_bg_elevation_6); }
|
|
1175
|
+
.bg-elevation.elevation-7 { background-color: var(--c_bg_elevation_7); }
|
|
1176
|
+
.bg-elevation.elevation-8 { background-color: var(--c_bg_elevation_8); }
|
|
1177
|
+
.bg-elevation.elevation-9 { background-color: var(--c_bg_elevation_9); }
|
|
1178
|
+
.bg-elevation.elevation-10 { background-color: var(--c_bg_elevation_10); }
|
|
1168
1179
|
.icon {
|
|
1169
1180
|
display: inline-block;
|
|
1170
1181
|
width: 1.35em;
|
|
@@ -219,9 +219,9 @@ export default {
|
|
|
219
219
|
}
|
|
220
220
|
},
|
|
221
221
|
|
|
222
|
-
'should prioritize .bg-primary over .elevation
|
|
222
|
+
'should prioritize .bg-primary over .bg-elevation background': ({pass, fail}) => {
|
|
223
223
|
const combined = document.createElement('div');
|
|
224
|
-
combined.className = 'elevation-3 bg-primary';
|
|
224
|
+
combined.className = 'elevation-3 bg-elevation bg-primary';
|
|
225
225
|
document.body.appendChild(combined);
|
|
226
226
|
|
|
227
227
|
const bgOnly = document.createElement('div');
|
|
@@ -229,7 +229,7 @@ export default {
|
|
|
229
229
|
document.body.appendChild(bgOnly);
|
|
230
230
|
|
|
231
231
|
const elevationOnly = document.createElement('div');
|
|
232
|
-
elevationOnly.className = 'elevation-3';
|
|
232
|
+
elevationOnly.className = 'elevation-3 bg-elevation';
|
|
233
233
|
document.body.appendChild(elevationOnly);
|
|
234
234
|
|
|
235
235
|
const combinedBg = getStyle(combined, 'backgroundColor');
|
|
@@ -63,19 +63,6 @@ export default {
|
|
|
63
63
|
}
|
|
64
64
|
},
|
|
65
65
|
|
|
66
|
-
'should have .drop-shadow class that sets box-shadow': ({pass, fail}) => {
|
|
67
|
-
const el = document.createElement('div');
|
|
68
|
-
el.className = 'drop-shadow';
|
|
69
|
-
document.body.appendChild(el);
|
|
70
|
-
const shadow = getStyle(el, 'boxShadow');
|
|
71
|
-
el.remove();
|
|
72
|
-
if(shadow && shadow !== 'none'){
|
|
73
|
-
pass(`.drop-shadow has box-shadow: ${shadow}`);
|
|
74
|
-
} else {
|
|
75
|
-
fail(`Expected box-shadow, got ${shadow}`);
|
|
76
|
-
}
|
|
77
|
-
},
|
|
78
|
-
|
|
79
66
|
'should style .icon as inline-block': ({pass, fail}) => {
|
|
80
67
|
const el = document.createElement('span');
|
|
81
68
|
el.className = 'icon';
|
|
@@ -150,7 +150,7 @@ export default {
|
|
|
150
150
|
},
|
|
151
151
|
|
|
152
152
|
'should have focus and shadow variables': ({pass, fail}) => {
|
|
153
|
-
const vars = ['--focus_shadow', '--focus_shadow_on_primary', '--
|
|
153
|
+
const vars = ['--focus_shadow', '--focus_shadow_on_primary', '--c_overlay'];
|
|
154
154
|
const missing = vars.filter(v => !getVar(v));
|
|
155
155
|
if(missing.length === 0){
|
|
156
156
|
pass('All focus and shadow variables exist');
|