Files
livewire-material/resources/css/tokens/state.css
T
Andreas Reinhold / reiniandClaude Fable 5.1 25ff5a8d71 Key breakpoints, scales, inks and states on M3's tokens
Tailwind's sm…2xl are cleared for M3's window size classes (medium 600, expanded
840, large 1200, extra-large 1600; resources/js/breakpoints.js for scripts), and
its radius, shadow, text-size, weight, leading, tracking and easing scales are
cleared like its palette, so only M3's utilities compile. The semantic inks are
roles rather than opacities (M3 reserves 38% for disabled). state.css declares
M3's state opacities as tokens, adds the dragged layer and a touch-target utility.
Plan: docs/plans/material-3-alignment.md, steps 1, 2, 3 and 8.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9
2026-09-14 03:54:21 +02:00

113 lines
3.2 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* Interaction states, as M3 draws them.
*
* The opacities are M3's state tokens (md.sys.state.*): the content colour laid over an
* element at 8% on hover, 10% on focus and press, 16% while dragged; disabled content at 38%
* and a disabled container at 12%.
*
* `state-layer` puts M3's state layer on an element. Hover only where the pointer can hover,
* because a touch screen keeps the last hover after a tap; `data-dragged` on the element draws
* the dragged layer. The layer is a ::before, so the element becomes `position: relative` and
* `isolation: isolate`; never pass `static` or a z-index to it.
*
* `touch-target` extends an element's pointer target to M3's 48×48px minimum without changing
* what is drawn: a ::after centred on it, at least 48px each way. It is `::after`-based, so a
* component that already draws with ::after wraps its control in an element carrying it.
*
* `focus-ring` is M3's focus indicator — 3px in secondary, 2px out, drawn only for keyboard
* focus. The site gives no thickness or offset; the values are @material/web's focus ring
* tokens (Apache-2.0, © Google LLC). `link` is a link in running text: underlined in the
* colour of the words around it.
*/
:root {
--md-sys-state-hover-state-layer-opacity: 0.08;
--md-sys-state-focus-state-layer-opacity: 0.1;
--md-sys-state-pressed-state-layer-opacity: 0.1;
--md-sys-state-dragged-state-layer-opacity: 0.16;
--md-sys-state-disabled-content-opacity: 0.38;
--md-sys-state-disabled-container-opacity: 0.12;
}
@utility state-layer {
position: relative;
isolation: isolate;
&::before {
content: '';
position: absolute;
inset: 0;
z-index: -1;
border-radius: inherit;
background-color: currentColor;
opacity: 0;
pointer-events: none;
transition: opacity var(--md-sys-motion-effects-fast-duration) var(--md-sys-motion-effects-fast);
}
@media (hover: hover) {
&:hover::before {
opacity: var(--md-sys-state-hover-state-layer-opacity);
}
}
&:focus-visible::before {
opacity: var(--md-sys-state-focus-state-layer-opacity);
}
&:active::before {
opacity: var(--md-sys-state-pressed-state-layer-opacity);
}
&[data-dragged]::before {
opacity: var(--md-sys-state-dragged-state-layer-opacity);
}
&:disabled::before,
&[aria-disabled='true']::before {
display: none;
}
}
@utility touch-target {
position: relative;
&::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 100%;
height: 100%;
min-width: 3rem;
min-height: 3rem;
transform: translate(-50%, -50%);
}
}
@utility focus-ring {
outline: none;
&:focus-visible {
outline: 3px solid var(--md-sys-color-secondary);
outline-offset: 2px;
}
}
@utility link {
cursor: pointer;
text-decoration-line: underline;
text-decoration-thickness: from-font;
text-underline-offset: 0.15em;
border-radius: var(--md-sys-shape-corner-xs);
&:focus-visible {
outline: 3px solid var(--md-sys-color-secondary);
outline-offset: 2px;
}
}
[x-cloak] {
display: none !important;
}