Finalize playful theme, closes #490 (#527)

* Finalize Playful theme

* Add changelog, add to alpha

* Add playful theme to alpha build

* Touchup and tweaks

* Tweak hover mix color in `wa-dark`

* Avoid transforming buttons in button groups

* Final touchup

---------

Co-authored-by: Lea Verou <lea@verou.me>
This commit is contained in:
Lindsay M
2025-01-15 17:13:48 -05:00
committed by GitHub
parent dfb9d53a25
commit 5ebe4f4d3e
4 changed files with 178 additions and 119 deletions

View File

@@ -19,6 +19,7 @@ During the alpha period, things might break! We take breaking changes very serio
- Added new themes:
- Glossy
- Premium
- Playful
## 3.0.0-alpha.8

View File

@@ -1,8 +1,7 @@
---
title: Playful
description: Fun, colorful, and full of personality.
description: Cheerful and engaging, like a playground on screen.
isPro: true
tags: pro
noAlpha: true
defaultPalette: rudimentary
---

View File

@@ -128,6 +128,7 @@ async function generateStyles() {
file.includes('themes/active') ||
file.includes('themes/glossy') ||
file.includes('themes/mellow') ||
file.includes('themes/playful') ||
file.includes('themes/premium') ||
file.includes('themes/tailspin') ||
file.includes('themes/brutalist')

View File

@@ -29,53 +29,53 @@
/**
* Semantic Colors
*/
--wa-color-brand-fill-quiet: var(--wa-color-violet-95);
--wa-color-brand-fill-quiet: var(--wa-color-violet-90);
--wa-color-brand-fill-normal: var(--wa-color-violet-80);
--wa-color-brand-fill-loud: var(--wa-color-violet-50);
--wa-color-brand-border-quiet: var(--wa-color-violet-90);
--wa-color-brand-border-normal: var(--wa-color-violet-70);
--wa-color-brand-border-loud: var(--wa-color-violet-50);
--wa-color-brand-on-quiet: var(--wa-color-violet-40);
--wa-color-brand-on-quiet: var(--wa-color-violet-30);
--wa-color-brand-on-normal: var(--wa-color-violet-30);
--wa-color-brand-on-loud: var(--wa-color-violet-95);
--wa-color-brand-on-loud: white;
--wa-color-success-fill-quiet: var(--wa-color-green-95);
--wa-color-success-fill-quiet: var(--wa-color-green-90);
--wa-color-success-fill-normal: var(--wa-color-green-80);
--wa-color-success-fill-loud: var(--wa-color-green-50);
--wa-color-success-border-quiet: var(--wa-color-green-90);
--wa-color-success-border-normal: var(--wa-color-green-70);
--wa-color-success-border-loud: var(--wa-color-green-50);
--wa-color-success-on-quiet: var(--wa-color-green-40);
--wa-color-success-on-quiet: var(--wa-color-green-30);
--wa-color-success-on-normal: var(--wa-color-green-30);
--wa-color-success-on-loud: var(--wa-color-green-95);
--wa-color-success-on-loud: white;
--wa-color-warning-fill-quiet: var(--wa-color-yellow-95);
--wa-color-warning-fill-quiet: var(--wa-color-yellow-90);
--wa-color-warning-fill-normal: var(--wa-color-yellow-80);
--wa-color-warning-fill-loud: var(--wa-color-yellow-50);
--wa-color-warning-border-quiet: var(--wa-color-yellow-90);
--wa-color-warning-border-normal: var(--wa-color-yellow-70);
--wa-color-warning-border-loud: var(--wa-color-yellow-50);
--wa-color-warning-on-quiet: var(--wa-color-yellow-40);
--wa-color-warning-on-quiet: var(--wa-color-yellow-30);
--wa-color-warning-on-normal: var(--wa-color-yellow-30);
--wa-color-warning-on-loud: var(--wa-color-yellow-95);
--wa-color-warning-on-loud: white;
--wa-color-danger-fill-quiet: var(--wa-color-red-95);
--wa-color-danger-fill-quiet: var(--wa-color-red-90);
--wa-color-danger-fill-normal: var(--wa-color-red-80);
--wa-color-danger-fill-loud: var(--wa-color-red-50);
--wa-color-danger-border-quiet: var(--wa-color-red-90);
--wa-color-danger-border-normal: var(--wa-color-red-70);
--wa-color-danger-border-loud: var(--wa-color-red-50);
--wa-color-danger-on-quiet: var(--wa-color-red-40);
--wa-color-danger-on-quiet: var(--wa-color-red-30);
--wa-color-danger-on-normal: var(--wa-color-red-30);
--wa-color-danger-on-loud: var(--wa-color-red-95);
--wa-color-danger-on-loud: white;
--wa-color-neutral-fill-quiet: var(--wa-color-gray-95);
--wa-color-neutral-fill-quiet: var(--wa-color-gray-90);
--wa-color-neutral-fill-normal: var(--wa-color-gray-80);
--wa-color-neutral-fill-loud: var(--wa-color-gray-40);
--wa-color-neutral-border-quiet: var(--wa-color-gray-90);
--wa-color-neutral-border-normal: var(--wa-color-gray-70);
--wa-color-neutral-border-loud: var(--wa-color-gray-50);
--wa-color-neutral-on-quiet: var(--wa-color-gray-40);
--wa-color-neutral-on-quiet: var(--wa-color-gray-30);
--wa-color-neutral-on-normal: var(--wa-color-gray-30);
--wa-color-neutral-on-loud: var(--wa-color-gray-95);
@@ -95,10 +95,21 @@
--wa-font-weight-heading: var(--wa-font-weight-semibold);
--wa-line-height-condensed: 1.35;
--wa-line-height-normal: 1.8;
--wa-line-height-expanded: 2.25;
--wa-link-decoration-default: underline color-mix(in oklab, currentColor 60%, transparent) dashed;
/**
* Borders
*/
--wa-border-width-scale: 4;
--wa-border-width-scale: 3;
/**
* Focus
*/
--wa-focus-ring-width: 0.25rem;
/**
* Rounding
@@ -114,9 +125,8 @@
/**
* Component Groups
*/
--wa-form-control-border-radius: var(--wa-border-radius-pill);
--wa-form-control-border-color: var(--wa-color-neutral-border-normal);
--wa-form-control-border-radius: min(var(--wa-border-radius-pill), calc(var(--wa-form-control-height) * 0.6));
}
.wa-dark,
@@ -137,68 +147,62 @@
--wa-color-text-quiet: var(--wa-color-gray-60);
--wa-color-text-link: var(--wa-color-yellow-80);
--wa-color-overlay-modal: color-mix(in oklab, black 60%, transparent);
--wa-color-overlay-inline: color-mix(in oklab, var(--wa-color-gray-50) 10%, transparent);
--wa-color-shadow: color-mix(in oklab, black calc(var(--wa-shadow-blur-scale) * 32% + 40%), transparent);
--wa-color-focus: var(--wa-color-violet-60);
--wa-color-mix-hover: black 8%;
--wa-color-mix-active: black 16%;
--wa-color-mix-hover: white 10%;
/**
* Semantic Colors
*/
--wa-color-brand-fill-quiet: var(--wa-color-violet-20);
--wa-color-brand-fill-normal: var(--wa-color-violet-40);
--wa-color-brand-fill-loud: var(--wa-color-violet-60);
--wa-color-brand-fill-loud: var(--wa-color-violet-50);
--wa-color-brand-border-quiet: var(--wa-color-violet-30);
--wa-color-brand-border-normal: var(--wa-color-violet-40);
--wa-color-brand-border-loud: var(--wa-color-violet-50);
--wa-color-brand-on-quiet: var(--wa-color-violet-70);
--wa-color-brand-on-normal: var(--wa-color-violet-95);
--wa-color-brand-on-loud: var(--wa-color-violet-10);
--wa-color-brand-on-normal: var(--wa-color-violet-90);
--wa-color-brand-on-loud: white;
--wa-color-success-fill-quiet: var(--wa-color-green-20);
--wa-color-success-fill-normal: var(--wa-color-green-40);
--wa-color-success-fill-loud: var(--wa-color-green-80);
--wa-color-success-fill-loud: var(--wa-color-green-50);
--wa-color-success-border-quiet: var(--wa-color-green-30);
--wa-color-success-border-normal: var(--wa-color-green-40);
--wa-color-success-border-loud: var(--wa-color-green-50);
--wa-color-success-on-quiet: var(--wa-color-green-70);
--wa-color-success-on-normal: var(--wa-color-green-95);
--wa-color-success-on-loud: var(--wa-color-green-20);
--wa-color-success-on-normal: var(--wa-color-green-90);
--wa-color-success-on-loud: white;
--wa-color-warning-fill-quiet: var(--wa-color-yellow-20);
--wa-color-warning-fill-normal: var(--wa-color-yellow-40);
--wa-color-warning-fill-loud: var(--wa-color-yellow-80);
--wa-color-warning-fill-loud: var(--wa-color-yellow-50);
--wa-color-warning-border-quiet: var(--wa-color-yellow-30);
--wa-color-warning-border-normal: var(--wa-color-yellow-40);
--wa-color-warning-border-loud: var(--wa-color-yellow-50);
--wa-color-warning-on-quiet: var(--wa-color-yellow-70);
--wa-color-warning-on-normal: var(--wa-color-yellow-95);
--wa-color-warning-on-loud: var(--wa-color-yellow-20);
--wa-color-warning-on-normal: var(--wa-color-yellow-90);
--wa-color-warning-on-loud: white;
--wa-color-danger-fill-quiet: var(--wa-color-red-20);
--wa-color-danger-fill-normal: var(--wa-color-red-40);
--wa-color-danger-fill-loud: var(--wa-color-red-60);
--wa-color-danger-fill-loud: var(--wa-color-red-50);
--wa-color-danger-border-quiet: var(--wa-color-red-30);
--wa-color-danger-border-normal: var(--wa-color-red-40);
--wa-color-danger-border-loud: var(--wa-color-red-50);
--wa-color-danger-on-quiet: var(--wa-color-red-70);
--wa-color-danger-on-normal: var(--wa-color-red-95);
--wa-color-danger-on-loud: var(--wa-color-red-10);
--wa-color-danger-on-normal: var(--wa-color-red-90);
--wa-color-danger-on-loud: white;
--wa-color-neutral-fill-quiet: var(--wa-color-gray-20);
--wa-color-neutral-fill-normal: var(--wa-color-gray-40);
--wa-color-neutral-fill-loud: var(--wa-color-gray-60);
--wa-color-neutral-fill-loud: var(--wa-color-gray-70);
--wa-color-neutral-border-quiet: var(--wa-color-gray-30);
--wa-color-neutral-border-normal: var(--wa-color-gray-40);
--wa-color-neutral-border-loud: var(--wa-color-gray-50);
--wa-color-neutral-on-quiet: var(--wa-color-gray-70);
--wa-color-neutral-on-normal: var(--wa-color-gray-95);
--wa-color-neutral-on-loud: var(--wa-color-gray-10);
--wa-color-neutral-on-normal: var(--wa-color-gray-90);
--wa-color-neutral-on-loud: var(--wa-color-gray-05);
}
/**
@@ -207,94 +211,148 @@
:where(:root),
:host,
.wa-theme-playful {
wa-button:not([disabled]) {
transition-property: all;
&:hover {
transform: scale(1.02, 1.02);
}
&:active {
transform: scale(0.98, 0.98);
}
}
wa-button:is([appearance~='accent'], [appearance~='filled']) {
--button-gradient-top: oklch(from var(--background-color) calc(l - 0.1) c h);
--button-gradient-middle: var(--background-color);
--button-gradient-bottom: oklch(from var(--background-color) calc(l + 0.1) c h);
--button-shadow-outer: oklch(from var(--background-color) calc(l + 0.1) c h);
--button-shadow-inner-a: oklch(from var(--background-color) calc(l - 0.2) c h);
--button-shadow-inner-b: oklch(from var(--background-color) calc(l + 0.3) c h);
--button-text-shadow: oklch(from var(--background-color) calc(l - 0.1) c h);
--border-color: var(--button-gradient-middle);
--border-width: 1px;
--border-color-hover: var(--button-gradient-middle);
--border-color-active: var(--button-gradient-middle);
&::part(base) {
background: linear-gradient(
180deg,
var(--button-gradient-top) 0%,
var(--button-gradient-middle) 51.88%,
var(--button-gradient-bottom) 100%
);
box-shadow:
0px 6px 16px var(--button-shadow-outer),
inset 0 -2px 8px var(--button-shadow-inner-a),
inset 0 2px 8px var(--button-shadow-inner-b);
}
&:not([disabled])::part(base):hover {
background: linear-gradient(
180deg,
var(--button-gradient-bottom) 0%,
var(--button-gradient-middle) 51.88%,
var(--button-gradient-top) 100%
);
}
&:not([disabled])::part(base):active {
background: linear-gradient(
180deg,
color-mix(in oklab, var(--button-gradient-top), var(--wa-color-mix-active)) 0%,
color-mix(in oklab, var(--button-gradient-middle), var(--wa-color-mix-active)) 51.88%,
color-mix(in oklab, var(--button-gradient-bottom), var(--wa-color-mix-active)) 100%
);
box-shadow:
inset 0 -2px 8px var(--button-shadow-inner-a),
inset 0 2px 8px var(--button-shadow-inner-b);
}
}
wa-button::part(label) {
wa-badge {
font-weight: var(--wa-font-weight-bold);
text-shadow: 0 2px 2px var(--button-text-shadow);
}
wa-callout {
border-style: dashed;
wa-badge,
wa-tag,
wa-select::part(tag) {
border-width: calc(var(--wa-border-width-s) * 0.67);
}
wa-select::part(tag) {
border-radius: var(--wa-form-control-border-radius);
}
wa-checkbox::part(check-icon) {
filter: drop-shadow(var(--wa-shadow-offset-x-s) var(--wa-shadow-offset-y-s) 0.125em var(--wa-color-shadow));
button,
input:where([type='button'], [type='reset'], [type='submit']),
wa-button,
wa-radio-group > wa-radio-button,
.wa-button {
font-weight: var(--wa-font-weight-bold);
&:not([disabled]) {
transition-property: all;
/* Doesn't apply transform to buttons in dropdowns or button groups.
* For dropdowns, this prevents the dropdown panel from shifting. */
&:not(:where(wa-button-group &, wa-dropdown &, wa-radio-group &)) {
&:hover {
transform: scale(1.02, 1.02);
}
&:active {
transform: scale(0.98, 0.98);
}
}
}
&:not(
wa-radio-button,
[appearance~='outlined'],
[appearance~='filled'],
[appearance~='plain'],
.wa-outlined,
.wa-filled,
.wa-plain
) {
--gradient-top: oklch(from var(--background-color) calc(l - 0.1) c h);
--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);
&::part(base),
:is(&) {
background: linear-gradient(
180deg,
var(--gradient-top) 0%,
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;
}
&:not([disabled]) {
&:hover {
&::part(base),
:is(&) {
background: linear-gradient(
180deg,
var(--gradient-bottom) 0%,
var(--gradient-middle) 51.88%,
var(--gradient-top) 100%
);
}
}
&:active {
&::part(base),
:is(&) {
background: linear-gradient(
180deg,
color-mix(in oklab, var(--gradient-top), var(--wa-color-mix-active)) 0%,
color-mix(in oklab, var(--gradient-middle), var(--wa-color-mix-active)) 51.88%,
color-mix(in oklab, var(--gradient-bottom), var(--wa-color-mix-active)) 100%
);
box-shadow:
0 0 transparent,
var(--shadow-lower),
var(--shadow-upper);
}
}
}
}
}
input:is([type='checkbox'], [type='radio']):is(:checked, :indeterminate),
wa-checkbox:is(:state(checked), :state(indeterminate))::part(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-middle: var(--background-color-checked);
--gradient-bottom: oklch(from var(--background-color-checked) calc(l + 0.1) c h);
background: linear-gradient(
180deg,
var(--gradient-top) 0%,
var(--gradient-middle) 51.88%,
var(--gradient-bottom) 100%
);
}
input[type='range'],
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);
--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);
--thumb-shadow: var(--wa-shadow-s), var(--shadow-lower), var(--shadow-upper);
&::part(indicator) {
box-shadow: var(--shadow-lower), var(--shadow-upper);
}
}
input[type='radio'],
wa-radio {
--background-color-checked: var(--wa-form-control-activated-color);
--checked-icon-color: var(--wa-color-surface-default);
--checked-icon-scale: 0.5;
}
wa-rating {
--symbol-color: color-mix(in oklab, var(--symbol-color-active), transparent);
}
wa-switch {
--thumb-size: 0.8em;
--height: 1.5em;
--width: calc(var(--thumb-size) * 3);
}
wa-switch[checked]::part(thumb) {
box-shadow: var(--wa-shadow-s);
}
wa-tag {
border-style: dashed;
border-color: var(--wa-color-border-quiet);
wa-switch[checked] {
--thumb-shadow: var(--wa-shadow-s);
}
}