/* * : a choice of colour profile as a grid of swatch cards, native radios under * them so `wire:model`/`x-model` bind and the arrow keys move the choice. * * [data-md-scheme-picker] fieldset * [data-md-scheme-picker-legend] optional; the fixed label-large/on-surface-variant text * classes carry its type and ink * [data-md-scheme-picker-options] 2 columns below medium, 4 from it * [data-md-scheme-picker-option] the card; md-state-layer for hover and press, a hidden * radio inside read with :has() for focus and choice * [data-md-scheme-picker-swatches] the overlapping dots * [data-md-scheme-picker-swatch] one role's colour, light by default, the dark theme's * custom property from [data-theme='dark'] * [data-md-scheme-picker-label] the profile's name, truncated * [data-md-scheme-picker-check] the chosen mark, shown with the radio * [data-md-scheme-picker-hint] the hint or, in error, the validation message; ink and * type are the fixed text classes on the view * * The chosen card takes secondary-container over a transparent edge, on the fast effects spring; * its focus ring reads off the radio inside with `:has()`, the one thing `md-focus-ring` cannot draw * since the real control is the input, not the label — the same refinement group.css keeps for its * own segments. `dark:` is `[data-theme='dark']` per an ancestor or the element itself * (tokens/theme.css's own `dark` custom variant, `&:where([data-theme='dark'], [data-theme='dark'] * *)`, reduces to a plain descendant selector here since the swatch itself never carries * `data-theme`). */ @layer material.reset, material.tokens, material.base, material.layout, material.components, material.text, material.visibility; @import './icon.css'; @layer material.components { [data-md-scheme-picker] { min-inline-size: 0; } [data-md-scheme-picker-legend] { margin-block-end: var(--md-sys-measurement-space100); } [data-md-scheme-picker-options] { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--md-sys-measurement-space100); @media (width >= 600px) { grid-template-columns: repeat(4, 1fr); } } [data-md-scheme-picker-option] { display: flex; min-inline-size: 0; flex-direction: column; align-items: flex-start; gap: var(--md-sys-measurement-space100); cursor: pointer; -webkit-user-select: none; user-select: none; border: 1px solid var(--md-sys-color-outline-variant); border-radius: var(--md-sys-shape-corner-lg); padding: 12px; background-color: var(--md-sys-color-surface-container-low); color: var(--md-sys-color-on-surface); transition-property: background-color, border-color; transition-duration: var(--md-sys-motion-effects-fast-duration); transition-timing-function: var(--md-sys-motion-effects-fast); &:has(:checked) { border-color: transparent; background-color: var(--md-sys-color-secondary-container); color: var(--md-sys-color-on-secondary-container); } /* Focus lands on the input inside, not the label, so it is read with :has() — the one difference md-state-layer's own :focus-visible rule cannot draw (group.css's segments keep the same refinement, for the same reason). */ &:has(:focus-visible) { outline: 3px solid var(--md-sys-color-secondary); outline-offset: 2px; &::before { opacity: var(--md-sys-state-focus-state-layer-opacity); } } & > input { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border-width: 0; } } [data-md-scheme-picker-swatches] { display: flex; flex-shrink: 0; } [data-md-scheme-picker-swatches] > * + * { margin-inline-start: -6px; } [data-md-scheme-picker-swatch] { inline-size: 20px; block-size: 20px; border-radius: var(--md-sys-shape-corner-full); background-color: var(--swatch-light); box-shadow: 0 0 0 2px var(--md-sys-color-surface-container-low); } [data-theme='dark'] [data-md-scheme-picker-swatch] { background-color: var(--swatch-dark); } [data-md-scheme-picker-option]:has(:checked) [data-md-scheme-picker-swatch] { box-shadow: 0 0 0 2px var(--md-sys-color-secondary-container); } [data-md-scheme-picker-label] { inline-size: 100%; padding-inline-end: var(--md-sys-measurement-space300); } [data-md-scheme-picker-check] { position: absolute; pointer-events: none; inset-inline-end: var(--md-sys-measurement-space100); top: var(--md-sys-measurement-space100); display: none; } [data-md-scheme-picker-option]:has(:checked) [data-md-scheme-picker-check] { display: block; } [data-md-scheme-picker-hint] { margin-block-start: var(--md-sys-measurement-space50); } }