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/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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kempo-css",
3
- "version": "1.3.13",
3
+ "version": "2.1.1",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "main": "scripts/build.js",
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
- /* Colors using light-dark() function */
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
- --c_danger__hover: rgb(221, 0, 17);
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: light-dark(rgba(0, 0, 0, 0.93), rgba(0, 0, 0, 0.93));
54
- --tc_light: light-dark(rgba(255, 255, 255, 0.93), rgba(255, 255, 255, 0.93));
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
- --tc_primary: light-dark(#36f, rgb(138, 180, 248));
64
- --tc_secondary: light-dark(#93f, rgb(187, 102, 255));
65
- --tc_success: light-dark(#080, rgb(102, 187, 102));
66
- --tc_warning: light-dark(#f60, rgb(255, 153, 51));
67
- --tc_danger: light-dark(#f03, rgb(255, 85, 119));
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
- --btn_bg: light-dark(rgb(221, 221, 221), rgb(170, 170, 170));
72
- --btn_bg__hover: light-dark(rgb(204, 204, 204), rgb(187, 187, 187));
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
- /* Elevation System - Level 0 = body bg, positive = lighter + drop shadow, negative = darker + inset shadow */
89
- --elevation_-2_bg: light-dark(rgb(215, 215, 215), rgb(25, 25, 25));
90
- --elevation_-1_bg: light-dark(rgb(232, 232, 232), rgb(38, 38, 38));
91
- --elevation_0_bg: var(--c_bg);
92
- --elevation_1_bg: light-dark(rgb(255, 255, 255), rgb(64, 64, 64));
93
- --elevation_2_bg: light-dark(rgb(255, 255, 255), rgb(77, 77, 77));
94
- --elevation_3_bg: light-dark(rgb(255, 255, 255), rgb(90, 90, 90));
95
- --elevation_-2_shadow__light: inset 0 2px 6px rgba(0, 0, 0, 0.18), inset 0 1px 3px rgba(0, 0, 0, 0.12);
96
- --elevation_-1_shadow__light: inset 0 1px 3px rgba(0, 0, 0, 0.1), inset 0 1px 2px rgba(0, 0, 0, 0.06);
97
- --elevation_0_shadow: none;
98
- --elevation_1_shadow__light: 0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.16);
99
- --elevation_2_shadow__light: 0 3px 6px rgba(0, 0, 0, 0.12), 0 2px 4px rgba(0, 0, 0, 0.1);
100
- --elevation_3_shadow__light: 0 8px 16px rgba(0, 0, 0, 0.14), 0 3px 6px rgba(0, 0, 0, 0.1);
101
- --elevation_-2_shadow__dark: inset 0 2px 8px rgba(0, 0, 0, 0.5), inset 0 1px 4px rgba(0, 0, 0, 0.4);
102
- --elevation_-1_shadow__dark: inset 0 1px 4px rgba(0, 0, 0, 0.35), inset 0 1px 2px rgba(0, 0, 0, 0.25);
103
- --elevation_1_shadow__dark: 0 2px 6px rgba(0, 0, 0, 0.5), 0 1px 3px rgba(0, 0, 0, 0.4);
104
- --elevation_2_shadow__dark: 0 4px 12px rgba(0, 0, 0, 0.55), 0 2px 4px rgba(0, 0, 0, 0.45);
105
- --elevation_3_shadow__dark: 0 8px 20px rgba(0, 0, 0, 0.6), 0 4px 8px rgba(0, 0, 0, 0.5);
106
- --elevation_-2_shadow: var(--elevation_-2_shadow__light);
107
- --elevation_-1_shadow: var(--elevation_-1_shadow__light);
108
- --elevation_1_shadow: var(--elevation_1_shadow__light);
109
- --elevation_2_shadow: var(--elevation_2_shadow__light);
110
- --elevation_3_shadow: var(--elevation_3_shadow__light);
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
- --drop_shadow: var(--drop_shadow__dark);
119
- --elevation_-2_shadow: var(--elevation_-2_shadow__dark);
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
- --drop_shadow: var(--drop_shadow__dark);
132
- --elevation_-2_shadow: var(--elevation_-2_shadow__dark);
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
- .drop-shadow {
1142
- box-shadow: var(--drop_shadow);
1143
- }
1144
- .elevation--2 {
1145
- background-color: var(--elevation_-2_bg);
1146
- box-shadow: var(--elevation_-2_shadow);
1147
- }
1148
- .elevation--1 {
1149
- background-color: var(--elevation_-1_bg);
1150
- box-shadow: var(--elevation_-1_shadow);
1151
- }
1152
- .elevation-0 {
1153
- background-color: var(--elevation_0_bg);
1154
- box-shadow: var(--elevation_0_shadow);
1155
- }
1156
- .elevation-1 {
1157
- background-color: var(--elevation_1_bg);
1158
- box-shadow: var(--elevation_1_shadow);
1159
- }
1160
- .elevation-2 {
1161
- background-color: var(--elevation_2_bg);
1162
- box-shadow: var(--elevation_2_shadow);
1163
- }
1164
- .elevation-3 {
1165
- background-color: var(--elevation_3_bg);
1166
- box-shadow: var(--elevation_3_shadow);
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-3 background': ({pass, fail}) => {
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', '--drop_shadow', '--drop_shadow__light', '--drop_shadow__dark', '--c_overlay'];
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');