Themer 2nd slice: Look & Feel (#920)

* Exclude Create link from sidebar, for reals this time

* Fix bug

* Very rough prototype of look & feel

* a11y

* Clean up data files

* Automatically generate theme metadata

* Read look & feel params straight from theme

* First stab at dimensionality icons

* Fix rounding 0 bug

* Add border width slider

* [Image-comparer] Expose wrapper as part

* [Comparer] `pointer-events: none` while dragging

* Dark mode slider

* Adjust increments and ranges for look + feel sliders

* Fix preview

* Fix bug where dark mode was not inverted

* Ability to select panel from URL

* Create mixin for Vue form controls and use it in `<swatch-select>`

* Prototype of slider min/max icon buttons

* Nx tooltip

* Icons

* Prevent failed request

* info-tip: Support passing text as prop

* Clearable

* [Brutalist] Match `--wa-shadow-offset-x-scale` to `--wa-shadow-offset-y-scale`

* Add 'Blocky' dimension (derived from Awesome theme)

* Only show Reset button when `clearable` is set

* Remove `clearable` from Look & Feel sliders

* Add tooltips to min/max buttons

* Remove superfluous `aria-label`

* Do not assume that all hyphens in URLs mean nesting, make it explicit

* Formatting

* Fix bug where styles were not applied on page load

* Update Subtle dimension to maximize compatibility

* `<wa-scoped>`: Do not allow non-template children

* Workaround for card not updating

* Update Glossy dimension to maximize compatibility

* Sync scrolling between regular and inverted preview

* Fix bug

* Make changing the base theme reset customizations

* Fix palette page

* Remove cancel button from editable text

* Don't error in theme pages

* Update Playful dimension to maximize compatibility

* Rename 'Look and Feel' to 'Elements' for better parallel structure

* Hide dimensionality controls

* Make back icon motion more subtle

* Expand spacing slider bounds

* Add `tabindex="-1"` where missing in theme showcase

* Remove extraneous gap from theme headers

* fix edit button bug

* rename comparer => comparison; fix aria-controls

* Always save theme name on blur

* Add changelog for themer and new patterns category

---------

Co-authored-by: lindsaym-fa <dev@lindsaym.design>
Co-authored-by: Cory LaViska <cory@abeautifulsite.net>
This commit is contained in:
Lea Verou
2025-05-20 10:16:49 -04:00
committed by GitHub
parent 8b17b3d3e0
commit 0b4c1a5934
58 changed files with 1027 additions and 450 deletions

View File

@@ -11,15 +11,6 @@
overflow: hidden;
}
/* Make content inert when dragging.
Otherwise, for <iframe> and <object> dragging is very choppy. */
:host(:active) {
.before,
.after {
pointer-events: none;
}
}
.before,
.after {
display: block;
@@ -44,6 +35,14 @@
width: 100%;
}
/* Disable pointer-events while dragging. This is especially important for iframes. */
:host(:state(dragging)) {
.before,
.after {
pointer-events: none;
}
}
.divider {
display: flex;
align-items: center;

View File

@@ -3,17 +3,17 @@ import { sendKeys } from '@web/test-runner-commands';
import { html } from 'lit';
import sinon from 'sinon';
import { fixtures } from '../../internal/test/fixture.js';
import type WaComparer from './comparer.js';
import type WaComparison from './comparison.js';
describe('<wa-comparer>', () => {
describe('<wa-comparison>', () => {
for (const fixture of fixtures) {
describe(`with "${fixture.type}" rendering`, () => {
it('should render a basic before/after', async () => {
const el = await fixture<WaComparer>(html`
<wa-comparer>
const el = await fixture<WaComparison>(html`
<wa-comparison>
<div slot="before"></div>
<div slot="after"></div>
</wa-comparer>
</wa-comparison>
`);
const afterPart = el.shadowRoot!.querySelector<HTMLElement>('[part~="after"]')!;
@@ -30,11 +30,11 @@ describe('<wa-comparer>', () => {
});
it('should emit change event when position changed manually', async () => {
const el = await fixture<WaComparer>(html`
<wa-comparer>
const el = await fixture<WaComparison>(html`
<wa-comparison>
<div slot="before"></div>
<div slot="after"></div>
</wa-comparer>
</wa-comparison>
`);
const handler = sinon.spy();
@@ -47,11 +47,11 @@ describe('<wa-comparer>', () => {
});
it('should increment position on arrow right', async () => {
const el = await fixture<WaComparer>(html`
<wa-comparer>
const el = await fixture<WaComparison>(html`
<wa-comparison>
<div slot="before"></div>
<div slot="after"></div>
</wa-comparer>
</wa-comparison>
`);
const handle = el.shadowRoot!.querySelector<HTMLElement>('[part~="handle"]')!;
@@ -63,11 +63,11 @@ describe('<wa-comparer>', () => {
});
it('should decrement position on arrow left', async () => {
const el = await fixture<WaComparer>(html`
<wa-comparer>
const el = await fixture<WaComparison>(html`
<wa-comparison>
<div slot="before"></div>
<div slot="after"></div>
</wa-comparer>
</wa-comparison>
`);
const handle = el.shadowRoot!.querySelector<HTMLElement>('[part~="handle"]')!;
@@ -80,11 +80,11 @@ describe('<wa-comparer>', () => {
});
it('should set position to 0 on home key', async () => {
const el = await fixture<WaComparer>(html`
<wa-comparer>
const el = await fixture<WaComparison>(html`
<wa-comparison>
<div slot="before"></div>
<div slot="after"></div>
</wa-comparer>
</wa-comparison>
`);
const handle = el.shadowRoot!.querySelector<HTMLElement>('[part~="handle"]')!;
@@ -97,11 +97,11 @@ describe('<wa-comparer>', () => {
});
it('should set position to 100 on end key', async () => {
const el = await fixture<WaComparer>(html`
<wa-comparer>
const el = await fixture<WaComparison>(html`
<wa-comparison>
<div slot="before"></div>
<div slot="after"></div>
</wa-comparer>
</wa-comparison>
`);
const handle = el.shadowRoot!.querySelector<HTMLElement>('[part~="handle"]')!;
@@ -114,11 +114,11 @@ describe('<wa-comparer>', () => {
});
it('should clamp to 100 on arrow right', async () => {
const el = await fixture<WaComparer>(html`
<wa-comparer>
const el = await fixture<WaComparison>(html`
<wa-comparison>
<div slot="before"></div>
<div slot="after"></div>
</wa-comparer>
</wa-comparison>
`);
el.position = 0;
@@ -134,11 +134,11 @@ describe('<wa-comparer>', () => {
});
it('should clamp to 0 on arrow left', async () => {
const el = await fixture<WaComparer>(html`
<wa-comparer>
const el = await fixture<WaComparison>(html`
<wa-comparison>
<div slot="before"></div>
<div slot="after"></div>
</wa-comparer>
</wa-comparison>
`);
el.position = 100;
@@ -154,11 +154,11 @@ describe('<wa-comparer>', () => {
});
it('should increment position by 10 on arrow right + shift', async () => {
const el = await fixture<WaComparer>(html`
<wa-comparer>
const el = await fixture<WaComparison>(html`
<wa-comparison>
<div slot="before"></div>
<div slot="after"></div>
</wa-comparer>
</wa-comparison>
`);
const handle = el.shadowRoot!.querySelector<HTMLElement>('[part~="handle"]')!;
@@ -171,11 +171,11 @@ describe('<wa-comparer>', () => {
});
it('should decrement position by 10 on arrow left + shift', async () => {
const el = await fixture<WaComparer>(html`
<wa-comparer>
const el = await fixture<WaComparison>(html`
<wa-comparison>
<div slot="before"></div>
<div slot="after"></div>
</wa-comparer>
</wa-comparison>
`);
const handle = el.shadowRoot!.querySelector<HTMLElement>('[part~="handle"]')!;
@@ -188,22 +188,22 @@ describe('<wa-comparer>', () => {
});
it('should set position by attribute', async () => {
const el = await fixture<WaComparer>(html`
<wa-comparer position="10">
const el = await fixture<WaComparison>(html`
<wa-comparison position="10">
<div slot="before"></div>
<div slot="after"></div>
</wa-comparer>
</wa-comparison>
`);
expect(el.position).to.equal(10);
});
it('should move position on drag', async () => {
const el = await fixture<WaComparer>(html`
<wa-comparer>
const el = await fixture<WaComparison>(html`
<wa-comparison>
<div slot="before" style="width: 50px"></div>
<div slot="after" style="width: 50px"></div>
</wa-comparer>
</wa-comparison>
`);
const handle = el.shadowRoot!.querySelector<HTMLElement>('[part~="handle"]')!;
const rect = handle.getBoundingClientRect();

View File

@@ -7,11 +7,11 @@ import { watch } from '../../internal/watch.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import { LocalizeController } from '../../utilities/localize.js';
import '../icon/icon.js';
import styles from './comparer.css';
import styles from './comparison.css';
/**
* @summary Compare visual differences between similar content with a sliding panel.
* @documentation https://backers.webawesome.com/docs/components/comparer
* @documentation https://backers.webawesome.com/docs/components/comparison
* @status stable
* @since 2.0
*
@@ -33,9 +33,11 @@ import styles from './comparer.css';
* @cssproperty --divider-width - The width of the dividing line.
* @cssproperty --handle-color - The color of the icon used inside the handle.
* @cssproperty --handle-size - The size of the compare handle.
*
* @cssstate dragging - Applied when the comparison is being dragged.
*/
@customElement('wa-comparer')
export default class WaComparer extends WebAwesomeElement {
@customElement('wa-comparison')
export default class WaComparison extends WebAwesomeElement {
static shadowStyle = styles;
private readonly localize = new LocalizeController(this);
@@ -53,9 +55,13 @@ export default class WaComparer extends WebAwesomeElement {
drag(this, {
onMove: x => {
this.toggleCustomState('dragging', true);
this.position = parseFloat(clamp((x / width) * 100, 0, 100).toFixed(2));
if (isRtl) this.position = 100 - this.position;
},
onStop: () => {
this.toggleCustomState('dragging', false);
},
initialEvent: event,
});
}
@@ -97,7 +103,7 @@ export default class WaComparer extends WebAwesomeElement {
const isRtl = this.hasUpdated ? this.localize.dir() === 'rtl' : this.dir === 'rtl';
return html`
<div class="image" part="base">
<div id="comparison" class="image" part="base">
<div part="before" class="before">
<slot name="before"></slot>
</div>
@@ -130,7 +136,7 @@ export default class WaComparer extends WebAwesomeElement {
aria-valuenow=${this.position}
aria-valuemin="0"
aria-valuemax="100"
aria-controls="comparer"
aria-controls="comparison"
tabindex="0"
>
<slot name="handle">
@@ -144,6 +150,6 @@ export default class WaComparer extends WebAwesomeElement {
declare global {
interface HTMLElementTagNameMap {
'wa-comparer': WaComparer;
'wa-comparison': WaComparison;
}
}

View File

@@ -1,21 +1,31 @@
:where(:root),
:host,
.wa-theme-active {
--wa-theme-active-shadow-pop-out: inset 0 0.0625rem 0 0 rgb(255 255 255 / 0.2) /* shine */,
--wa-theme-active-shadow-pop-out: inset 0 0.0625rem 0 0.0625rem rgb(255 255 255 / 0.15) /* shine */,
inset 0 0.0625rem 0.125rem 0 rgb(255 255 255 / 0.2) /* inner highlight */,
inset 0 -0.0625rem 0.0625rem 0 rgb(0 0 0 / 0.2) /* inner shadow */, var(--wa-shadow-s) /* outer shadow */;
inset 0 -0.125rem 0.0625rem 0 rgb(0 0 0 / 0.2) /* inner shadow */;
--wa-theme-active-shadow-punch-in: inset 0 0 0 0 transparent /* shine */,
inset 0 0.125rem 0.125rem 0 rgb(0 0 0 / 0.1) /* inner highlight */,
inset 0 -0.0625rem 0.25rem 0 rgb(0 0 0 / 0.1) /* inner shadow */, 0 0 0 0 transparent /* outer shadow */;
inset 0 0.125rem 0.125rem 0 rgb(0 0 0 / 0.15) /* inner highlight */,
inset 0 -0.0625rem 0.25rem 0 rgb(0 0 0 / 0.15) /* inner shadow */;
:is(button, input:where([type='button'], [type='reset'], [type='submit']), wa-button, .wa-button):not(
[appearance='plain'],
[appearance~='plain'],
.wa-plain
) {
box-shadow: var(--wa-theme-active-shadow-pop-out);
box-shadow:
var(--wa-theme-active-shadow-pop-out),
inset 0 0 0 var(--border-width) var(--border-color, var(--background-color, transparent));
&:not([disabled], [loading]):active {
box-shadow: var(--wa-theme-active-shadow-punch-in);
box-shadow:
var(--wa-theme-active-shadow-punch-in),
inset 0 0 0 var(--border-width) var(--border-color-active, var(--background-color-active, transparent));
}
&::part(base),
:is(&) {
padding-inline: calc(var(--wa-space) + var(--border-width));
border-width: 0px;
}
}

View File

@@ -6,6 +6,7 @@
@import url('default/shadows.css');
@import url('default/transitions.css');
@import url('default/groups.css');
@import url('awesome/dimension.css');
@import url('awesome/overrides.css');
:where(:root),

View File

@@ -0,0 +1,89 @@
:where(:root),
:host,
.wa-theme-awesome {
:is(
button,
input:where([type='button'], [type='reset'], [type='submit']),
wa-button,
wa-radio-group > wa-radio-button,
.wa-button
):not([appearance='plain'], .wa-plain) {
--wa-transition-slow: 0;
--wa-transition-normal: 0;
--wa-transition-fast: 0;
--border-color-hover: var(--border-color);
--border-color-active: var(--border-color);
box-shadow: var(--wa-shadow-offset-x-s) max(var(--wa-shadow-offset-y-s), var(--border-width)) 0 0
var(--border-color);
--background-color-active: var(--border-color);
margin-bottom: var(--wa-shadow-offset-y-s);
margin-right: var(--wa-shadow-offset-x-s);
&:is([appearance='outlined'], .wa-outlined) {
--background-color: var(--wa-color-surface-default);
}
&:not([disabled], [loading]):active,
&::part(checked) {
box-shadow: none;
transform: translate(var(--wa-shadow-offset-x-s), max(var(--wa-shadow-offset-y-s), var(--border-width)));
}
:where(&),
.wa-light &,
.wa-dark .wa-invert & {
&:not([appearance~='outlined'], .wa-outlined) {
--border-color: oklab(from var(--background-color) calc(l - 0.07) a b);
}
--text-color-active: var(--wa-color-on-loud);
}
.wa-dark &,
.wa-invert & {
--text-color-active: var(--wa-color-on-quiet);
}
}
wa-radio-group > wa-radio-button {
&::part(base) {
--background-color-active: var(--border-color-active);
--border-color-active: var(--wa-color-neutral-border-loud);
--text-color-active: var(--wa-color-surface-default);
}
&::part(checked) {
--background-color: var(--border-color);
--background-color-hover: var(--border-color);
--border-color: var(--wa-color-neutral-border-loud);
--text-color: var(--wa-color-surface-default);
--text-color-hover: var(--text-color);
}
}
:is(
input:where(
:not(
[type='button'],
[type='checkbox'],
[type='color'],
[type='file'],
[type='hidden'],
[type='image'],
[type='radio'],
[type='range'],
[type='reset'],
[type='submit']
)
),
select,
textarea,
wa-input,
wa-select,
wa-textarea,
.wa-text-field
):not(:focus, [appearance='filled'], .wa-filled) {
--box-shadow: inset var(--wa-shadow-offset-x-s) max(var(--wa-shadow-offset-y-s), var(--border-width)) 0 0
var(--wa-color-shadow);
}
}

View File

@@ -8,28 +8,6 @@
wa-radio-group > wa-radio-button,
.wa-button
):not([appearance='plain'], .wa-plain) {
--wa-transition-slow: 0;
--wa-transition-normal: 0;
--wa-transition-fast: 0;
--border-color-hover: var(--border-color);
--border-color-active: var(--border-color);
box-shadow: var(--wa-shadow-offset-x-s) var(--wa-shadow-offset-y-s) var(--wa-shadow-blur-s)
var(--wa-shadow-spread-s) var(--border-color);
--background-color-active: var(--border-color);
margin-bottom: var(--wa-shadow-offset-y-s);
&:is([appearance='outlined'], .wa-outlined) {
--background-color: var(--wa-color-surface-default);
}
&:not([disabled], [loading]):active,
&::part(checked) {
box-shadow: none;
transform: translateY(var(--wa-shadow-offset-y-s));
}
:where(&),
.wa-light &,
.wa-dark .wa-invert & {
@@ -44,46 +22,6 @@
}
}
wa-radio-group > wa-radio-button {
&::part(base) {
--background-color-active: var(--border-color-active);
--border-color-active: var(--wa-color-neutral-border-loud);
--text-color-active: var(--wa-color-surface-default);
}
&::part(checked) {
--background-color: var(--border-color);
--background-color-hover: var(--border-color);
--border-color: var(--wa-color-neutral-border-loud);
--text-color: var(--wa-color-surface-default);
--text-color-hover: var(--text-color);
}
}
:is(
input:where(
:not(
[type='button'],
[type='checkbox'],
[type='color'],
[type='file'],
[type='hidden'],
[type='image'],
[type='radio'],
[type='range'],
[type='reset'],
[type='submit']
)
),
select,
textarea,
wa-input,
wa-select,
wa-textarea,
.wa-text-field
):not(:focus, [appearance='filled'], .wa-filled) {
--box-shadow: inset var(--wa-shadow-s);
}
wa-badge {
border-radius: var(--wa-border-radius-m);
font-weight: var(--wa-font-weight-bold);

View File

@@ -33,7 +33,7 @@
* Shadows
*/
--wa-shadow-blur-scale: 0;
--wa-shadow-offset-x-scale: 4;
--wa-shadow-offset-x-scale: var(--wa-shadow-offset-y-scale);
--wa-shadow-offset-y-scale: 4;
/**

View File

@@ -44,7 +44,7 @@
}
wa-carousel::part(pagination-item),
wa-comparer::part(handle),
wa-comparison::part(handle),
wa-progress-bar::part(base),
wa-slider::part(base),
input[type='range'],

View File

@@ -2,7 +2,7 @@
:host,
.wa-theme-glossy {
--wa-theme-glossy-inner-shine: inset 0 0.125rem 0 0 rgb(255 255 255 / 0.3);
--wa-theme-glossy-top-highlight: inset 0 0.25rem 0 0 rgb(255 255 255 / 0.15);
--wa-theme-glossy-top-highlight: inset 0 0.25rem 0 0 rgb(255 255 255 / 0.1);
--wa-theme-glossy-upper-tint: inset 0 1.25em 0 0 rgb(255 255 255 / 0.1);
--wa-theme-glossy-lower-shade: inset 0 -1.125em 0 0 rgb(0 0 0 / 0.03);
--wa-theme-glossy-bottom-shadow: inset 0 -0.0625rem 0 0 rgb(0 0 0 / 0.15);
@@ -20,19 +20,36 @@
wa-radio-button,
.wa-button
):not([appearance='plain'], .wa-plain) {
box-shadow: var(--wa-theme-glossy-inner-shine), var(--wa-theme-glossy-top-highlight),
var(--wa-theme-glossy-upper-tint), var(--wa-theme-glossy-lower-shade), var(--wa-theme-glossy-bottom-shadow);
box-shadow:
inset 0 0 0 0.0625rem var(--border-color, var(--background-color, transparent)),
var(--wa-theme-glossy-inner-shine),
var(--wa-theme-glossy-top-highlight),
var(--wa-theme-glossy-upper-tint),
var(--wa-theme-glossy-lower-shade),
var(--wa-theme-glossy-bottom-shadow),
inset 0 0 0 var(--border-width) var(--border-color, var(--background-color, transparent));
margin-bottom: var(--wa-shadow-offset-y-s);
transition: all var(--wa-transition-fast);
&:not([disabled]):active {
box-shadow: var(--wa-theme-glossy-inner-shine-active), var(--wa-theme-glossy-top-highlight-active),
var(--wa-theme-glossy-upper-tint-active), var(--wa-theme-glossy-lower-shade-active),
var(--wa-theme-glossy-bottom-shadow-active);
box-shadow:
inset 0 0 0 0.0625rem var(--border-color-active, var(--background-color-active, transparent)),
var(--wa-theme-glossy-inner-shine-active),
var(--wa-theme-glossy-top-highlight-active),
var(--wa-theme-glossy-upper-tint-active),
var(--wa-theme-glossy-lower-shade-active),
var(--wa-theme-glossy-bottom-shadow-active),
inset 0 0 0 var(--border-width) var(--border-color-active, var(--background-color-active, transparent));
transform: scale(0.98);
}
&::part(base),
:is(&) {
padding-inline: calc(var(--wa-space) + var(--border-width));
border-width: 0px;
}
}
input:where(
@@ -69,13 +86,19 @@
wa-checkbox:is(:state(checked), :state(indeterminate)),
wa-tree-item:is(:state(selected), :state(indeterminate))::part(checkbox__control),
wa-radio:state(checked) {
--box-shadow: var(--wa-theme-glossy-inner-shine), var(--wa-theme-glossy-top-highlight),
var(--wa-theme-glossy-bottom-shadow);
--box-shadow: inset 0 0 0 1px var(--border-color-checked, var(--background-color, transparent)),
var(--wa-theme-glossy-inner-shine), var(--wa-theme-glossy-top-highlight), var(--wa-theme-glossy-bottom-shadow),
inset 0 0 0 var(--border-width) var(--border-color-checked, var(--background-color, transparent));
&:active {
--box-shadow: var(--wa-theme-glossy-inner-shine-active), var(--wa-theme-glossy-top-highlight-active),
var(--wa-theme-glossy-bottom-shadow-active);
}
&::part(control),
:is(&) {
border-width: 0px;
}
}
input[type='range'],

View File

@@ -24,21 +24,26 @@
&:not(
wa-radio-button,
[appearance~='outlined'],
[appearance~='filled'],
[appearance='outlined'],
[appearance~='plain'],
.wa-outlined,
.wa-filled,
.wa-plain
.wa-plain,
.wa-outlined:not(.wa-accent, .wa-filled)
) {
--gradient-top: oklch(from var(--background-color) calc(l - 0.1) c h);
--gradient-top: oklab(from var(--background-color) calc(l - 0.1) a b);
--gradient-middle: var(--background-color);
--gradient-bottom: oklch(from var(--background-color) calc(l + 0.1) c h);
--shadow-outer: 0px 0.375em 1em
color-mix(in oklch, oklch(from var(--background-color) calc(l + 0.1) c h), transparent 70%);
--shadow-lower: inset 0 -0.125em 0.5em oklch(from var(--background-color) calc(l - 0.2) c h);
--shadow-upper: inset 0 0.125em 0.5em oklch(from var(--background-color) calc(l + 0.4) c h);
text-shadow: 0 0.125em 0.125em oklch(from var(--background-color) calc(l - 0.1) c h);
--gradient-bottom: oklab(from var(--background-color) calc(l + 0.1) a b);
--glow-outer: 0px 0.375em 1em
color-mix(in oklab, oklab(from var(--background-color) calc(l + 0.1) a b), transparent 70%);
--shadow-lower: inset 0 -0.125em 0.5em oklab(from var(--background-color) calc(l - 0.2) a b);
--shadow-upper: inset 0 0.125em 0.5em oklab(from var(--background-color) calc(l + 0.4) a b);
text-shadow: 0 0.125em 0.125em oklab(from var(--background-color) calc(l - 0.1) a b);
&:is([appearance~='filled'], .wa-filled) {
--gradient-top: oklab(from var(--background-color) calc(l - 0.05) a b);
--gradient-bottom: oklab(from var(--background-color) calc(l + 0.15) a b);
--shadow-lower: inset 0 -0.125em 0.5em oklab(from var(--background-color) calc(l - 0.1) a b);
--shadow-upper: inset 0 0.125em 0.5em oklab(from var(--background-color) calc(l + 0.5) a b);
}
&::part(base),
:is(&) {
@@ -48,9 +53,15 @@
var(--gradient-middle) 51.88%,
var(--gradient-bottom) 100%
);
box-shadow: var(--shadow-outer), var(--shadow-lower), var(--shadow-upper);
padding-inline: calc(var(--wa-space) + var(--border-width));
border-width: 0px;
box-shadow: var(--glow-outer), var(--shadow-lower), var(--shadow-upper);
}
&:not([appearance~='outlined'], .wa-outlined) {
&::part(base),
:is(&) {
padding-inline: calc(var(--wa-space) + var(--border-width));
border-width: 0px;
}
}
&:not([disabled]) {
@@ -90,9 +101,9 @@
wa-tree-item:is(:state(selected), :state(indeterminate))::part(checkbox__control),
wa-radio:state(checked)::part(control),
wa-switch:state(checked)::part(control) {
--gradient-top: oklch(from var(--background-color-checked) calc(l - 0.1) c h);
--gradient-top: oklab(from var(--background-color-checked) calc(l - 0.1) a b);
--gradient-middle: var(--background-color-checked);
--gradient-bottom: oklch(from var(--background-color-checked) calc(l + 0.1) c h);
--gradient-bottom: oklab(from var(--background-color-checked) calc(l + 0.1) a b);
background: linear-gradient(
180deg,
@@ -106,9 +117,9 @@
wa-progress-bar,
wa-slider {
--shadow-lower: inset 0 -0.125em 0.5em
oklch(from var(--indicator-color, var(--wa-form-control-activated-color)) calc(l - 0.2) c h);
oklab(from var(--indicator-color, var(--wa-form-control-activated-color)) calc(l - 0.2) a b);
--shadow-upper: inset 0 0.125em 0.5em
oklch(from var(--indicator-color, var(--wa-form-control-activated-color)) calc(l + 0.4) c h);
oklab(from var(--indicator-color, var(--wa-form-control-activated-color)) calc(l + 0.4) a b);
--thumb-shadow: var(--wa-shadow-s), var(--shadow-lower), var(--shadow-upper);