Cut duplicated and speculative code across the package
An over-engineering audit of the whole tree, applied in five reviewed batches. Behaviour stays the same except where UPGRADE.md says otherwise. PHP: the showcase and error-page stylesheets are prebuilt into resources/dist by bin/stylesheets.mjs, through Vite's own postcss-import (first occurrence kept, the order an application's build gives), instead of Stylesheets::bundle() inlining imports on every request; only the import walk DesignGuard needs stays. SchemeStylesheet::withProfiles() replaces three copies of the scheme-plus-profiles loop, material:scheme leaves spec and contrast checks to the node script that already made them, and the error page's scheme cache, the hashed view namespace, the translations path with no lang/ folder and DesignGuard's 1.x-name hints are gone. JS: the androidx shape port progress.js and both bin scripts each carried lives once in resources/js/shapes.js (the generated SVGs are unchanged); util.js holds ringIndex(), ms(), reopenGuard() and remember(), which were written out several times; listeners are released through AbortController; tooltip.js's hoverPopover() serves the rich tooltip too. CSS: every rule for an element inside the navigation rail queries `--md-navigation-rail-value` instead of repeating the seven collapsed conditions under five media branches; badge, alert, progress, slider and button read one non-inheriting colour-role table (components/color.css); the dialog chrome, the submenu's popover chrome, the chip's state layer and touch target, and the visually-hidden inputs use the shared rules they copied; foundation/tokens.css is folded into foundation.css. Views: Support\Field and Support\Link replace the error-key, bound-value and link-attribute blocks copied into the fields and link components; the timepicker period group, the menu filter and the showcase head are partials; the datepicker's steppers and entry fields are loops; component docblocks no longer restate SKILL.md. Tests and tooling: one dataset-driven ComponentStylesheetsTest replaces four per-group files, DesignGuardTest and the layout-component tests use datasets, browser tests share one ready() helper, CSS parsing lives in ComponentStylesheet alone. docs/audits and the finding IDs citing it are removed, as are pestphp/pest-plugin-laravel, the unused composer scripts and check:font; the lint job runs in the feature job, which now installs node packages so the prebuilt-stylesheet staleness test runs in CI. Feature suite 1177 passed, Chrome browser suite 299 passed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
471d927e64
commit
247c596c3a
@@ -2,7 +2,7 @@
|
||||
* Livewire Material for an application that wants everything: the foundation, every layout
|
||||
* stylesheet and every component stylesheet, each imported once. The blocks below are the same
|
||||
* groups `components.css` and `layout.css` used before this file replaced both of them (plan step
|
||||
* 37) — one block per audit stream, so a stylesheet still lands in a predictable place — plus the
|
||||
* 37) — one block per group, so a stylesheet still lands in a predictable place — plus the
|
||||
* Layout block those two files didn't share.
|
||||
*
|
||||
* This is not the recommended way to bring the package's CSS in: importing `all.css` pulls in
|
||||
@@ -38,6 +38,7 @@
|
||||
/* Foundation components */
|
||||
@import './components/icon.css';
|
||||
@import './components/shape.css';
|
||||
@import './components/color.css';
|
||||
|
||||
/* Actions and communication */
|
||||
@import './components/loading.css';
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
/*
|
||||
* <x-account-menu>: the avatar trigger of an `<x-menu>`, its name-and-email header and its theme
|
||||
* item — an M3 "extra" the audit found already inside the foundations (docs/audits/m3-alignment/
|
||||
* navigation.md): a 40px trigger reaching M3's 48px target through `md-touch-target` (N-01), with
|
||||
* item — not one of M3's own catalogued components, so its states are judged against the general
|
||||
* foundations instead: a 40px trigger reaching M3's 48px target through `md-touch-target`, with
|
||||
* `md-state-layer` for the hover and pressed feedback every other trigger in the library already
|
||||
* has (N-15) and `md-focus-ring` for its keyboard ring. The avatar image sits behind the state
|
||||
* has and `md-focus-ring` for its keyboard ring. The avatar image sits behind the state
|
||||
* layer's `::before` (z-index -1, foundation/interaction.css) at z-index -2, so a hover or a press
|
||||
* still washes over the picture instead of under it; nothing clips the pseudo-target the touch
|
||||
* class draws past the 40px circle.
|
||||
|
||||
@@ -9,12 +9,13 @@
|
||||
* neutral (surface-container-high, on-surface — it has no state colour of its own). The dismiss
|
||||
* button is drawn at 40px, pulled 8px out into the alert's padding, and renders the foundation's
|
||||
* `md-state-layer`, `md-focus-ring` and `md-touch-target` (foundation/interaction.css) to reach
|
||||
* M3's 48px target (ACT-18); nothing here copies their rules.
|
||||
* M3's 48px target; nothing here copies their rules.
|
||||
*/
|
||||
|
||||
@layer material.reset, material.tokens, material.base, material.layout, material.components, material.text, material.visibility;
|
||||
|
||||
@import './icon.css';
|
||||
@import './color.css';
|
||||
|
||||
@layer material.components {
|
||||
[data-md-alert] {
|
||||
@@ -23,38 +24,8 @@
|
||||
gap: 12px;
|
||||
border-radius: var(--md-sys-shape-corner-md);
|
||||
padding: var(--md-sys-measurement-space200);
|
||||
background-color: var(--md-sys-color-info-container);
|
||||
color: var(--md-sys-color-on-info-container);
|
||||
}
|
||||
|
||||
[data-md-alert][data-md-color='success'] {
|
||||
background-color: var(--md-sys-color-success-container);
|
||||
color: var(--md-sys-color-on-success-container);
|
||||
}
|
||||
|
||||
[data-md-alert][data-md-color='warning'] {
|
||||
background-color: var(--md-sys-color-warning-container);
|
||||
color: var(--md-sys-color-on-warning-container);
|
||||
}
|
||||
|
||||
[data-md-alert][data-md-color='error'] {
|
||||
background-color: var(--md-sys-color-error-container);
|
||||
color: var(--md-sys-color-on-error-container);
|
||||
}
|
||||
|
||||
[data-md-alert][data-md-color='primary'] {
|
||||
background-color: var(--md-sys-color-primary-container);
|
||||
color: var(--md-sys-color-on-primary-container);
|
||||
}
|
||||
|
||||
[data-md-alert][data-md-color='secondary'] {
|
||||
background-color: var(--md-sys-color-secondary-container);
|
||||
color: var(--md-sys-color-on-secondary-container);
|
||||
}
|
||||
|
||||
[data-md-alert][data-md-color='tertiary'] {
|
||||
background-color: var(--md-sys-color-tertiary-container);
|
||||
color: var(--md-sys-color-on-tertiary-container);
|
||||
background-color: var(--md-container, var(--md-sys-color-info-container));
|
||||
color: var(--md-on-container, var(--md-sys-color-on-info-container));
|
||||
}
|
||||
|
||||
[data-md-alert][data-md-color='neutral'] {
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
* small 64px, title-large title (label-medium subtitle), 4px from the edges, the title 16px
|
||||
* from the start or straight after the navigation icon
|
||||
* center the same, the title centred — a three-column grid, so it shrinks against whatever is
|
||||
* beside it rather than ellipsising underneath it (N-11: a fixed inset fit exactly one
|
||||
* of M3's two trailing buttons)
|
||||
* beside it rather than ellipsising underneath it: a fixed inset fit exactly one
|
||||
* of M3's two trailing buttons
|
||||
* medium 112px (136px with a subtitle): the 64px row of icons over a headline-medium title
|
||||
* large 120px (152px with a subtitle): a display-small title
|
||||
* search the row holds a search bar, full width to 312px and then half of what is left (N-09)
|
||||
* search the row holds a search bar, full width to 312px and then half of what is left
|
||||
*
|
||||
* The container is the surface, and surface-container once content scrolls under it. A medium or
|
||||
* large bar collapses into the small one without script moving anything: the bar is sticky at a
|
||||
@@ -169,7 +169,7 @@
|
||||
|
||||
/* Centred: a three-column row — leading, headline, trailing — so the headline is centred in the
|
||||
window and shrinks against whatever is actually beside it. M3 allows two trailing icon
|
||||
buttons, which a fixed inset for one would have let a long title ellipsise underneath (N-11). */
|
||||
buttons, which a fixed inset for one would have let a long title ellipsise underneath. */
|
||||
[data-md-app-bar][data-md-variant='center'] [data-md-app-bar-row] {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr auto 1fr;
|
||||
@@ -196,7 +196,7 @@
|
||||
}
|
||||
|
||||
/* The search bar fills the space between the leading and trailing elements until it is 312dp
|
||||
wide, and then grows into only half of what is left (N-09). The percentage is of the row
|
||||
wide, and then grows into only half of what is left. The percentage is of the row
|
||||
rather than of that space, which CSS cannot name without measuring it; below 312px the cap
|
||||
never binds, so a phone still gets the whole row. */
|
||||
[data-md-app-bar-search] {
|
||||
|
||||
@@ -20,12 +20,14 @@
|
||||
|
||||
@layer material.reset, material.tokens, material.base, material.layout, material.components, material.text, material.visibility;
|
||||
|
||||
@import './color.css';
|
||||
|
||||
@layer material.components {
|
||||
[data-md-badge] {
|
||||
--md-badge-color: var(--md-sys-color-error);
|
||||
--md-badge-on-color: var(--md-sys-color-on-error);
|
||||
--md-badge-container: var(--md-sys-color-error-container);
|
||||
--md-badge-on-container: var(--md-sys-color-on-error-container);
|
||||
--md-badge-color: var(--md-color, var(--md-sys-color-error));
|
||||
--md-badge-on-color: var(--md-on-color, var(--md-sys-color-on-error));
|
||||
--md-badge-container: var(--md-container, var(--md-sys-color-error-container));
|
||||
--md-badge-on-container: var(--md-on-container, var(--md-sys-color-on-error-container));
|
||||
|
||||
display: inline-flex;
|
||||
flex-shrink: 0;
|
||||
@@ -65,48 +67,6 @@
|
||||
border: 1px solid;
|
||||
}
|
||||
|
||||
[data-md-badge][data-md-color='primary'] {
|
||||
--md-badge-color: var(--md-sys-color-primary);
|
||||
--md-badge-on-color: var(--md-sys-color-on-primary);
|
||||
--md-badge-container: var(--md-sys-color-primary-container);
|
||||
--md-badge-on-container: var(--md-sys-color-on-primary-container);
|
||||
}
|
||||
|
||||
[data-md-badge][data-md-color='secondary'] {
|
||||
--md-badge-color: var(--md-sys-color-secondary);
|
||||
--md-badge-on-color: var(--md-sys-color-on-secondary);
|
||||
--md-badge-container: var(--md-sys-color-secondary-container);
|
||||
--md-badge-on-container: var(--md-sys-color-on-secondary-container);
|
||||
}
|
||||
|
||||
[data-md-badge][data-md-color='tertiary'] {
|
||||
--md-badge-color: var(--md-sys-color-tertiary);
|
||||
--md-badge-on-color: var(--md-sys-color-on-tertiary);
|
||||
--md-badge-container: var(--md-sys-color-tertiary-container);
|
||||
--md-badge-on-container: var(--md-sys-color-on-tertiary-container);
|
||||
}
|
||||
|
||||
[data-md-badge][data-md-color='success'] {
|
||||
--md-badge-color: var(--md-sys-color-success);
|
||||
--md-badge-on-color: var(--md-sys-color-on-success);
|
||||
--md-badge-container: var(--md-sys-color-success-container);
|
||||
--md-badge-on-container: var(--md-sys-color-on-success-container);
|
||||
}
|
||||
|
||||
[data-md-badge][data-md-color='warning'] {
|
||||
--md-badge-color: var(--md-sys-color-warning);
|
||||
--md-badge-on-color: var(--md-sys-color-on-warning);
|
||||
--md-badge-container: var(--md-sys-color-warning-container);
|
||||
--md-badge-on-container: var(--md-sys-color-on-warning-container);
|
||||
}
|
||||
|
||||
[data-md-badge][data-md-color='info'] {
|
||||
--md-badge-color: var(--md-sys-color-info);
|
||||
--md-badge-on-color: var(--md-sys-color-on-info);
|
||||
--md-badge-container: var(--md-sys-color-info-container);
|
||||
--md-badge-on-container: var(--md-sys-color-on-info-container);
|
||||
}
|
||||
|
||||
[data-md-badge][data-md-color='neutral'] {
|
||||
--md-badge-color: var(--md-sys-color-on-surface-variant);
|
||||
--md-badge-on-color: var(--md-sys-color-surface);
|
||||
|
||||
@@ -8,13 +8,13 @@
|
||||
* [data-md-bottom-sheet-probe] hidden, measures a stop's px height for a drag to settle on
|
||||
* [data-md-bottom-sheet-panel] surface-container-low, extra-large top corners, elevation 1;
|
||||
* data-md-preset while `heights`/`snap` gives it stops
|
||||
* [data-md-bottom-sheet-handle] the drag target and M3's 48dp hit area (C-01)
|
||||
* [data-md-bottom-sheet-handle] the drag target and M3's 48dp hit area
|
||||
* [data-md-bottom-sheet-grip] the 32×4px bar, the shared classes' touch target
|
||||
* [data-md-bottom-sheet-announce] a live region, only while stops exist
|
||||
* [data-md-bottom-sheet-body], [data-md-bottom-sheet-title], [data-md-bottom-sheet-actions]
|
||||
*
|
||||
* 640px max width, centred; 28px top corners only (`DockedContainerShape` = CornerExtraLargeTop);
|
||||
* 50dvh default open height under a ceiling of the screen less M3's 72dp top margin (C-19). It
|
||||
* 50dvh default open height under a ceiling of the screen less M3's 72dp top margin. It
|
||||
* rises on emphasized decelerate and only falls on emphasized accelerate — the asymmetric timing a
|
||||
* more specific selector for the open state supplies, since a CSS transition always takes its
|
||||
* duration and easing from the *after-change* style (the technique resources/css/components/
|
||||
|
||||
@@ -143,10 +143,7 @@
|
||||
[data-md-button-group='connected'] > * {
|
||||
--md-button-group-corner: var(--md-button-group-inner);
|
||||
|
||||
border-start-start-radius: var(--md-button-group-corner);
|
||||
border-end-start-radius: var(--md-button-group-corner);
|
||||
border-start-end-radius: var(--md-button-group-corner);
|
||||
border-end-end-radius: var(--md-button-group-corner);
|
||||
border-radius: var(--md-button-group-corner);
|
||||
}
|
||||
|
||||
[data-md-button-group='connected'] > :active {
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
* lg 96px 48px 12px headline-sm 32 / 32px 2px xl lg
|
||||
* xl 136px 64px 16px headline-lg 40 / 40px 3px xl lg
|
||||
*
|
||||
* (ButtonXSmall…XLargeTokens; the xs padding is the 16px Phase D settled on, ACT-09.) An icon button
|
||||
* (ButtonXSmall…XLargeTokens; the xs padding is the 16px Phase D settled on.) An icon button
|
||||
* (`data-md-icon-button`) is as tall and `narrow`, `default` or `wide` across by
|
||||
* XSmall…XLargeIconButtonTokens: 28/32/40, 32/40/52, 48/56/72, 64/96/128 and 104/136/184px. The
|
||||
* views size the glyphs through `<x-icon size>`; `--md-button-icon` carries the same size for the
|
||||
@@ -30,7 +30,7 @@
|
||||
* plain declaration. Primary's tonal button is secondary-container and its standard icon button
|
||||
* on-surface-variant, as M3 draws them; the text button's label is primary, as Compose draws it,
|
||||
* not the token's on-surface-variant, which its own source marks as wrong; a selected text button
|
||||
* takes the tonal container (the library's deliberate deviations, docs/audits/m3-alignment).
|
||||
* takes the tonal container (a deliberate deviation from the token).
|
||||
*
|
||||
* Motion: corners, padding, margins and `bottom` on the fast spatial spring, colour and shadow on
|
||||
* the fast effects spring beside it — a colour must never overshoot (tokens/motion.css).
|
||||
@@ -54,13 +54,14 @@
|
||||
@import './icon.css';
|
||||
@import './loading.css';
|
||||
@import './tooltip.css';
|
||||
@import './color.css';
|
||||
|
||||
@layer material.components {
|
||||
[data-md-button] {
|
||||
--md-button-color: var(--md-sys-color-primary);
|
||||
--md-button-on-color: var(--md-sys-color-on-primary);
|
||||
--md-button-tone: var(--md-sys-color-secondary-container);
|
||||
--md-button-on-tone: var(--md-sys-color-on-secondary-container);
|
||||
--md-button-color: var(--md-color, var(--md-sys-color-primary));
|
||||
--md-button-on-color: var(--md-on-color, var(--md-sys-color-on-primary));
|
||||
--md-button-tone: var(--md-container, var(--md-sys-color-secondary-container));
|
||||
--md-button-on-tone: var(--md-on-container, var(--md-sys-color-on-secondary-container));
|
||||
--md-button-tone-selected: var(--md-sys-color-secondary);
|
||||
--md-button-on-tone-selected: var(--md-sys-color-on-secondary);
|
||||
--md-button-quiet: var(--md-sys-color-on-surface-variant);
|
||||
@@ -223,49 +224,14 @@
|
||||
border-radius: var(--md-button-pressed);
|
||||
}
|
||||
|
||||
/* Colour roles. */
|
||||
[data-md-button][data-md-color='secondary'] {
|
||||
--md-button-color: var(--md-sys-color-secondary);
|
||||
--md-button-on-color: var(--md-sys-color-on-secondary);
|
||||
/* Colour roles: every hue but primary comes straight off the shared table (color.css). Its
|
||||
`primary` entry is plain primary-container, so the one hue this file draws differently keeps
|
||||
a small override of its own. */
|
||||
[data-md-button][data-md-color='primary'] {
|
||||
--md-button-tone: var(--md-sys-color-secondary-container);
|
||||
--md-button-on-tone: var(--md-sys-color-on-secondary-container);
|
||||
}
|
||||
|
||||
[data-md-button][data-md-color='tertiary'] {
|
||||
--md-button-color: var(--md-sys-color-tertiary);
|
||||
--md-button-on-color: var(--md-sys-color-on-tertiary);
|
||||
--md-button-tone: var(--md-sys-color-tertiary-container);
|
||||
--md-button-on-tone: var(--md-sys-color-on-tertiary-container);
|
||||
}
|
||||
|
||||
[data-md-button][data-md-color='error'] {
|
||||
--md-button-color: var(--md-sys-color-error);
|
||||
--md-button-on-color: var(--md-sys-color-on-error);
|
||||
--md-button-tone: var(--md-sys-color-error-container);
|
||||
--md-button-on-tone: var(--md-sys-color-on-error-container);
|
||||
}
|
||||
|
||||
[data-md-button][data-md-color='success'] {
|
||||
--md-button-color: var(--md-sys-color-success);
|
||||
--md-button-on-color: var(--md-sys-color-on-success);
|
||||
--md-button-tone: var(--md-sys-color-success-container);
|
||||
--md-button-on-tone: var(--md-sys-color-on-success-container);
|
||||
}
|
||||
|
||||
[data-md-button][data-md-color='warning'] {
|
||||
--md-button-color: var(--md-sys-color-warning);
|
||||
--md-button-on-color: var(--md-sys-color-on-warning);
|
||||
--md-button-tone: var(--md-sys-color-warning-container);
|
||||
--md-button-on-tone: var(--md-sys-color-on-warning-container);
|
||||
}
|
||||
|
||||
[data-md-button][data-md-color='info'] {
|
||||
--md-button-color: var(--md-sys-color-info);
|
||||
--md-button-on-color: var(--md-sys-color-on-info);
|
||||
--md-button-tone: var(--md-sys-color-info-container);
|
||||
--md-button-on-tone: var(--md-sys-color-on-info-container);
|
||||
}
|
||||
|
||||
/* Every colour but primary selects into the colour itself and is quiet in it. */
|
||||
[data-md-button]:not([data-md-color='primary']) {
|
||||
--md-button-tone-selected: var(--md-button-color);
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
* OutlinedCardTokens.kt, androidx Compose Material 3, Apache-2.0; docs/reference/m3
|
||||
* § Cards → Specs) — filled (surface-container-highest), elevated (surface-container-low at
|
||||
* elevation 1) and outlined (surface, an outline-variant edge); one 12dp corner for all three,
|
||||
* which never morphs (M3 specifies shape morph for buttons, FABs and list items, never cards —
|
||||
* docs/audits/m3-alignment/containment.md, C-23).
|
||||
* which never morphs (M3 specifies shape morph for buttons, FABs and list items, never cards).
|
||||
*
|
||||
* Every card renders the shared `md-state-layer` class, and a row (`data-md-list-row`,
|
||||
* `resources/js/list-rows.js`) `md-focus-ring` too (foundation/interaction.css), for its tint and
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
/*
|
||||
* <x-carousel-item>: one slide of an <x-carousel>, masked and shifted by the keyline maths
|
||||
* carousel.css's header describes, unless the row is full-screen or multi-aspect, where nothing
|
||||
* masks it at all (docs/reference/m3/components-actions-communication-containment.md § Carousel;
|
||||
* docs/audits/m3-alignment/containment.md, C-11, C-12, C-25).
|
||||
* masks it at all (docs/reference/m3/components-actions-communication-containment.md § Carousel).
|
||||
*
|
||||
* [data-md-carousel-item] the tab stop (C-18), a focusable `group`, `md-focus-ring`
|
||||
* [data-md-carousel-item] the tab stop, a focusable `group`, `md-focus-ring`
|
||||
* [data-md-carousel-surface] the masked, shifted, extra-large-corner (28px) box
|
||||
* [data-md-carousel-content] the slot (an <img>, cropped)
|
||||
* [data-md-carousel-label] the `label` prop's words, over a scrim gradient
|
||||
@@ -26,7 +25,7 @@
|
||||
* The label's ink is a literal `white`, not a role: it sits over `--md-sys-color-scrim`, which is
|
||||
* black in every scheme, theme and contrast level, so white is the one ink that always has the
|
||||
* scrim's contrast — a role (`inverse-on-surface`) is dark ink in a dark scheme and fails there
|
||||
* (C-25, deliberately kept, as the component's original header explained).
|
||||
* (deliberately kept).
|
||||
*/
|
||||
|
||||
@layer material.reset, material.tokens, material.base, material.layout, material.components, material.text, material.visibility;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* and sizes as inline custom properties every scroll frame; this file draws everything the script
|
||||
* does not — the row's layout per layout, and the controls — and carousel-item.css draws the
|
||||
* item and its mask (docs/reference/m3/components-actions-communication-containment.md
|
||||
* § Carousel; docs/audits/m3-alignment/containment.md).
|
||||
* § Carousel).
|
||||
*
|
||||
* [data-md-carousel] the row wrapper; its value is the layout
|
||||
* [data-md-carousel-probe] hidden, measures the preferred item width for the script
|
||||
@@ -17,12 +17,12 @@
|
||||
* [data-md-carousel-previous], [data-md-carousel-next]
|
||||
*
|
||||
* Specs table: 16dp leading/trailing padding, 8dp top/bottom and between items, for every layout
|
||||
* but uncontained (leading only) and full-screen (0, edge to edge — C-12); a `>` combinator
|
||||
* but uncontained (leading only) and full-screen (0, edge to edge); a `>` combinator
|
||||
* throughout, never a bare descendant one, because a carousel item can itself hold a nested
|
||||
* carousel (a `multi-aspect` gallery inside a `hero` slide) whose own root would otherwise match
|
||||
* its parent's rules too. Full-screen scrolls vertically, one edge-to-edge item at a time, capped
|
||||
* at the 840px medium window it is meant for (C-11); reduced motion needs no rule here at all —
|
||||
* the script writes zero inset, shift and full opacity itself for every layout (C-05).
|
||||
* at the 840px medium window it is meant for; reduced motion needs no rule here at all —
|
||||
* the script writes zero inset, shift and full opacity itself for every layout.
|
||||
*
|
||||
* The previous/next icons mirror in RTL by scaling the whole button, as the row's arrow keys and
|
||||
* scroll direction already do (`resources/js/carousel.js`'s own `state.rtl`), rather than through
|
||||
@@ -53,10 +53,6 @@
|
||||
[data-md-carousel] > [data-md-carousel-scroller] {
|
||||
display: flex;
|
||||
scrollbar-width: none;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
[data-md-carousel='full-screen'] > [data-md-carousel-scroller] {
|
||||
|
||||
@@ -76,55 +76,28 @@
|
||||
|
||||
/* ---- Assist, filter and suggestion: the chip is the control ------------------------------ */
|
||||
|
||||
/* The state layer and the 48px target are the foundation's `md-state-layer md-touch-target`
|
||||
classes now (chip.blade.php, as group and scheme-picker's own controls render them;
|
||||
foundation/interaction.css), at the same opacities and off the same `currentColor` this
|
||||
chip always painted them from. Three extras stay chip's own: a filter chip's label is never
|
||||
itself `:focus-visible` — the checkbox inside it is, caught with `:has()`, the same way the
|
||||
ring below already had to; `data-md-disabled` marks a chip with no native `disabled` to
|
||||
catch (a link, or a toggle button with no press of its own). */
|
||||
[data-md-chip]:not([data-md-chip='input']) {
|
||||
isolation: isolate;
|
||||
padding-inline: 15px;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
|
||||
/* The 48px target, past the chip's 32px. */
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset-inline: 0;
|
||||
top: 50%;
|
||||
height: var(--md-sys-measurement-space600);
|
||||
translate: 0 -50%;
|
||||
}
|
||||
|
||||
&::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,
|
||||
&:has(:focus-visible)::before {
|
||||
opacity: var(--md-sys-state-focus-state-layer-opacity);
|
||||
}
|
||||
|
||||
&:active::before {
|
||||
opacity: var(--md-sys-state-pressed-state-layer-opacity);
|
||||
}
|
||||
|
||||
&:is(:focus-visible, :has(:focus-visible)) {
|
||||
outline: 3px solid var(--md-sys-color-secondary);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
&:is(:disabled, [aria-disabled='true'], [data-md-disabled])::before {
|
||||
&[data-md-disabled]::before {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* <x-collapse>: not an M3 component — M3 has expandable list items and menu expansion but no
|
||||
* standalone disclosure — built on the native `<details>` so it opens without script, keeps its
|
||||
* state through a Livewire morph, and is announced as a disclosure by the browser. Judged against
|
||||
* foundations rather than any M3 component spec (docs/audits/m3-alignment/containment.md, C-24).
|
||||
* foundations rather than any M3 component spec, since M3 has no standalone disclosure.
|
||||
*
|
||||
* The height eases open and shut on the fast spatial spring, the same one that turns the chevron,
|
||||
* from resources/js/collapse.js: it animates the `<details>`' own `block-size`. This file cannot —
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* The colour-role table M3's semantic colours share, so a component that offers the same set of
|
||||
* roles does not repeat it: `data-md-color` picks primary (most components' default, drawn
|
||||
* without the attribute), secondary, tertiary, error, success, warning or info, and this sets the
|
||||
* four generic variables a component's own stylesheet reads — `--md-color`/`--md-on-color` the
|
||||
* role itself, `--md-container`/`--md-on-container` its tonal container.
|
||||
*
|
||||
* A component gives its own prefixed variables (`--md-badge-color`, …) a fallback of its default
|
||||
* role, `var(--md-color, var(--md-sys-color-<default>))`, so the generic ones only take over once
|
||||
* `data-md-color` is actually written on that element. The four are registered as not inheriting,
|
||||
* so a component inside a coloured one (a badge on an error button) still falls back to its own
|
||||
* default rather than taking its ancestor's role. A component whose primary
|
||||
* deliberately reads secondary-container instead of primary-container (button.css, slider.css,
|
||||
* progress.css) keeps a small override of its own for an explicit `data-md-color="primary"` too:
|
||||
* this file's `primary` entry is the plain M3 mapping every other role, and every other component,
|
||||
* wants.
|
||||
*
|
||||
* A component that supports only part of this set (fab.css's primary/secondary/tertiary) does not
|
||||
* import this file: wiring it in would make every role it leaves out suddenly take effect through
|
||||
* the bare `[data-md-color]` selector below, a behaviour change rather than a rewrite.
|
||||
*/
|
||||
|
||||
@layer material.reset, material.tokens, material.base, material.layout, material.components, material.text, material.visibility;
|
||||
|
||||
@layer material.components {
|
||||
@property --md-color {
|
||||
syntax: '*';
|
||||
inherits: false;
|
||||
}
|
||||
|
||||
@property --md-on-color {
|
||||
syntax: '*';
|
||||
inherits: false;
|
||||
}
|
||||
|
||||
@property --md-container {
|
||||
syntax: '*';
|
||||
inherits: false;
|
||||
}
|
||||
|
||||
@property --md-on-container {
|
||||
syntax: '*';
|
||||
inherits: false;
|
||||
}
|
||||
|
||||
[data-md-color='primary'] {
|
||||
--md-color: var(--md-sys-color-primary);
|
||||
--md-on-color: var(--md-sys-color-on-primary);
|
||||
--md-container: var(--md-sys-color-primary-container);
|
||||
--md-on-container: var(--md-sys-color-on-primary-container);
|
||||
}
|
||||
|
||||
[data-md-color='secondary'] {
|
||||
--md-color: var(--md-sys-color-secondary);
|
||||
--md-on-color: var(--md-sys-color-on-secondary);
|
||||
--md-container: var(--md-sys-color-secondary-container);
|
||||
--md-on-container: var(--md-sys-color-on-secondary-container);
|
||||
}
|
||||
|
||||
[data-md-color='tertiary'] {
|
||||
--md-color: var(--md-sys-color-tertiary);
|
||||
--md-on-color: var(--md-sys-color-on-tertiary);
|
||||
--md-container: var(--md-sys-color-tertiary-container);
|
||||
--md-on-container: var(--md-sys-color-on-tertiary-container);
|
||||
}
|
||||
|
||||
[data-md-color='error'] {
|
||||
--md-color: var(--md-sys-color-error);
|
||||
--md-on-color: var(--md-sys-color-on-error);
|
||||
--md-container: var(--md-sys-color-error-container);
|
||||
--md-on-container: var(--md-sys-color-on-error-container);
|
||||
}
|
||||
|
||||
[data-md-color='success'] {
|
||||
--md-color: var(--md-sys-color-success);
|
||||
--md-on-color: var(--md-sys-color-on-success);
|
||||
--md-container: var(--md-sys-color-success-container);
|
||||
--md-on-container: var(--md-sys-color-on-success-container);
|
||||
}
|
||||
|
||||
[data-md-color='warning'] {
|
||||
--md-color: var(--md-sys-color-warning);
|
||||
--md-on-color: var(--md-sys-color-on-warning);
|
||||
--md-container: var(--md-sys-color-warning-container);
|
||||
--md-on-container: var(--md-sys-color-on-warning-container);
|
||||
}
|
||||
|
||||
[data-md-color='info'] {
|
||||
--md-color: var(--md-sys-color-info);
|
||||
--md-on-color: var(--md-sys-color-on-info);
|
||||
--md-container: var(--md-sys-color-info-container);
|
||||
--md-on-container: var(--md-sys-color-on-info-container);
|
||||
}
|
||||
}
|
||||
@@ -51,6 +51,7 @@
|
||||
@import './field.css';
|
||||
@import './icon.css';
|
||||
@import './button.css';
|
||||
@import './modal.css';
|
||||
|
||||
@layer material.components {
|
||||
/* ---- The support line under the field ------------------------------------------------------ */
|
||||
@@ -112,25 +113,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
/* The entry pop and the scrim are modal.css's shared dialog chrome, imported above. */
|
||||
[data-md-datepicker-picker]:modal {
|
||||
inset: 0;
|
||||
margin: auto;
|
||||
opacity: 1;
|
||||
scale: 1;
|
||||
transition-property: opacity, scale;
|
||||
transition-duration: var(--md-sys-motion-spatial-fast-duration);
|
||||
transition-timing-function: var(--md-sys-motion-spatial-fast);
|
||||
}
|
||||
|
||||
@starting-style {
|
||||
[data-md-datepicker-picker]:modal {
|
||||
opacity: 0;
|
||||
scale: 0.95;
|
||||
}
|
||||
}
|
||||
|
||||
[data-md-datepicker-picker]:modal::backdrop {
|
||||
background-color: color-mix(in srgb, var(--md-sys-color-scrim) 32%, transparent);
|
||||
}
|
||||
|
||||
[data-md-datepicker-surface] {
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* [data-md-drawer-subtitle], [data-md-drawer-close]
|
||||
* [data-md-drawer-body] a size container, so its contents lay out by the sheet's own
|
||||
* width (`@md:`), never the viewport's
|
||||
* [data-md-drawer-actions] left-aligned, 72dp (C-10 — a dialog's are trailing-aligned)
|
||||
* [data-md-drawer-actions] left-aligned, 72dp — a dialog's are trailing-aligned
|
||||
*
|
||||
* 400px cap, 24dp start/end padding, a large corner on the inner edge only — from the specs
|
||||
* table. It enters on the emphasized-decelerate easing rather than a spring, because a sheet
|
||||
|
||||
@@ -29,13 +29,13 @@
|
||||
* as the old `font-sans` was; only the fallback, which has no `@font-face`, uses a system stack.
|
||||
*
|
||||
* Colours from the roles (`docs/reference/m3/styles.md` § Typography, "Accessibility
|
||||
* requirements": surface/on-surface); the display code over its primary-container shape is the
|
||||
* pairing `docs/audits/m3-alignment/containment.md`'s "Aligned" section confirms; 24px page
|
||||
* gutters and the 600px growth of the art and headline are the same numbers the audit found
|
||||
* clean. `--md-sys-typescale-emphasized-display-lg` is the code's weight and roundedness; the
|
||||
* shape's 60s linear turn has no motion token (`--md-sys-motion-*` pairs a duration with a spring
|
||||
* for a state change, not an ambient loop) and stays a literal, gated the way the audit's
|
||||
* "Aligned" section already found it: behind `prefers-reduced-motion: no-preference`.
|
||||
* requirements": surface/on-surface); the display code over its primary-container shape is a
|
||||
* correct on-primary-container/primary-container contrast pairing; 24px page gutters and the
|
||||
* 600px growth of the art and headline follow the same spacing rules as every other M3 surface in
|
||||
* the library. `--md-sys-typescale-emphasized-display-lg` is the code's weight and roundedness;
|
||||
* the shape's 60s linear turn has no motion token (`--md-sys-motion-*` pairs a duration with a
|
||||
* spring for a state change, not an ambient loop) and stays a literal, gated behind
|
||||
* `prefers-reduced-motion: no-preference` like every other ambient animation in the library.
|
||||
*/
|
||||
|
||||
@layer material.reset, material.tokens, material.base, material.layout, material.components, material.text, material.visibility;
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
*
|
||||
* The entry is `@starting-style` on the item itself; the exit is the popover's exit copy
|
||||
* (resources/js/popover-exit.js), whose items fab-menu.css sets to the closed values, so the item
|
||||
* has somewhere to animate to (ACT-33).
|
||||
* has somewhere to animate to.
|
||||
*/
|
||||
|
||||
@layer material.reset, material.tokens, material.base, material.layout, material.components, material.text, material.visibility;
|
||||
|
||||
@@ -4,17 +4,17 @@
|
||||
* FabMenuBaselineTokens (androidx Compose Material 3, Apache-2.0): the trigger is a 56px FAB,
|
||||
* `data-md-color`'s container, large corner, elevation 3, rising to elevation 4 under a hovering
|
||||
* pointer; while its list is open (`aria-expanded`) it turns fully round and paints the colour
|
||||
* itself, on the default spatial and effects springs (ACT-19 splits the two). It renders the
|
||||
* itself, on the default spatial and effects springs (split between the two). It renders the
|
||||
* foundation's `md-state-layer` and `md-focus-ring` (foundation/interaction.css); its 56px already
|
||||
* meets M3's target, so it needs no `md-touch-target`. The list sits
|
||||
* `data-md-position`'s corner of the trigger, 8px padding — the room the close button keeps below
|
||||
* the first item — and scrolls past `calc(100dvh - 128px)` on a short window, behind the close
|
||||
* button, which stays fixed (ACT-32).
|
||||
* button, which stays fixed.
|
||||
*
|
||||
* The items (fab-menu-item.css) rise into place as the list opens and sink back as it closes: the
|
||||
* entry is `@starting-style` on the item itself; the exit is the popover's exit copy
|
||||
* (`data-md-popover-exit`, resources/js/popover-exit.js), which stays on screen after the popover
|
||||
* has closed, so the items have somewhere to animate to (ACT-33) in every engine, Firefox included.
|
||||
* has closed, so the items have somewhere to animate to in every engine, Firefox included.
|
||||
* `[data-md-fab-menu-popover]:not(:popover-open) > *` and the copy's `[data-md-popover-closing] > *`
|
||||
* are the closed values; inside the layer they beat fab-menu-item.css's resting `translate: 0 0`
|
||||
* and `opacity: 1` on specificity — two attributes, or an attribute and a pseudo-class, against the
|
||||
|
||||
@@ -126,11 +126,6 @@
|
||||
font-family: var(--md-ref-typeface-mono);
|
||||
}
|
||||
|
||||
[data-md-field-control]::placeholder {
|
||||
color: var(--md-sys-color-on-surface-variant);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* Autofill paints its own background, which on a card is a pale block in the
|
||||
wrong colour. Delaying the transition for a week keeps the field's own. */
|
||||
[data-md-field-control]:-webkit-autofill {
|
||||
|
||||
@@ -97,18 +97,9 @@
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* The radio or checkbox stays in the page, for the form, the keyboard and a screen reader. */
|
||||
& > input {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
padding: 0;
|
||||
margin: -1px;
|
||||
overflow: hidden;
|
||||
clip-path: inset(50%);
|
||||
white-space: nowrap;
|
||||
border-width: 0;
|
||||
}
|
||||
/* The radio or checkbox stays in the page, for the form, the keyboard and a screen reader
|
||||
— `md-visually-hidden` on the element itself (text.css), which outranks this layer
|
||||
whatever wins the specificity, `material.text` sitting above `material.components`. */
|
||||
}
|
||||
|
||||
[data-md-group][data-md-inline] [data-md-group-segment] {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Material 3, Apache-2.0) — the tallest element sets the height, and a three-line item top-aligns
|
||||
* rather than centring (docs/reference/m3/components-actions-communication-containment.md
|
||||
* § Lists → Specs). Leading/trailing gap and container padding are both `space200` (16px,
|
||||
* `ItemLeadingSpace`/`ItemTrailingSpace`/container padding, C-14).
|
||||
* `ItemLeadingSpace`/`ItemTrailingSpace`/container padding).
|
||||
*
|
||||
* `data-md-list-row` (`resources/js/list-rows.js`, shared with `<x-card>` and an application's own
|
||||
* table rows) and `[data-md-list-open]:focus-visible` answer with the state layer — the row's ink at
|
||||
@@ -12,25 +12,25 @@
|
||||
* `[data-md-card]`, which draws its own tint through the shared `md-state-layer` class instead
|
||||
* (card.css). The layer is mixed over the row's own fill, `--md-list-row-fill` (a segmented tile's
|
||||
* surface, a selected item's secondary-container, table.css's selected row), so a hovered, pressed
|
||||
* or focused row keeps its fill under the tint instead of trading it for a translucent one (C-08's
|
||||
* second fix). `data-md-selected` is M3's selected item, secondary-container filled, which also
|
||||
* or focused row keeps its fill under the tint instead of trading it for a translucent one.
|
||||
* `data-md-selected` is M3's selected item, secondary-container filled, which also
|
||||
* lifts the description/overline/trailing/icon colour rules below since they exclude it — the
|
||||
* container's own colour takes over by inheritance. The same attribute on any other row that is
|
||||
* not a card — an application's own `<li>`, `<div>` or `<tr>` — draws the same fill and ink, as
|
||||
* 1.x's `data-selected` did; a card keeps its own container. A selected option draws a second cue, a
|
||||
* trailing check, so selection is never colour alone (C-03). `aria-disabled` inks the whole item
|
||||
* trailing check, so selection is never colour alone. `aria-disabled` inks the whole item
|
||||
* on-surface at the disabled-content opacity (38%) and blocks the pointer; the view drops the
|
||||
* item's link entirely rather than leaving a focusable, activatable control behind it (C-02).
|
||||
* item's link entirely rather than leaving a focusable, activatable control behind it.
|
||||
*
|
||||
* `data-md-list="segmented"` items (M3 Expressive) are `surface-container` tiles (one tone up from
|
||||
* `ItemSegmentedContainerColor`, so they read against the package's own `surface` page;
|
||||
* C-21), 4px corners that open to 16px at the list's own ends and while hovered (12px), pressed,
|
||||
* focused or selected (16px) — the specs page's interaction-state expressive shapes (C-22). Leading
|
||||
* `ItemSegmentedContainerColor`, so they read against the package's own `surface` page),
|
||||
* 4px corners that open to 16px at the list's own ends and while hovered (12px), pressed,
|
||||
* focused or selected (16px) — the specs page's interaction-state expressive shapes. Leading
|
||||
* icons there are drawn at 20px, not scaled down from 24 — list-item.blade.php passes `size` to
|
||||
* `<x-icon>` from the parent's `@aware(['segmented'])`, so no CSS override is needed here (C-26).
|
||||
* `<x-icon>` from the parent's `@aware(['segmented'])`, so no CSS override is needed here.
|
||||
*
|
||||
* `data-md-dividers` on the list insets its rule 16px from both ends (`DividerLeadingSpace`/
|
||||
* `DividerTrailingSpace`, C-16) rather than full-bleed.
|
||||
* `DividerTrailingSpace`) rather than full-bleed.
|
||||
*
|
||||
* Leading media: `data-md-list-item-avatar` is 40px, full corner, initials in primary-container
|
||||
* when it is a `<span>`, an image otherwise; `data-md-list-item-image` is a 56px small-corner
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* `selectable`/`selection` switch the container's role between `list` and `listbox`
|
||||
* (list.blade.php; docs/reference/m3/components-actions-communication-containment.md
|
||||
* § Lists → Accessibility, C-03) — a role takes no CSS of its own.
|
||||
* § Lists → Accessibility) — a role takes no CSS of its own.
|
||||
*/
|
||||
|
||||
@layer material.reset, material.tokens, material.base, material.layout, material.components, material.text, material.visibility;
|
||||
|
||||
@@ -3,20 +3,20 @@
|
||||
* the trigger and popover of a nested menu beside it.
|
||||
*
|
||||
* SegmentedMenuTokens (androidx Compose Material 3, Apache-2.0): 48px row (M3's published "List
|
||||
* item height" wins over the token's own 44dp `Item`, docs/audits/m3-alignment/actions.md §
|
||||
* ACT-28), 16px either side (`ItemLeadingSpace`/`ItemTrailingSpace`, § ACT-11), 12px between the
|
||||
* icon, the label and the trailing content (`ItemBetweenSpace`, off the 8dp grid), 4px corners
|
||||
* (`ItemShape`) that open to 12px at either end of the list (`ItemFirstChildShape`/
|
||||
* `ItemLastChildShape` — the library's own list ends, 12px, win over `GroupShape`'s 8dp so a
|
||||
* cluster's ends and a list's ends match, menu-group.css). A selected row
|
||||
* (`role="menuitemcheckbox"`, the tick beside the colour and shape § ACT-27) takes
|
||||
* `ItemSelectedShape`'s 12px corner in tertiary-container; `current` — a menu of places rather
|
||||
* than choices — takes the same 12px corner in secondary-container, the navigation-indicator
|
||||
* role. `description` (`ItemSupportingTextFont`) grows the row by 8px top and bottom; `shortcut`
|
||||
* (`ItemTrailingSupportingTextFont`) sits at the end. Every quiet part of the row — the icon, the
|
||||
* description, the trailing text — inks together as `--md-menu-item-ink`; corner and colour are
|
||||
* two springs, not one (§ ACT-19), and `icon-class` paints only the leading icon, over that ink
|
||||
* but never over disabled. The row renders the foundation's `md-state-layer` and `md-focus-ring`
|
||||
* item height" wins over the token's own 44dp `Item`), 16px either side
|
||||
* (`ItemLeadingSpace`/`ItemTrailingSpace`), 12px between the icon, the label and the trailing
|
||||
* content (`ItemBetweenSpace`, off the 8dp grid), 4px corners (`ItemShape`) that open to 12px at
|
||||
* either end of the list (`ItemFirstChildShape`/`ItemLastChildShape` — the library's own list
|
||||
* ends, 12px, win over `GroupShape`'s 8dp so a cluster's ends and a list's ends match,
|
||||
* menu-group.css). A selected row (`role="menuitemcheckbox"`, the tick beside the colour and
|
||||
* shape) takes `ItemSelectedShape`'s 12px corner in tertiary-container; `current` — a menu of
|
||||
* places rather than choices — takes the same 12px corner in secondary-container, the
|
||||
* navigation-indicator role. `description` (`ItemSupportingTextFont`) grows the row by 8px top
|
||||
* and bottom; `shortcut` (`ItemTrailingSupportingTextFont`) sits at the end. Every quiet part of
|
||||
* the row — the icon, the description, the trailing text — inks together as
|
||||
* `--md-menu-item-ink`; corner and colour are two springs, not one — a colour must never
|
||||
* overshoot — and `icon-class` paints only the leading icon, over that ink but never over
|
||||
* disabled. The row renders the foundation's `md-state-layer` and `md-focus-ring`
|
||||
* (foundation/interaction.css) — no `md-touch-target`, since the row is already 48px tall — and
|
||||
* keeps only one refinement: the ring reads inward (-3px), because a row sits edge to edge in the
|
||||
* list and an outward one would run past it. A disabled item stays focusable and keeps its ring,
|
||||
@@ -36,6 +36,7 @@
|
||||
|
||||
@import './icon.css';
|
||||
@import './badge.css';
|
||||
@import './menu.css';
|
||||
|
||||
@layer material.components {
|
||||
[data-md-menu-item] {
|
||||
@@ -145,40 +146,13 @@
|
||||
}
|
||||
|
||||
/* The submenu popover: a menu of its own, sharing the container colour of the list it opens
|
||||
from. The fallbacks are the standard menu's, for a submenu inside some other list. */
|
||||
from. Its size, radius, padding, shadow and pop-and-fade entry/exit are menu.css's shared
|
||||
popover chrome (imported above); only its axis and its position are its own — inline,
|
||||
beside the item, rather than the standard menu's block axis under its trigger. */
|
||||
[data-md-submenu] {
|
||||
inset: auto;
|
||||
margin: 0;
|
||||
margin-inline: var(--md-sys-measurement-space50);
|
||||
min-inline-size: 112px;
|
||||
max-inline-size: 280px;
|
||||
max-block-size: min(288px, calc(100dvh - 32px));
|
||||
overflow-y: auto;
|
||||
border-width: 0;
|
||||
border-radius: var(--md-sys-shape-corner-lg);
|
||||
padding: var(--md-sys-measurement-space50);
|
||||
background-color: var(--material-menu-surface, var(--md-sys-color-surface-container-low));
|
||||
color: var(--material-menu-ink, var(--md-sys-color-on-surface));
|
||||
box-shadow: var(--md-sys-elevation-2);
|
||||
margin: 0 var(--md-sys-measurement-space50);
|
||||
transform-origin: top;
|
||||
position-area: inline-end span-block-end;
|
||||
position-try-fallbacks: flip-inline;
|
||||
opacity: 0;
|
||||
scale: 0.95;
|
||||
transition-property: opacity, scale;
|
||||
transition-duration: var(--md-sys-motion-effects-fast-duration), var(--md-sys-motion-spatial-fast-duration);
|
||||
transition-timing-function: var(--md-sys-motion-effects-fast), var(--md-sys-motion-spatial-fast);
|
||||
|
||||
&:popover-open:not([data-md-popover-closing]) {
|
||||
opacity: 1;
|
||||
scale: 1;
|
||||
}
|
||||
|
||||
@starting-style {
|
||||
&:popover-open {
|
||||
opacity: 0;
|
||||
scale: 0.95;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
*
|
||||
* `[data-md-menu]` is `<x-menu>`'s root, holding the trigger and the popover; the popover itself
|
||||
* is `[data-md-menu-popover]`, capped at 288px so a long menu scrolls instead of running off the
|
||||
* top layer's edge (ACT-04), and transitions in by growing from its trigger's corner while it
|
||||
* fades, on the spatial and effects springs respectively (ACT-26). `data-md-vibrant` swaps its
|
||||
* top layer's edge, and transitions in by growing from its trigger's corner while it
|
||||
* fades, on the spatial and effects springs respectively. `data-md-vibrant` swaps its
|
||||
* container for tertiary-container; a nested submenu inherits the colour through
|
||||
* `--material-menu-surface`/`--material-menu-ink`, which the sheet's own copy of the list falls
|
||||
* back to instead (it is not a descendant of the popover).
|
||||
@@ -50,13 +50,14 @@
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
[data-md-menu-popover] {
|
||||
--material-menu-surface: var(--md-sys-color-surface-container-low);
|
||||
--material-menu-ink: var(--md-sys-color-on-surface);
|
||||
|
||||
/* The popover chrome a submenu shares (menu-item.css, which imports this file for it): size
|
||||
limits, the surface's own colour (a submenu with no ancestor popover falls back to the
|
||||
standard menu's own), radius, padding, shadow, and the pop-and-fade entry/exit — M3's
|
||||
effects-fast fade behind the spatial-fast scale. Each writes its own whole `margin`, so no
|
||||
rule here depends on which file a bundler puts first. */
|
||||
[data-md-menu-popover],
|
||||
[data-md-submenu] {
|
||||
inset: auto;
|
||||
margin: 0;
|
||||
margin-block: var(--md-sys-measurement-space50);
|
||||
min-inline-size: 112px;
|
||||
max-inline-size: 280px;
|
||||
max-block-size: min(288px, calc(100dvh - 32px));
|
||||
@@ -64,10 +65,9 @@
|
||||
border-width: 0;
|
||||
border-radius: var(--md-sys-shape-corner-lg);
|
||||
padding: var(--md-sys-measurement-space50);
|
||||
background-color: var(--material-menu-surface);
|
||||
color: var(--material-menu-ink);
|
||||
background-color: var(--material-menu-surface, var(--md-sys-color-surface-container-low));
|
||||
color: var(--material-menu-ink, var(--md-sys-color-on-surface));
|
||||
box-shadow: var(--md-sys-elevation-2);
|
||||
position-try-fallbacks: flip-block, flip-inline, flip-block flip-inline;
|
||||
opacity: 0;
|
||||
scale: 0.95;
|
||||
transition-property: opacity, scale;
|
||||
@@ -87,6 +87,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
[data-md-menu-popover] {
|
||||
--material-menu-surface: var(--md-sys-color-surface-container-low);
|
||||
--material-menu-ink: var(--md-sys-color-on-surface);
|
||||
|
||||
margin: var(--md-sys-measurement-space50) 0;
|
||||
position-try-fallbacks: flip-block, flip-inline, flip-block flip-inline;
|
||||
}
|
||||
|
||||
[data-md-menu-popover]:has(> [data-md-menu-filter]) {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
@@ -12,11 +12,11 @@
|
||||
*
|
||||
* 560/280px width (max/min), 48px scrim margin, 28px corner and 24dp padding all match the specs
|
||||
* page; a compact window's full-screen dialog swaps the box for the whole screen with a 56px bar
|
||||
* (C-17: this used to be 64px) instead of the headline block. It opens on the fast spatial spring
|
||||
* (this used to be 64px) instead of the headline block. It opens on the fast spatial spring
|
||||
* and closes at once — a native `<dialog>` makes an exit transition awkward, since
|
||||
* `@starting-style` only ever supplies an entry.
|
||||
*
|
||||
* The dividers (§ Dialogs → Anatomy, C-06): a 1px outline-variant rule under the pinned head and
|
||||
* The dividers (§ Dialogs → Anatomy): a 1px outline-variant rule under the pinned head and
|
||||
* over the pinned actions, each only while the body has more content hidden on its side.
|
||||
* resources/js/dialog.js marks the `<dialog>` with data-md-overflow-top/-bottom as the body
|
||||
* scrolls; `data-md-modal-divider` says an element takes part at all — the head and the actions
|
||||
@@ -53,6 +53,19 @@
|
||||
padding: 0;
|
||||
background-color: transparent;
|
||||
color: var(--md-sys-color-on-surface);
|
||||
}
|
||||
|
||||
/* Dialog chrome shared with the time picker's dialog and a modal date picker (timepicker.css,
|
||||
* datepicker.css, both import this file for it): M3's spatial-fast pop and a 32%-scrim
|
||||
* backdrop, entering only — a native `<dialog>` makes an exit transition awkward, since
|
||||
* `@starting-style` only ever supplies an entry. A plain selector list, not `:is()`: `:is()`
|
||||
* would flatten every branch to the specificity of `[data-md-datepicker-picker]:modal`, the
|
||||
* one with a pseudo-class, and outrank whatever else the modal or the time picker's dialog is
|
||||
* layered against.
|
||||
*/
|
||||
[data-md-modal],
|
||||
[data-md-timepicker-dialog],
|
||||
[data-md-datepicker-picker]:modal {
|
||||
opacity: 1;
|
||||
scale: 1;
|
||||
transition-property: opacity, scale;
|
||||
@@ -61,13 +74,17 @@
|
||||
}
|
||||
|
||||
@starting-style {
|
||||
[data-md-modal] {
|
||||
[data-md-modal],
|
||||
[data-md-timepicker-dialog],
|
||||
[data-md-datepicker-picker]:modal {
|
||||
opacity: 0;
|
||||
scale: 0.95;
|
||||
}
|
||||
}
|
||||
|
||||
[data-md-modal]::backdrop {
|
||||
[data-md-modal]::backdrop,
|
||||
[data-md-timepicker-dialog]::backdrop,
|
||||
[data-md-datepicker-picker]:modal::backdrop {
|
||||
background-color: color-mix(in srgb, var(--md-sys-color-scrim) 32%, transparent);
|
||||
}
|
||||
|
||||
@@ -100,7 +117,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
/* The phone-only header bar: M3's full-screen dialog header, 56dp (C-17). */
|
||||
/* The phone-only header bar: M3's full-screen dialog header, 56dp. */
|
||||
[data-md-modal-bar] {
|
||||
display: flex;
|
||||
height: var(--md-sys-measurement-space700);
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* wide. From 600px icon and label share a 40px horizontal indicator with 16px leading and
|
||||
* trailing space; the label stays label-medium — `NavigationBarTokens.LabelTextFont` is the bar's
|
||||
* only label token, and Compose's `ShortNavigationBarItem` passes it for both icon positions (the
|
||||
* *rail's* horizontal item is label-large, a different component's token; N-08). An active item is
|
||||
* *rail's* horizontal item is label-large, a different component's token). An active item is
|
||||
* secondary-container behind on-secondary-container (icon and, from 600px, label); its indicator's
|
||||
* fill is a background image so it can grow from its centre (navigation-item.css) rather than
|
||||
* stretch the icon.
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* `NavigationRailColorTokens.kt` gives one colour for all six states, active or not:
|
||||
* `ItemActiveHoveredStateLayer = … = ItemInactivePressedStateLayer = OnSecondaryContainer`.
|
||||
* `NavigationBarTokens.kt` states no state-layer tokens of its own, so the bar's item takes the
|
||||
* rail's (N-19). Hover only where a pointer can hover, so a touch screen does not keep the last
|
||||
* rail's. Hover only where a pointer can hover, so a touch screen does not keep the last
|
||||
* hover after a tap; state.css's own opacities (8% hover, 10% focus and press) rather than the
|
||||
* package's `md-state-layer` class, because the element focused and pressed is the whole item
|
||||
* while the layer is drawn only on the smaller indicator or pill inside it — `md-state-layer`
|
||||
|
||||
@@ -108,14 +108,7 @@
|
||||
/* ---- Collapsed: icon over label, the 56×32 indicator, badge back on the icon. ---- */
|
||||
|
||||
[data-md-navigation-rail-item] {
|
||||
&:where(
|
||||
[data-md-navigation-rail='collapsed'],
|
||||
[data-md-navigation-rail='collapsed'] *,
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='collapsible']:not([data-md-open]),
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='collapsible']:not([data-md-open]) *,
|
||||
[data-md-navigation-rail='modal']:not([data-md-open]),
|
||||
[data-md-navigation-rail='modal']:not([data-md-open]) *
|
||||
) {
|
||||
@container style(--md-navigation-rail-value: collapsed) {
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
gap: 4px;
|
||||
@@ -127,136 +120,13 @@
|
||||
font: var(--md-sys-typescale-label-md);
|
||||
letter-spacing: var(--md-sys-typescale-label-md-tracking);
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
@media (width < 600px) {
|
||||
&:where([data-md-navigation-rail='collapsible']:not([data-md-open]), [data-md-navigation-rail='collapsible']:not([data-md-open]) *) {
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
gap: 4px;
|
||||
height: auto;
|
||||
min-height: 64px;
|
||||
margin-inline: 0;
|
||||
padding: 6px 4px;
|
||||
border-radius: 0;
|
||||
font: var(--md-sys-typescale-label-md);
|
||||
letter-spacing: var(--md-sys-typescale-label-md-tracking);
|
||||
white-space: normal;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width < 840px) {
|
||||
&:where([data-md-navigation-rail='adaptive']:not([data-md-open]), [data-md-navigation-rail='adaptive']:not([data-md-open]) *) {
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
gap: 4px;
|
||||
height: auto;
|
||||
min-height: 64px;
|
||||
margin-inline: 0;
|
||||
padding: 6px 4px;
|
||||
border-radius: 0;
|
||||
font: var(--md-sys-typescale-label-md);
|
||||
letter-spacing: var(--md-sys-typescale-label-md-tracking);
|
||||
white-space: normal;
|
||||
}
|
||||
}
|
||||
|
||||
@media (840px <= width < 1200px) {
|
||||
&:where(
|
||||
:is([data-rail='collapsed'], [data-rail-auto]) [data-md-navigation-rail='adaptive']:not([data-md-open]),
|
||||
:is([data-rail='collapsed'], [data-rail-auto]) [data-md-navigation-rail='adaptive']:not([data-md-open]) *
|
||||
) {
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
gap: 4px;
|
||||
height: auto;
|
||||
min-height: 64px;
|
||||
margin-inline: 0;
|
||||
padding: 6px 4px;
|
||||
border-radius: 0;
|
||||
font: var(--md-sys-typescale-label-md);
|
||||
letter-spacing: var(--md-sys-typescale-label-md-tracking);
|
||||
white-space: normal;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width >= 1200px) {
|
||||
&:where(
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='adaptive']:not([data-md-open]),
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='adaptive']:not([data-md-open]) *
|
||||
) {
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
gap: 4px;
|
||||
height: auto;
|
||||
min-height: 64px;
|
||||
margin-inline: 0;
|
||||
padding: 6px 4px;
|
||||
border-radius: 0;
|
||||
font: var(--md-sys-typescale-label-md);
|
||||
letter-spacing: var(--md-sys-typescale-label-md-tracking);
|
||||
white-space: normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[data-md-navigation-rail-item] {
|
||||
&:where(
|
||||
[data-md-navigation-rail='collapsed'],
|
||||
[data-md-navigation-rail='collapsed'] *,
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='collapsible']:not([data-md-open]),
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='collapsible']:not([data-md-open]) *,
|
||||
[data-md-navigation-rail='modal']:not([data-md-open]),
|
||||
[data-md-navigation-rail='modal']:not([data-md-open]) *
|
||||
) {
|
||||
--navigation-item-layer: 0;
|
||||
--navigation-indicator-layer: var(--navigation-layer);
|
||||
}
|
||||
|
||||
@media (width < 600px) {
|
||||
&:where([data-md-navigation-rail='collapsible']:not([data-md-open]), [data-md-navigation-rail='collapsible']:not([data-md-open]) *) {
|
||||
--navigation-item-layer: 0;
|
||||
--navigation-indicator-layer: var(--navigation-layer);
|
||||
}
|
||||
}
|
||||
|
||||
@media (width < 840px) {
|
||||
&:where([data-md-navigation-rail='adaptive']:not([data-md-open]), [data-md-navigation-rail='adaptive']:not([data-md-open]) *) {
|
||||
--navigation-item-layer: 0;
|
||||
--navigation-indicator-layer: var(--navigation-layer);
|
||||
}
|
||||
}
|
||||
|
||||
@media (840px <= width < 1200px) {
|
||||
&:where(
|
||||
:is([data-rail='collapsed'], [data-rail-auto]) [data-md-navigation-rail='adaptive']:not([data-md-open]),
|
||||
:is([data-rail='collapsed'], [data-rail-auto]) [data-md-navigation-rail='adaptive']:not([data-md-open]) *
|
||||
) {
|
||||
--navigation-item-layer: 0;
|
||||
--navigation-indicator-layer: var(--navigation-layer);
|
||||
}
|
||||
}
|
||||
|
||||
@media (width >= 1200px) {
|
||||
&:where(
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='adaptive']:not([data-md-open]),
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='adaptive']:not([data-md-open]) *
|
||||
) {
|
||||
--navigation-item-layer: 0;
|
||||
--navigation-indicator-layer: var(--navigation-layer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[data-md-navigation-rail-item] [data-md-navigation-label] {
|
||||
&:where(
|
||||
[data-md-navigation-rail='collapsed'],
|
||||
[data-md-navigation-rail='collapsed'] *,
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='collapsible']:not([data-md-open]),
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='collapsible']:not([data-md-open]) *,
|
||||
[data-md-navigation-rail='modal']:not([data-md-open]),
|
||||
[data-md-navigation-rail='modal']:not([data-md-open]) *
|
||||
) {
|
||||
@container style(--md-navigation-rail-value: collapsed) {
|
||||
flex: none;
|
||||
display: -webkit-box;
|
||||
max-width: 100%;
|
||||
@@ -265,381 +135,52 @@
|
||||
text-align: center;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
@media (width < 600px) {
|
||||
&:where([data-md-navigation-rail='collapsible']:not([data-md-open]), [data-md-navigation-rail='collapsible']:not([data-md-open]) *) {
|
||||
flex: none;
|
||||
display: -webkit-box;
|
||||
max-width: 100%;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
text-align: center;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width < 840px) {
|
||||
&:where([data-md-navigation-rail='adaptive']:not([data-md-open]), [data-md-navigation-rail='adaptive']:not([data-md-open]) *) {
|
||||
flex: none;
|
||||
display: -webkit-box;
|
||||
max-width: 100%;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
text-align: center;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
}
|
||||
|
||||
@media (840px <= width < 1200px) {
|
||||
&:where(
|
||||
:is([data-rail='collapsed'], [data-rail-auto]) [data-md-navigation-rail='adaptive']:not([data-md-open]),
|
||||
:is([data-rail='collapsed'], [data-rail-auto]) [data-md-navigation-rail='adaptive']:not([data-md-open]) *
|
||||
) {
|
||||
flex: none;
|
||||
display: -webkit-box;
|
||||
max-width: 100%;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
text-align: center;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width >= 1200px) {
|
||||
&:where(
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='adaptive']:not([data-md-open]),
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='adaptive']:not([data-md-open]) *
|
||||
) {
|
||||
flex: none;
|
||||
display: -webkit-box;
|
||||
max-width: 100%;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
text-align: center;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[data-md-navigation-rail-item][data-md-active] {
|
||||
&:where(
|
||||
[data-md-navigation-rail='collapsed'],
|
||||
[data-md-navigation-rail='collapsed'] *,
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='collapsible']:not([data-md-open]),
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='collapsible']:not([data-md-open]) *,
|
||||
[data-md-navigation-rail='modal']:not([data-md-open]),
|
||||
[data-md-navigation-rail='modal']:not([data-md-open]) *
|
||||
) {
|
||||
@container style(--md-navigation-rail-value: collapsed) {
|
||||
background-image: none;
|
||||
color: var(--md-sys-color-secondary);
|
||||
}
|
||||
|
||||
@media (width < 600px) {
|
||||
&:where([data-md-navigation-rail='collapsible']:not([data-md-open]), [data-md-navigation-rail='collapsible']:not([data-md-open]) *) {
|
||||
background-image: none;
|
||||
color: var(--md-sys-color-secondary);
|
||||
}
|
||||
}
|
||||
|
||||
@media (width < 840px) {
|
||||
&:where([data-md-navigation-rail='adaptive']:not([data-md-open]), [data-md-navigation-rail='adaptive']:not([data-md-open]) *) {
|
||||
background-image: none;
|
||||
color: var(--md-sys-color-secondary);
|
||||
}
|
||||
}
|
||||
|
||||
@media (840px <= width < 1200px) {
|
||||
&:where(
|
||||
:is([data-rail='collapsed'], [data-rail-auto]) [data-md-navigation-rail='adaptive']:not([data-md-open]),
|
||||
:is([data-rail='collapsed'], [data-rail-auto]) [data-md-navigation-rail='adaptive']:not([data-md-open]) *
|
||||
) {
|
||||
background-image: none;
|
||||
color: var(--md-sys-color-secondary);
|
||||
}
|
||||
}
|
||||
|
||||
@media (width >= 1200px) {
|
||||
&:where(
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='adaptive']:not([data-md-open]),
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='adaptive']:not([data-md-open]) *
|
||||
) {
|
||||
background-image: none;
|
||||
color: var(--md-sys-color-secondary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[data-md-navigation-rail-item] [data-md-navigation-indicator] {
|
||||
&:where(
|
||||
[data-md-navigation-rail='collapsed'],
|
||||
[data-md-navigation-rail='collapsed'] *,
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='collapsible']:not([data-md-open]),
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='collapsible']:not([data-md-open]) *,
|
||||
[data-md-navigation-rail='modal']:not([data-md-open]),
|
||||
[data-md-navigation-rail='modal']:not([data-md-open]) *
|
||||
) {
|
||||
@container style(--md-navigation-rail-value: collapsed) {
|
||||
width: 56px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
@media (width < 600px) {
|
||||
&:where([data-md-navigation-rail='collapsible']:not([data-md-open]), [data-md-navigation-rail='collapsible']:not([data-md-open]) *) {
|
||||
width: 56px;
|
||||
height: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width < 840px) {
|
||||
&:where([data-md-navigation-rail='adaptive']:not([data-md-open]), [data-md-navigation-rail='adaptive']:not([data-md-open]) *) {
|
||||
width: 56px;
|
||||
height: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (840px <= width < 1200px) {
|
||||
&:where(
|
||||
:is([data-rail='collapsed'], [data-rail-auto]) [data-md-navigation-rail='adaptive']:not([data-md-open]),
|
||||
:is([data-rail='collapsed'], [data-rail-auto]) [data-md-navigation-rail='adaptive']:not([data-md-open]) *
|
||||
) {
|
||||
width: 56px;
|
||||
height: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width >= 1200px) {
|
||||
&:where(
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='adaptive']:not([data-md-open]),
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='adaptive']:not([data-md-open]) *
|
||||
) {
|
||||
width: 56px;
|
||||
height: 32px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[data-md-navigation-rail-item][data-md-active] [data-md-navigation-indicator] {
|
||||
&:where(
|
||||
[data-md-navigation-rail='collapsed'],
|
||||
[data-md-navigation-rail='collapsed'] *,
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='collapsible']:not([data-md-open]),
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='collapsible']:not([data-md-open]) *,
|
||||
[data-md-navigation-rail='modal']:not([data-md-open]),
|
||||
[data-md-navigation-rail='modal']:not([data-md-open]) *
|
||||
) {
|
||||
@container style(--md-navigation-rail-value: collapsed) {
|
||||
background-image: linear-gradient(var(--md-sys-color-secondary-container), var(--md-sys-color-secondary-container));
|
||||
color: var(--md-sys-color-on-secondary-container);
|
||||
}
|
||||
|
||||
@media (width < 600px) {
|
||||
&:where([data-md-navigation-rail='collapsible']:not([data-md-open]), [data-md-navigation-rail='collapsible']:not([data-md-open]) *) {
|
||||
background-image: linear-gradient(var(--md-sys-color-secondary-container), var(--md-sys-color-secondary-container));
|
||||
color: var(--md-sys-color-on-secondary-container);
|
||||
}
|
||||
}
|
||||
|
||||
@media (width < 840px) {
|
||||
&:where([data-md-navigation-rail='adaptive']:not([data-md-open]), [data-md-navigation-rail='adaptive']:not([data-md-open]) *) {
|
||||
background-image: linear-gradient(var(--md-sys-color-secondary-container), var(--md-sys-color-secondary-container));
|
||||
color: var(--md-sys-color-on-secondary-container);
|
||||
}
|
||||
}
|
||||
|
||||
@media (840px <= width < 1200px) {
|
||||
&:where(
|
||||
:is([data-rail='collapsed'], [data-rail-auto]) [data-md-navigation-rail='adaptive']:not([data-md-open]),
|
||||
:is([data-rail='collapsed'], [data-rail-auto]) [data-md-navigation-rail='adaptive']:not([data-md-open]) *
|
||||
) {
|
||||
background-image: linear-gradient(var(--md-sys-color-secondary-container), var(--md-sys-color-secondary-container));
|
||||
color: var(--md-sys-color-on-secondary-container);
|
||||
}
|
||||
}
|
||||
|
||||
@media (width >= 1200px) {
|
||||
&:where(
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='adaptive']:not([data-md-open]),
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='adaptive']:not([data-md-open]) *
|
||||
) {
|
||||
background-image: linear-gradient(var(--md-sys-color-secondary-container), var(--md-sys-color-secondary-container));
|
||||
color: var(--md-sys-color-on-secondary-container);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[data-md-navigation-rail-item]:focus-visible {
|
||||
&:where(
|
||||
[data-md-navigation-rail='collapsed'],
|
||||
[data-md-navigation-rail='collapsed'] *,
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='collapsible']:not([data-md-open]),
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='collapsible']:not([data-md-open]) *,
|
||||
[data-md-navigation-rail='modal']:not([data-md-open]),
|
||||
[data-md-navigation-rail='modal']:not([data-md-open]) *
|
||||
) {
|
||||
@container style(--md-navigation-rail-value: collapsed) {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
@media (width < 600px) {
|
||||
&:where([data-md-navigation-rail='collapsible']:not([data-md-open]), [data-md-navigation-rail='collapsible']:not([data-md-open]) *) {
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width < 840px) {
|
||||
&:where([data-md-navigation-rail='adaptive']:not([data-md-open]), [data-md-navigation-rail='adaptive']:not([data-md-open]) *) {
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (840px <= width < 1200px) {
|
||||
&:where(
|
||||
:is([data-rail='collapsed'], [data-rail-auto]) [data-md-navigation-rail='adaptive']:not([data-md-open]),
|
||||
:is([data-rail='collapsed'], [data-rail-auto]) [data-md-navigation-rail='adaptive']:not([data-md-open]) *
|
||||
) {
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width >= 1200px) {
|
||||
&:where(
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='adaptive']:not([data-md-open]),
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='adaptive']:not([data-md-open]) *
|
||||
) {
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[data-md-navigation-rail-item]:focus-visible [data-md-navigation-indicator] {
|
||||
&:where(
|
||||
[data-md-navigation-rail='collapsed'],
|
||||
[data-md-navigation-rail='collapsed'] *,
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='collapsible']:not([data-md-open]),
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='collapsible']:not([data-md-open]) *,
|
||||
[data-md-navigation-rail='modal']:not([data-md-open]),
|
||||
[data-md-navigation-rail='modal']:not([data-md-open]) *
|
||||
) {
|
||||
@container style(--md-navigation-rail-value: collapsed) {
|
||||
outline: 3px solid var(--md-sys-color-secondary);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
@media (width < 600px) {
|
||||
&:where([data-md-navigation-rail='collapsible']:not([data-md-open]), [data-md-navigation-rail='collapsible']:not([data-md-open]) *) {
|
||||
outline: 3px solid var(--md-sys-color-secondary);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width < 840px) {
|
||||
&:where([data-md-navigation-rail='adaptive']:not([data-md-open]), [data-md-navigation-rail='adaptive']:not([data-md-open]) *) {
|
||||
outline: 3px solid var(--md-sys-color-secondary);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (840px <= width < 1200px) {
|
||||
&:where(
|
||||
:is([data-rail='collapsed'], [data-rail-auto]) [data-md-navigation-rail='adaptive']:not([data-md-open]),
|
||||
:is([data-rail='collapsed'], [data-rail-auto]) [data-md-navigation-rail='adaptive']:not([data-md-open]) *
|
||||
) {
|
||||
outline: 3px solid var(--md-sys-color-secondary);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width >= 1200px) {
|
||||
&:where(
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='adaptive']:not([data-md-open]),
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='adaptive']:not([data-md-open]) *
|
||||
) {
|
||||
outline: 3px solid var(--md-sys-color-secondary);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[data-md-navigation-badge-end],
|
||||
[data-md-navigation-badge-icon] {
|
||||
&:where(
|
||||
[data-md-navigation-rail='collapsed'],
|
||||
[data-md-navigation-rail='collapsed'] *,
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='collapsible']:not([data-md-open]),
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='collapsible']:not([data-md-open]) *,
|
||||
[data-md-navigation-rail='modal']:not([data-md-open]),
|
||||
[data-md-navigation-rail='modal']:not([data-md-open]) *
|
||||
) {
|
||||
@container style(--md-navigation-rail-value: collapsed) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (width < 600px) {
|
||||
&:where([data-md-navigation-rail='collapsible']:not([data-md-open]), [data-md-navigation-rail='collapsible']:not([data-md-open]) *) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width < 840px) {
|
||||
&:where([data-md-navigation-rail='adaptive']:not([data-md-open]), [data-md-navigation-rail='adaptive']:not([data-md-open]) *) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (840px <= width < 1200px) {
|
||||
&:where(
|
||||
:is([data-rail='collapsed'], [data-rail-auto]) [data-md-navigation-rail='adaptive']:not([data-md-open]),
|
||||
:is([data-rail='collapsed'], [data-rail-auto]) [data-md-navigation-rail='adaptive']:not([data-md-open]) *
|
||||
) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width >= 1200px) {
|
||||
&:where(
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='adaptive']:not([data-md-open]),
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='adaptive']:not([data-md-open]) *
|
||||
) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[data-md-navigation-badge-icon] {
|
||||
&:where(
|
||||
[data-md-navigation-rail='collapsed'],
|
||||
[data-md-navigation-rail='collapsed'] *,
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='collapsible']:not([data-md-open]),
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='collapsible']:not([data-md-open]) *,
|
||||
[data-md-navigation-rail='modal']:not([data-md-open]),
|
||||
[data-md-navigation-rail='modal']:not([data-md-open]) *
|
||||
) {
|
||||
@container style(--md-navigation-rail-value: collapsed) {
|
||||
display: contents;
|
||||
}
|
||||
|
||||
@media (width < 600px) {
|
||||
&:where([data-md-navigation-rail='collapsible']:not([data-md-open]), [data-md-navigation-rail='collapsible']:not([data-md-open]) *) {
|
||||
display: contents;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width < 840px) {
|
||||
&:where([data-md-navigation-rail='adaptive']:not([data-md-open]), [data-md-navigation-rail='adaptive']:not([data-md-open]) *) {
|
||||
display: contents;
|
||||
}
|
||||
}
|
||||
|
||||
@media (840px <= width < 1200px) {
|
||||
&:where(
|
||||
:is([data-rail='collapsed'], [data-rail-auto]) [data-md-navigation-rail='adaptive']:not([data-md-open]),
|
||||
:is([data-rail='collapsed'], [data-rail-auto]) [data-md-navigation-rail='adaptive']:not([data-md-open]) *
|
||||
) {
|
||||
display: contents;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width >= 1200px) {
|
||||
&:where(
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='adaptive']:not([data-md-open]),
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='adaptive']:not([data-md-open]) *
|
||||
) {
|
||||
display: contents;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,46 +14,9 @@
|
||||
}
|
||||
|
||||
[data-md-navigation-rail-section]:not(:first-child) {
|
||||
&:where(
|
||||
[data-md-navigation-rail='collapsed'],
|
||||
[data-md-navigation-rail='collapsed'] *,
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='collapsible']:not([data-md-open]),
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='collapsible']:not([data-md-open]) *,
|
||||
[data-md-navigation-rail='modal']:not([data-md-open]),
|
||||
[data-md-navigation-rail='modal']:not([data-md-open]) *
|
||||
) {
|
||||
@container style(--md-navigation-rail-value: collapsed) {
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
@media (width < 600px) {
|
||||
&:where([data-md-navigation-rail='collapsible']:not([data-md-open]), [data-md-navigation-rail='collapsible']:not([data-md-open]) *) {
|
||||
margin-top: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width < 840px) {
|
||||
&:where([data-md-navigation-rail='adaptive']:not([data-md-open]), [data-md-navigation-rail='adaptive']:not([data-md-open]) *) {
|
||||
margin-top: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (840px <= width < 1200px) {
|
||||
&:where(
|
||||
:is([data-rail='collapsed'], [data-rail-auto]) [data-md-navigation-rail='adaptive']:not([data-md-open]),
|
||||
:is([data-rail='collapsed'], [data-rail-auto]) [data-md-navigation-rail='adaptive']:not([data-md-open]) *
|
||||
) {
|
||||
margin-top: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width >= 1200px) {
|
||||
&:where(
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='adaptive']:not([data-md-open]),
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='adaptive']:not([data-md-open]) *
|
||||
) {
|
||||
margin-top: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[data-md-navigation-rail-heading] {
|
||||
@@ -67,48 +30,9 @@
|
||||
letter-spacing: var(--md-sys-typescale-title-sm-tracking);
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
[data-md-navigation-rail-heading] {
|
||||
&:where(
|
||||
[data-md-navigation-rail='collapsed'],
|
||||
[data-md-navigation-rail='collapsed'] *,
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='collapsible']:not([data-md-open]),
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='collapsible']:not([data-md-open]) *,
|
||||
[data-md-navigation-rail='modal']:not([data-md-open]),
|
||||
[data-md-navigation-rail='modal']:not([data-md-open]) *
|
||||
) {
|
||||
@container style(--md-navigation-rail-value: collapsed) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (width < 600px) {
|
||||
&:where([data-md-navigation-rail='collapsible']:not([data-md-open]), [data-md-navigation-rail='collapsible']:not([data-md-open]) *) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width < 840px) {
|
||||
&:where([data-md-navigation-rail='adaptive']:not([data-md-open]), [data-md-navigation-rail='adaptive']:not([data-md-open]) *) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (840px <= width < 1200px) {
|
||||
&:where(
|
||||
:is([data-rail='collapsed'], [data-rail-auto]) [data-md-navigation-rail='adaptive']:not([data-md-open]),
|
||||
:is([data-rail='collapsed'], [data-rail-auto]) [data-md-navigation-rail='adaptive']:not([data-md-open]) *
|
||||
) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width >= 1200px) {
|
||||
&:where(
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='adaptive']:not([data-md-open]),
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='adaptive']:not([data-md-open]) *
|
||||
) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
* [data-md-navigation-rail-item] navigation-rail-item.css
|
||||
* [data-md-navigation-rail-footer] never scrolls
|
||||
*
|
||||
* **Collapsed**: a rail (and anything in it) is drawn collapsed while any of these hold, each its
|
||||
* own rule below wherever a property differs by shape — a fixed `collapsed` mode; a `collapsible` rail the visitor collapsed
|
||||
* **Collapsed**: a rail (and anything in it) is drawn collapsed while any of these hold, which the
|
||||
* rail's own two rules below publish as `--md-navigation-rail-value` for everything inside it — a fixed `collapsed` mode; a `collapsible` rail the visitor collapsed
|
||||
* (`<html data-rail="collapsed">`, set before the first paint by `<x-theme-script>`) and not
|
||||
* currently open over the page; a `modal` rail not open; below `medium` (600px) a `collapsible`
|
||||
* rail regardless of choice, M3's floor ("compact → use a navigation bar, not a standard rail");
|
||||
@@ -56,14 +56,14 @@
|
||||
*
|
||||
* `data-md-divider` and `data-md-fill="false"` are both Missing until this rewrite: an optional
|
||||
* vertical divider on the page's edge, M3's own answer to a page scrolling under a fixed rail, and
|
||||
* a transparent container as long as the items keep 3:1 contrast (N-22). `data-md-align="center"`
|
||||
* a transparent container as long as the items keep 3:1 contrast. `data-md-align="center"`
|
||||
* is M3's other alignment, preferred on a tablet for reach — only the destinations move; the
|
||||
* header, footer and menu button stay at their ends, and `safe` gives the top back once there are
|
||||
* more destinations than fit.
|
||||
*
|
||||
* The rail-header FAB rules at the end draw M3's nested-FAB elevation (level 0, not a standalone
|
||||
* FAB's 3 — N-03) and morph it into an extended FAB as the rail opens, rather than swapping two by
|
||||
* `display` (N-23). Both sit in this file's own `material.components` layer and win by specificity
|
||||
* FAB's 3) and morph it into an extended FAB as the rail opens, rather than swapping two by
|
||||
* `display`. Both sit in this file's own `material.components` layer and win by specificity
|
||||
* alone, whichever copy of fab.css a build places last: the flat shadow outranks fab.css's resting
|
||||
* and hover shadows, and the collapsed FAB's `gap` and minimum width outrank fab.css's extended-size
|
||||
* and collapse-on-scroll rules, which would otherwise tie with them.
|
||||
@@ -187,14 +187,7 @@
|
||||
alone; the label is taken out of the drawing, not out of the page (navigation-rail-item.css
|
||||
renders it always — it is what names the destination). */
|
||||
[data-md-navigation-rail][data-md-width='narrow'] [data-md-navigation-rail-item] [data-md-navigation-label] {
|
||||
&:where(
|
||||
[data-md-navigation-rail='collapsed'],
|
||||
[data-md-navigation-rail='collapsed'] *,
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='collapsible']:not([data-md-open]),
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='collapsible']:not([data-md-open]) *,
|
||||
[data-md-navigation-rail='modal']:not([data-md-open]),
|
||||
[data-md-navigation-rail='modal']:not([data-md-open]) *
|
||||
) {
|
||||
@container style(--md-navigation-rail-value: collapsed) {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
@@ -204,64 +197,6 @@
|
||||
clip-path: inset(50%);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@media (width < 600px) {
|
||||
&:where([data-md-navigation-rail='collapsible']:not([data-md-open]), [data-md-navigation-rail='collapsible']:not([data-md-open]) *) {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
padding: 0;
|
||||
margin: -1px;
|
||||
overflow: hidden;
|
||||
clip-path: inset(50%);
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width < 840px) {
|
||||
&:where([data-md-navigation-rail='adaptive']:not([data-md-open]), [data-md-navigation-rail='adaptive']:not([data-md-open]) *) {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
padding: 0;
|
||||
margin: -1px;
|
||||
overflow: hidden;
|
||||
clip-path: inset(50%);
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
@media (840px <= width < 1200px) {
|
||||
&:where(
|
||||
:is([data-rail='collapsed'], [data-rail-auto]) [data-md-navigation-rail='adaptive']:not([data-md-open]),
|
||||
:is([data-rail='collapsed'], [data-rail-auto]) [data-md-navigation-rail='adaptive']:not([data-md-open]) *
|
||||
) {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
padding: 0;
|
||||
margin: -1px;
|
||||
overflow: hidden;
|
||||
clip-path: inset(50%);
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width >= 1200px) {
|
||||
&:where(
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='adaptive']:not([data-md-open]),
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='adaptive']:not([data-md-open]) *
|
||||
) {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
padding: 0;
|
||||
margin: -1px;
|
||||
overflow: hidden;
|
||||
clip-path: inset(50%);
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* A modal rail keeps its collapsed width in the layout while it is open over it, as Compose's
|
||||
@@ -284,7 +219,7 @@
|
||||
|
||||
/* "Compact → don't use a standard rail, use a navigation bar." A `collapsible` rail takes
|
||||
the width the visitor chose, which on a 360px screen would be two-thirds of it, so it is
|
||||
floored at its collapsed width (N-24). `collapsed` and `expanded` mean what they say and
|
||||
floored at its collapsed width. `collapsed` and `expanded` mean what they say and
|
||||
are left alone: wrap one in an application's own `medium:` element if it must not show
|
||||
on a phone. */
|
||||
[data-md-navigation-rail='collapsible'] {
|
||||
@@ -315,7 +250,7 @@
|
||||
/* M3's two optional container treatments: "optional vertical divider separates rail from
|
||||
content, placed on the content-adjacent edge" — also its answer to a page scrolling under a
|
||||
fixed rail — and "container fill can be turned off (transparent) as long as items keep ≥3:1
|
||||
contrast" (N-22). Neither applies to a rail open over a scrim, a surface over the page. */
|
||||
contrast". Neither applies to a rail open over a scrim, a surface over the page. */
|
||||
[data-md-navigation-rail][data-md-divider]:not([data-md-open], [data-md-closing='sheet']) > [data-md-navigation-rail-panel] {
|
||||
border-inline-end: 1px solid var(--md-sys-color-outline-variant);
|
||||
}
|
||||
@@ -393,14 +328,7 @@
|
||||
the collapsed branches, which stop the moment the rail is open — that is what makes it the
|
||||
expanded rail that comes back, on the unconditional rule below. */
|
||||
[data-md-navigation-rail][data-md-hide-when-collapsed] > [data-md-navigation-rail-panel] {
|
||||
&:where(
|
||||
[data-md-navigation-rail='collapsed'],
|
||||
[data-md-navigation-rail='collapsed'] *,
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='collapsible']:not([data-md-open]),
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='collapsible']:not([data-md-open]) *,
|
||||
[data-md-navigation-rail='modal']:not([data-md-open]),
|
||||
[data-md-navigation-rail='modal']:not([data-md-open]) *
|
||||
) {
|
||||
@container style(--md-navigation-rail-value: collapsed) {
|
||||
display: none;
|
||||
translate: -100% 0;
|
||||
transition:
|
||||
@@ -410,64 +338,6 @@
|
||||
translate: 100% 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width < 600px) {
|
||||
&:where([data-md-navigation-rail='collapsible']:not([data-md-open]), [data-md-navigation-rail='collapsible']:not([data-md-open]) *) {
|
||||
display: none;
|
||||
translate: -100% 0;
|
||||
transition:
|
||||
translate var(--md-sys-motion-effects-default-duration) var(--md-sys-motion-easing-emphasized-accelerate);
|
||||
|
||||
&:is([dir='rtl'], [dir='rtl'] *) {
|
||||
translate: 100% 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (width < 840px) {
|
||||
&:where([data-md-navigation-rail='adaptive']:not([data-md-open]), [data-md-navigation-rail='adaptive']:not([data-md-open]) *) {
|
||||
display: none;
|
||||
translate: -100% 0;
|
||||
transition:
|
||||
translate var(--md-sys-motion-effects-default-duration) var(--md-sys-motion-easing-emphasized-accelerate);
|
||||
|
||||
&:is([dir='rtl'], [dir='rtl'] *) {
|
||||
translate: 100% 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (840px <= width < 1200px) {
|
||||
&:where(
|
||||
:is([data-rail='collapsed'], [data-rail-auto]) [data-md-navigation-rail='adaptive']:not([data-md-open]),
|
||||
:is([data-rail='collapsed'], [data-rail-auto]) [data-md-navigation-rail='adaptive']:not([data-md-open]) *
|
||||
) {
|
||||
display: none;
|
||||
translate: -100% 0;
|
||||
transition:
|
||||
translate var(--md-sys-motion-effects-default-duration) var(--md-sys-motion-easing-emphasized-accelerate);
|
||||
|
||||
&:is([dir='rtl'], [dir='rtl'] *) {
|
||||
translate: 100% 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (width >= 1200px) {
|
||||
&:where(
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='adaptive']:not([data-md-open]),
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='adaptive']:not([data-md-open]) *
|
||||
) {
|
||||
display: none;
|
||||
translate: -100% 0;
|
||||
transition:
|
||||
translate var(--md-sys-motion-effects-default-duration) var(--md-sys-motion-easing-emphasized-accelerate);
|
||||
|
||||
&:is([dir='rtl'], [dir='rtl'] *) {
|
||||
translate: 100% 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[data-md-navigation-rail][data-md-hide-when-collapsed][data-md-open] > [data-md-navigation-rail-panel] {
|
||||
@@ -591,46 +461,9 @@
|
||||
}
|
||||
|
||||
[data-md-navigation-rail][data-md-width='narrow'] [data-md-navigation-rail-header]:has([data-md-navigation-rail-menu]) [data-md-navigation-rail-menu-row] {
|
||||
&:where(
|
||||
[data-md-navigation-rail='collapsed'],
|
||||
[data-md-navigation-rail='collapsed'] *,
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='collapsible']:not([data-md-open]),
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='collapsible']:not([data-md-open]) *,
|
||||
[data-md-navigation-rail='modal']:not([data-md-open]),
|
||||
[data-md-navigation-rail='modal']:not([data-md-open]) *
|
||||
) {
|
||||
@container style(--md-navigation-rail-value: collapsed) {
|
||||
padding-inline-start: 20px;
|
||||
}
|
||||
|
||||
@media (width < 600px) {
|
||||
&:where([data-md-navigation-rail='collapsible']:not([data-md-open]), [data-md-navigation-rail='collapsible']:not([data-md-open]) *) {
|
||||
padding-inline-start: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width < 840px) {
|
||||
&:where([data-md-navigation-rail='adaptive']:not([data-md-open]), [data-md-navigation-rail='adaptive']:not([data-md-open]) *) {
|
||||
padding-inline-start: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (840px <= width < 1200px) {
|
||||
&:where(
|
||||
:is([data-rail='collapsed'], [data-rail-auto]) [data-md-navigation-rail='adaptive']:not([data-md-open]),
|
||||
:is([data-rail='collapsed'], [data-rail-auto]) [data-md-navigation-rail='adaptive']:not([data-md-open]) *
|
||||
) {
|
||||
padding-inline-start: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width >= 1200px) {
|
||||
&:where(
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='adaptive']:not([data-md-open]),
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='adaptive']:not([data-md-open]) *
|
||||
) {
|
||||
padding-inline-start: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[data-md-navigation-rail-menu] {
|
||||
@@ -658,137 +491,24 @@
|
||||
|
||||
[data-md-navigation-rail-menu-collapse-icon],
|
||||
[data-md-navigation-rail-menu-expand-icon] {
|
||||
&:where(
|
||||
[data-md-navigation-rail='collapsed'],
|
||||
[data-md-navigation-rail='collapsed'] *,
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='collapsible']:not([data-md-open]),
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='collapsible']:not([data-md-open]) *,
|
||||
[data-md-navigation-rail='modal']:not([data-md-open]),
|
||||
[data-md-navigation-rail='modal']:not([data-md-open]) *
|
||||
) {
|
||||
@container style(--md-navigation-rail-value: collapsed) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (width < 600px) {
|
||||
&:where([data-md-navigation-rail='collapsible']:not([data-md-open]), [data-md-navigation-rail='collapsible']:not([data-md-open]) *) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width < 840px) {
|
||||
&:where([data-md-navigation-rail='adaptive']:not([data-md-open]), [data-md-navigation-rail='adaptive']:not([data-md-open]) *) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (840px <= width < 1200px) {
|
||||
&:where(
|
||||
:is([data-rail='collapsed'], [data-rail-auto]) [data-md-navigation-rail='adaptive']:not([data-md-open]),
|
||||
:is([data-rail='collapsed'], [data-rail-auto]) [data-md-navigation-rail='adaptive']:not([data-md-open]) *
|
||||
) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width >= 1200px) {
|
||||
&:where(
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='adaptive']:not([data-md-open]),
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='adaptive']:not([data-md-open]) *
|
||||
) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[data-md-navigation-rail-menu-expand-icon] {
|
||||
&:where(
|
||||
[data-md-navigation-rail='collapsed'],
|
||||
[data-md-navigation-rail='collapsed'] *,
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='collapsible']:not([data-md-open]),
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='collapsible']:not([data-md-open]) *,
|
||||
[data-md-navigation-rail='modal']:not([data-md-open]),
|
||||
[data-md-navigation-rail='modal']:not([data-md-open]) *
|
||||
) {
|
||||
@container style(--md-navigation-rail-value: collapsed) {
|
||||
display: contents;
|
||||
}
|
||||
|
||||
@media (width < 600px) {
|
||||
&:where([data-md-navigation-rail='collapsible']:not([data-md-open]), [data-md-navigation-rail='collapsible']:not([data-md-open]) *) {
|
||||
display: contents;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width < 840px) {
|
||||
&:where([data-md-navigation-rail='adaptive']:not([data-md-open]), [data-md-navigation-rail='adaptive']:not([data-md-open]) *) {
|
||||
display: contents;
|
||||
}
|
||||
}
|
||||
|
||||
@media (840px <= width < 1200px) {
|
||||
&:where(
|
||||
:is([data-rail='collapsed'], [data-rail-auto]) [data-md-navigation-rail='adaptive']:not([data-md-open]),
|
||||
:is([data-rail='collapsed'], [data-rail-auto]) [data-md-navigation-rail='adaptive']:not([data-md-open]) *
|
||||
) {
|
||||
display: contents;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width >= 1200px) {
|
||||
&:where(
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='adaptive']:not([data-md-open]),
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='adaptive']:not([data-md-open]) *
|
||||
) {
|
||||
display: contents;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[data-md-navigation-rail-brand] {
|
||||
min-width: 0;
|
||||
flex: 1 1 0%;
|
||||
}
|
||||
|
||||
[data-md-navigation-rail-brand] {
|
||||
&:where(
|
||||
[data-md-navigation-rail='collapsed'],
|
||||
[data-md-navigation-rail='collapsed'] *,
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='collapsible']:not([data-md-open]),
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='collapsible']:not([data-md-open]) *,
|
||||
[data-md-navigation-rail='modal']:not([data-md-open]),
|
||||
[data-md-navigation-rail='modal']:not([data-md-open]) *
|
||||
) {
|
||||
@container style(--md-navigation-rail-value: collapsed) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (width < 600px) {
|
||||
&:where([data-md-navigation-rail='collapsible']:not([data-md-open]), [data-md-navigation-rail='collapsible']:not([data-md-open]) *) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width < 840px) {
|
||||
&:where([data-md-navigation-rail='adaptive']:not([data-md-open]), [data-md-navigation-rail='adaptive']:not([data-md-open]) *) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (840px <= width < 1200px) {
|
||||
&:where(
|
||||
:is([data-rail='collapsed'], [data-rail-auto]) [data-md-navigation-rail='adaptive']:not([data-md-open]),
|
||||
:is([data-rail='collapsed'], [data-rail-auto]) [data-md-navigation-rail='adaptive']:not([data-md-open]) *
|
||||
) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width >= 1200px) {
|
||||
&:where(
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='adaptive']:not([data-md-open]),
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='adaptive']:not([data-md-open]) *
|
||||
) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* The FAB row: 20px either side in the default 96px rail, 12px in a narrow 80 while collapsed
|
||||
@@ -803,46 +523,9 @@
|
||||
}
|
||||
|
||||
[data-md-navigation-rail][data-md-width='narrow'] [data-md-navigation-rail-fab-row] {
|
||||
&:where(
|
||||
[data-md-navigation-rail='collapsed'],
|
||||
[data-md-navigation-rail='collapsed'] *,
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='collapsible']:not([data-md-open]),
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='collapsible']:not([data-md-open]) *,
|
||||
[data-md-navigation-rail='modal']:not([data-md-open]),
|
||||
[data-md-navigation-rail='modal']:not([data-md-open]) *
|
||||
) {
|
||||
@container style(--md-navigation-rail-value: collapsed) {
|
||||
padding-inline: 12px;
|
||||
}
|
||||
|
||||
@media (width < 600px) {
|
||||
&:where([data-md-navigation-rail='collapsible']:not([data-md-open]), [data-md-navigation-rail='collapsible']:not([data-md-open]) *) {
|
||||
padding-inline: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width < 840px) {
|
||||
&:where([data-md-navigation-rail='adaptive']:not([data-md-open]), [data-md-navigation-rail='adaptive']:not([data-md-open]) *) {
|
||||
padding-inline: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (840px <= width < 1200px) {
|
||||
&:where(
|
||||
:is([data-rail='collapsed'], [data-rail-auto]) [data-md-navigation-rail='adaptive']:not([data-md-open]),
|
||||
:is([data-rail='collapsed'], [data-rail-auto]) [data-md-navigation-rail='adaptive']:not([data-md-open]) *
|
||||
) {
|
||||
padding-inline: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width >= 1200px) {
|
||||
&:where(
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='adaptive']:not([data-md-open]),
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='adaptive']:not([data-md-open]) *
|
||||
) {
|
||||
padding-inline: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[data-md-navigation-rail-destinations] {
|
||||
@@ -858,50 +541,10 @@
|
||||
[data-md-navigation-rail-footer] {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
[data-md-navigation-rail-destinations],
|
||||
[data-md-navigation-rail-footer] {
|
||||
&:where(
|
||||
[data-md-navigation-rail='collapsed'],
|
||||
[data-md-navigation-rail='collapsed'] *,
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='collapsible']:not([data-md-open]),
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='collapsible']:not([data-md-open]) *,
|
||||
[data-md-navigation-rail='modal']:not([data-md-open]),
|
||||
[data-md-navigation-rail='modal']:not([data-md-open]) *
|
||||
) {
|
||||
@container style(--md-navigation-rail-value: collapsed) {
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
@media (width < 600px) {
|
||||
&:where([data-md-navigation-rail='collapsible']:not([data-md-open]), [data-md-navigation-rail='collapsible']:not([data-md-open]) *) {
|
||||
gap: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width < 840px) {
|
||||
&:where([data-md-navigation-rail='adaptive']:not([data-md-open]), [data-md-navigation-rail='adaptive']:not([data-md-open]) *) {
|
||||
gap: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (840px <= width < 1200px) {
|
||||
&:where(
|
||||
:is([data-rail='collapsed'], [data-rail-auto]) [data-md-navigation-rail='adaptive']:not([data-md-open]),
|
||||
:is([data-rail='collapsed'], [data-rail-auto]) [data-md-navigation-rail='adaptive']:not([data-md-open]) *
|
||||
) {
|
||||
gap: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width >= 1200px) {
|
||||
&:where(
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='adaptive']:not([data-md-open]),
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='adaptive']:not([data-md-open]) *
|
||||
) {
|
||||
gap: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[data-md-navigation-rail-footer] {
|
||||
@@ -921,7 +564,7 @@
|
||||
/*
|
||||
* A FAB in the rail's header rests at elevation 0, not the 3 a standalone FAB has
|
||||
* (§ Navigation Rail/Behaviour: "when nested within another component, such as the navigation
|
||||
* rail, the FAB's resting elevation should be level 0" — N-03). The doubled `[data-md-fab]`
|
||||
* rail, the FAB's resting elevation should be level 0"). The doubled `[data-md-fab]`
|
||||
* attribute only adds specificity, over fab.css's `[data-md-fab]:hover` too, as
|
||||
* `[data-md-navigation-rail-item][data-md-navigation-rail-item]::before`
|
||||
* (navigation-rail-item.css) does for the same reason.
|
||||
@@ -933,7 +576,7 @@
|
||||
|
||||
/*
|
||||
* "Rail transitions from collapsed to expanded should animate the FAB into and out of an
|
||||
* extended FAB" (N-23) — so the header takes one `<x-fab label icon>` and morphs it, rather
|
||||
* extended FAB" — so the header takes one `<x-fab label icon>` and morphs it, rather
|
||||
* than swapping two by `display`, which showed the collapsed one at once while the rail's
|
||||
* width was still springing. The label's width springs on the rail's own spatial spring; with
|
||||
* the gap and the extended FAB's own minimum width both zeroed, `aspect-ratio` squares what is
|
||||
@@ -949,109 +592,21 @@
|
||||
transition:
|
||||
max-width var(--md-sys-motion-spatial-default-duration) var(--md-sys-motion-spatial-default),
|
||||
opacity var(--md-sys-motion-effects-default-duration) var(--md-sys-motion-effects-default);
|
||||
}
|
||||
|
||||
[data-md-navigation-rail-header] [data-md-fab] > span {
|
||||
&:where(
|
||||
[data-md-navigation-rail='collapsed'],
|
||||
[data-md-navigation-rail='collapsed'] *,
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='collapsible']:not([data-md-open]),
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='collapsible']:not([data-md-open]) *,
|
||||
[data-md-navigation-rail='modal']:not([data-md-open]),
|
||||
[data-md-navigation-rail='modal']:not([data-md-open]) *
|
||||
) {
|
||||
@container style(--md-navigation-rail-value: collapsed) {
|
||||
max-width: 0;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
@media (width < 600px) {
|
||||
&:where([data-md-navigation-rail='collapsible']:not([data-md-open]), [data-md-navigation-rail='collapsible']:not([data-md-open]) *) {
|
||||
max-width: 0;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width < 840px) {
|
||||
&:where([data-md-navigation-rail='adaptive']:not([data-md-open]), [data-md-navigation-rail='adaptive']:not([data-md-open]) *) {
|
||||
max-width: 0;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (840px <= width < 1200px) {
|
||||
&:where(
|
||||
:is([data-rail='collapsed'], [data-rail-auto]) [data-md-navigation-rail='adaptive']:not([data-md-open]),
|
||||
:is([data-rail='collapsed'], [data-rail-auto]) [data-md-navigation-rail='adaptive']:not([data-md-open]) *
|
||||
) {
|
||||
max-width: 0;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width >= 1200px) {
|
||||
&:where(
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='adaptive']:not([data-md-open]),
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='adaptive']:not([data-md-open]) *
|
||||
) {
|
||||
max-width: 0;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* `[data-md-extended]` doubled for the same reason as the shadow's `[data-md-fab]` above: it
|
||||
outranks fab.css's `[data-md-fab][data-md-extended][data-md-size]` gap and its collapsed
|
||||
collapse-on-scroll FAB's minimum width, three attributes each. */
|
||||
[data-md-navigation-rail-header] [data-md-fab][data-md-extended][data-md-extended] {
|
||||
&:where(
|
||||
[data-md-navigation-rail='collapsed'],
|
||||
[data-md-navigation-rail='collapsed'] *,
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='collapsible']:not([data-md-open]),
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='collapsible']:not([data-md-open]) *,
|
||||
[data-md-navigation-rail='modal']:not([data-md-open]),
|
||||
[data-md-navigation-rail='modal']:not([data-md-open]) *
|
||||
) {
|
||||
@container style(--md-navigation-rail-value: collapsed) {
|
||||
min-inline-size: 0;
|
||||
aspect-ratio: 1;
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
@media (width < 600px) {
|
||||
&:where([data-md-navigation-rail='collapsible']:not([data-md-open]), [data-md-navigation-rail='collapsible']:not([data-md-open]) *) {
|
||||
min-inline-size: 0;
|
||||
aspect-ratio: 1;
|
||||
gap: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width < 840px) {
|
||||
&:where([data-md-navigation-rail='adaptive']:not([data-md-open]), [data-md-navigation-rail='adaptive']:not([data-md-open]) *) {
|
||||
min-inline-size: 0;
|
||||
aspect-ratio: 1;
|
||||
gap: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (840px <= width < 1200px) {
|
||||
&:where(
|
||||
:is([data-rail='collapsed'], [data-rail-auto]) [data-md-navigation-rail='adaptive']:not([data-md-open]),
|
||||
:is([data-rail='collapsed'], [data-rail-auto]) [data-md-navigation-rail='adaptive']:not([data-md-open]) *
|
||||
) {
|
||||
min-inline-size: 0;
|
||||
aspect-ratio: 1;
|
||||
gap: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width >= 1200px) {
|
||||
&:where(
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='adaptive']:not([data-md-open]),
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='adaptive']:not([data-md-open]) *
|
||||
) {
|
||||
min-inline-size: 0;
|
||||
aspect-ratio: 1;
|
||||
gap: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,10 +23,12 @@
|
||||
|
||||
@layer material.reset, material.tokens, material.base, material.layout, material.components, material.text, material.visibility;
|
||||
|
||||
@import './color.css';
|
||||
|
||||
@layer material.components {
|
||||
[data-md-progress] {
|
||||
color: var(--md-sys-color-primary);
|
||||
stroke: var(--md-sys-color-secondary-container);
|
||||
color: var(--md-color, var(--md-sys-color-primary));
|
||||
stroke: var(--md-container, var(--md-sys-color-secondary-container));
|
||||
|
||||
& > svg {
|
||||
display: block;
|
||||
@@ -80,33 +82,9 @@
|
||||
height: 52px;
|
||||
}
|
||||
|
||||
[data-md-progress][data-md-color='secondary'] {
|
||||
color: var(--md-sys-color-secondary);
|
||||
/* Every other hue comes from the shared colour-role table (color.css): its own `primary` entry
|
||||
is plain primary-container, so the one hue this file draws differently keeps its override. */
|
||||
[data-md-progress][data-md-color='primary'] {
|
||||
stroke: var(--md-sys-color-secondary-container);
|
||||
}
|
||||
|
||||
[data-md-progress][data-md-color='tertiary'] {
|
||||
color: var(--md-sys-color-tertiary);
|
||||
stroke: var(--md-sys-color-tertiary-container);
|
||||
}
|
||||
|
||||
[data-md-progress][data-md-color='error'] {
|
||||
color: var(--md-sys-color-error);
|
||||
stroke: var(--md-sys-color-error-container);
|
||||
}
|
||||
|
||||
[data-md-progress][data-md-color='success'] {
|
||||
color: var(--md-sys-color-success);
|
||||
stroke: var(--md-sys-color-success-container);
|
||||
}
|
||||
|
||||
[data-md-progress][data-md-color='warning'] {
|
||||
color: var(--md-sys-color-warning);
|
||||
stroke: var(--md-sys-color-warning-container);
|
||||
}
|
||||
|
||||
[data-md-progress][data-md-color='info'] {
|
||||
color: var(--md-sys-color-info);
|
||||
stroke: var(--md-sys-color-info-container);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
* back to the closed opacity.
|
||||
*
|
||||
* resources/js/rich-tooltip.js shows and hides the bubble and keeps the trigger described with
|
||||
* `aria-describedby` — and, while `persistent`, `aria-haspopup`/`aria-expanded` (ACT-22) — none of
|
||||
* `aria-describedby` — and, while `persistent`, `aria-haspopup`/`aria-expanded` — none of
|
||||
* which this stylesheet draws.
|
||||
*/
|
||||
|
||||
|
||||
@@ -84,17 +84,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
& > input {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
padding: 0;
|
||||
margin: -1px;
|
||||
overflow: hidden;
|
||||
clip-path: inset(50%);
|
||||
white-space: nowrap;
|
||||
border-width: 0;
|
||||
}
|
||||
/* The radio stays in the page, for the form, the keyboard and a screen reader —
|
||||
`md-visually-hidden` on the element itself (text.css), which outranks this layer
|
||||
whatever wins the specificity, `material.text` sitting above `material.components`. */
|
||||
}
|
||||
|
||||
[data-md-scheme-picker-swatches] {
|
||||
|
||||
@@ -168,11 +168,6 @@
|
||||
letter-spacing: var(--md-sys-typescale-body-lg-tracking);
|
||||
}
|
||||
|
||||
[data-md-search-input]::placeholder {
|
||||
color: var(--md-sys-color-on-surface-variant);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
[data-md-search-input]::-webkit-search-cancel-button,
|
||||
[data-md-search-input]::-webkit-search-decoration {
|
||||
appearance: none;
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
* <x-section-nav>: the navigation inside one area of an application — M3's secondary tabs from
|
||||
* `medium` (600px), five or more of them the scrollable tab bar M3's own accessibility page
|
||||
* blesses rather than a grid that would break the tab bar's divider and strand the upper rows'
|
||||
* indicators against nothing (docs/audits/m3-alignment/navigation.md N-16); below `medium`, where a
|
||||
* row of them never fits, a button naming the current section opens the same list as a menu.
|
||||
* indicators against nothing; below `medium`, where a row of them never fits, a button naming the
|
||||
* current section opens the same list as a menu.
|
||||
*
|
||||
* [data-md-section-nav] min-inline-size: 0
|
||||
* [data-md-section-nav-picker] hidden from medium
|
||||
@@ -14,7 +14,7 @@
|
||||
*
|
||||
* Reuses `<x-tabs>`'s own hooks and stylesheet rather than a tab bar of its own: a link marked
|
||||
* `aria-current="page"` takes the same active indicator and colour tabs.css already draws for
|
||||
* `aria-selected="true"` (N-21), so nothing here repeats a rule tabs.css owns; the only addition is
|
||||
* `aria-selected="true"`, so nothing here repeats a rule tabs.css owns; the only addition is
|
||||
* this bar's own list items — flex rows, so tabs.css's `li > [data-md-tab]` share of the width
|
||||
* applies, and `min-inline-size: 0`, so a long title in a fixed row wraps to its second line and
|
||||
* truncates there (tabs.css, M3's "may wrap to a max second line if needed with truncation")
|
||||
|
||||
@@ -45,13 +45,14 @@
|
||||
@layer material.reset, material.tokens, material.base, material.layout, material.components, material.text, material.visibility;
|
||||
|
||||
@import './icon.css';
|
||||
@import './color.css';
|
||||
|
||||
@layer material.components {
|
||||
[data-md-slider] {
|
||||
--slider-active: var(--md-sys-color-primary);
|
||||
--slider-inactive: var(--md-sys-color-secondary-container);
|
||||
--slider-on-active: var(--md-sys-color-on-primary);
|
||||
--slider-on-inactive: var(--md-sys-color-on-secondary-container);
|
||||
--slider-active: var(--md-color, var(--md-sys-color-primary));
|
||||
--slider-inactive: var(--md-container, var(--md-sys-color-secondary-container));
|
||||
--slider-on-active: var(--md-on-color, var(--md-sys-color-on-primary));
|
||||
--slider-on-inactive: var(--md-on-container, var(--md-sys-color-on-secondary-container));
|
||||
--slider-disabled-active: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-content-opacity) * 100%), transparent);
|
||||
--slider-disabled-inactive: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-container-opacity) * 100%), transparent);
|
||||
--slider-across: 48px;
|
||||
@@ -84,44 +85,11 @@
|
||||
--slider-handle: 108px;
|
||||
}
|
||||
|
||||
[data-md-slider][data-md-color='secondary'] {
|
||||
--slider-active: var(--md-sys-color-secondary);
|
||||
--slider-on-active: var(--md-sys-color-on-secondary);
|
||||
}
|
||||
|
||||
[data-md-slider][data-md-color='tertiary'] {
|
||||
--slider-active: var(--md-sys-color-tertiary);
|
||||
--slider-inactive: var(--md-sys-color-tertiary-container);
|
||||
--slider-on-active: var(--md-sys-color-on-tertiary);
|
||||
--slider-on-inactive: var(--md-sys-color-on-tertiary-container);
|
||||
}
|
||||
|
||||
[data-md-slider][data-md-color='error'] {
|
||||
--slider-active: var(--md-sys-color-error);
|
||||
--slider-inactive: var(--md-sys-color-error-container);
|
||||
--slider-on-active: var(--md-sys-color-on-error);
|
||||
--slider-on-inactive: var(--md-sys-color-on-error-container);
|
||||
}
|
||||
|
||||
[data-md-slider][data-md-color='success'] {
|
||||
--slider-active: var(--md-sys-color-success);
|
||||
--slider-inactive: var(--md-sys-color-success-container);
|
||||
--slider-on-active: var(--md-sys-color-on-success);
|
||||
--slider-on-inactive: var(--md-sys-color-on-success-container);
|
||||
}
|
||||
|
||||
[data-md-slider][data-md-color='warning'] {
|
||||
--slider-active: var(--md-sys-color-warning);
|
||||
--slider-inactive: var(--md-sys-color-warning-container);
|
||||
--slider-on-active: var(--md-sys-color-on-warning);
|
||||
--slider-on-inactive: var(--md-sys-color-on-warning-container);
|
||||
}
|
||||
|
||||
[data-md-slider][data-md-color='info'] {
|
||||
--slider-active: var(--md-sys-color-info);
|
||||
--slider-inactive: var(--md-sys-color-info-container);
|
||||
--slider-on-active: var(--md-sys-color-on-info);
|
||||
--slider-on-inactive: var(--md-sys-color-on-info-container);
|
||||
/* Every other hue comes from the shared colour-role table (color.css): its own `primary` entry
|
||||
is plain primary-container, so the one hue this file draws differently keeps its override. */
|
||||
[data-md-slider][data-md-color='primary'] {
|
||||
--slider-inactive: var(--md-sys-color-secondary-container);
|
||||
--slider-on-inactive: var(--md-sys-color-on-secondary-container);
|
||||
}
|
||||
|
||||
/* Disabled: the colours give way to on-surface at M3's disabled opacities. */
|
||||
|
||||
@@ -66,10 +66,7 @@
|
||||
[data-md-split-button] [data-md-split] {
|
||||
--md-split-button-corner: var(--md-split-button-inner);
|
||||
|
||||
border-start-start-radius: var(--md-split-button-corner);
|
||||
border-end-start-radius: var(--md-split-button-corner);
|
||||
border-start-end-radius: var(--md-split-button-corner);
|
||||
border-end-end-radius: var(--md-split-button-corner);
|
||||
border-radius: var(--md-split-button-corner);
|
||||
}
|
||||
|
||||
[data-md-split-button] [data-md-split]:active {
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
* [data-md-tab-content] [data-md-icon] (optional), [data-md-tab-label],
|
||||
* [data-md-tab-indicator]
|
||||
* [data-md-tab-label] [data-md-tab-text], [data-md-badge] (optional)
|
||||
* [data-md-tab-panel] role="tabpanel", hidden server-side until chosen (N-05)
|
||||
* [data-md-tab-panel] role="tabpanel", hidden server-side until chosen
|
||||
*
|
||||
* "Labels: single row by default; may wrap to a max second line if needed with truncation, or use
|
||||
* scrollable tabs to give longer titles more room" (§ Tabs, "Behaviour and guidelines"). A fixed
|
||||
@@ -25,7 +25,7 @@
|
||||
*
|
||||
* The active indicator is drawn in every tab and shown under the chosen one, so it is right before
|
||||
* Alpine starts and after a morph: 3px with rounded top corners under the content of a primary tab
|
||||
* (at least 24px wide, inset 2px at each side — N-18), 2px across the whole of a secondary one.
|
||||
* (at least 24px wide, inset 2px at each side), 2px across the whole of a secondary one.
|
||||
* When the choice changes, a view transition moves it from the old tab to the new (resources/js/tabs.js),
|
||||
* as M3's slides.
|
||||
*
|
||||
@@ -33,10 +33,10 @@
|
||||
* rest of the package draws 3px thick 2px outside the element (tokens/state.css). `--tabs-ring` is
|
||||
* the room that takes: the bar carries it as padding on every side, and the state layer and the
|
||||
* indicator reach back out into it, so the divider still sits against the tabs and the indicator
|
||||
* still sits on the divider (N-20). That makes the bar 10px taller than M3's 48px tab. A scrollable
|
||||
* set's first tab is offset 52dp from the leading edge, so it reads as scrollable (N-10). A link
|
||||
* still sits on the divider. That makes the bar 10px taller than M3's 48px tab. A scrollable
|
||||
* set's first tab is offset 52dp from the leading edge, so it reads as scrollable. A link
|
||||
* marked `aria-current="page"` (`<x-section-nav>`'s tabs) takes the active indicator and colour
|
||||
* exactly as `aria-selected="true"` does (N-21).
|
||||
* exactly as `aria-selected="true"` does.
|
||||
*/
|
||||
|
||||
@layer material.reset, material.tokens, material.base, material.layout, material.components, material.text, material.visibility;
|
||||
@@ -63,7 +63,7 @@
|
||||
}
|
||||
|
||||
/* "Offset the first scrollable tab 52dp from the leading edge so it's clear that more content
|
||||
is available" (N-10). Logical, so a right-to-left page mirrors it. */
|
||||
is available". Logical, so a right-to-left page mirrors it. */
|
||||
[data-md-tabs-bar][data-md-scrollable] {
|
||||
padding-inline-start: 52px;
|
||||
scroll-padding-inline-start: 52px;
|
||||
@@ -141,7 +141,7 @@
|
||||
}
|
||||
|
||||
/* A link-based bar marks the page with aria-current, not aria-selected; both are the chosen
|
||||
tab, and both take the variant's active colour (N-21). */
|
||||
tab, and both take the variant's active colour. */
|
||||
[data-md-tab]:is([aria-selected='true'], [aria-current='page']) {
|
||||
color: var(--md-sys-color-primary);
|
||||
}
|
||||
@@ -196,7 +196,7 @@
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
/* Primary indicators are inset 2dp at each side (N-18); both variants sit on the divider, which
|
||||
/* Primary indicators are inset 2dp at each side; both variants sit on the divider, which
|
||||
the ring's room has pushed below the tab. */
|
||||
[data-md-tab-indicator] {
|
||||
position: absolute;
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
/*
|
||||
* <x-theme-toggle>: `mode="toggle"|"cycle"` an icon button between light, dark (and system for
|
||||
* cycle); `mode="picker"|"contrast"` a connected group over native radios (docs/audits/m3-alignment/
|
||||
* navigation.md N-04, N-17 — the Expressive-deprecated segmented button's successor,
|
||||
* `<x-group>`, already fixes both there). This file only draws the icon button; the group's own
|
||||
* shape, colour and 48px minimum below `medium` are group.css's.
|
||||
* cycle); `mode="picker"|"contrast"` a connected group over native radios — the Expressive-
|
||||
* deprecated segmented button's successor, `<x-group>`, already gives it the keyboard handling and
|
||||
* shape a hand-rolled control would have to reimplement. This file only draws the icon button; the
|
||||
* group's own shape, colour and 48px minimum below `medium` are group.css's.
|
||||
*
|
||||
* [data-md-theme-toggle="toggle"|"cycle"] the icon button: 40px reaching 48px through
|
||||
* md-touch-target (N-01), morphing corner
|
||||
* md-touch-target, morphing corner
|
||||
* [data-md-theme-toggle="picker"|"contrast"] the group's own wrapper (`role="group"`)
|
||||
*
|
||||
* The icon button also carries `data-md-icon-button`, the hook `resources/css/components/
|
||||
* toolbar.css` matches generically (not `[data-md-button][data-md-icon-button]`, as button.css
|
||||
* requires): a theme toggle placed in a toolbar's `actions` takes the toolbar's own icon colour
|
||||
* (N-13) the same way one of its `<x-button icon>` children would.
|
||||
* the same way one of its `<x-button icon>` children would.
|
||||
*
|
||||
* The corner morphs from full to `sm` while pressed on the fast spatial spring — M3 Expressive's
|
||||
* pressed-state shape change, the same motion `<x-button>`'s own icon buttons use
|
||||
|
||||
@@ -64,6 +64,7 @@
|
||||
@import './field.css';
|
||||
@import './icon.css';
|
||||
@import './button.css';
|
||||
@import './modal.css';
|
||||
|
||||
@layer material.components {
|
||||
@property --timepicker-angle {
|
||||
@@ -77,7 +78,8 @@
|
||||
caret-color: transparent;
|
||||
}
|
||||
|
||||
/* The dialog: M3's spatial-fast pop, a 32%-scrim backdrop, no default border or padding. */
|
||||
/* The dialog's size, no default border or padding; the entry pop and the scrim are
|
||||
modal.css's shared dialog chrome, imported above. */
|
||||
[data-md-timepicker-dialog] {
|
||||
max-width: calc(100vw - var(--md-sys-measurement-space400));
|
||||
max-height: calc(100dvh - var(--md-sys-measurement-space400));
|
||||
@@ -87,22 +89,6 @@
|
||||
border: 0;
|
||||
background: transparent;
|
||||
color: var(--md-sys-color-on-surface);
|
||||
opacity: 1;
|
||||
scale: 1;
|
||||
transition-property: opacity, scale;
|
||||
transition-duration: var(--md-sys-motion-spatial-fast-duration);
|
||||
transition-timing-function: var(--md-sys-motion-spatial-fast);
|
||||
}
|
||||
|
||||
@starting-style {
|
||||
[data-md-timepicker-dialog] {
|
||||
opacity: 0;
|
||||
scale: 0.95;
|
||||
}
|
||||
}
|
||||
|
||||
[data-md-timepicker-dialog]::backdrop {
|
||||
background-color: color-mix(in srgb, var(--md-sys-color-scrim) 32%, transparent);
|
||||
}
|
||||
|
||||
[data-md-timepicker-surface] {
|
||||
|
||||
@@ -15,19 +15,19 @@
|
||||
* as M3 nudges a snackbar clear of a docked toolbar and never in front of navigation;
|
||||
* `data-md-position="bottom-start"` moves it to the start edge, with M3's margin growing from `medium`. resources/js/snackbar.js
|
||||
* publishes the snackbar's own height as `--material-snackbar-height`, so a FAB (fab.css) can
|
||||
* lift clear of it — M3 puts a snackbar above a FAB, never in front of or behind one (ACT-17).
|
||||
* lift clear of it — M3 puts a snackbar above a FAB, never in front of or behind one.
|
||||
* Below `medium` it is full width; from there it hugs its line length, which an application's own
|
||||
* class can still bound.
|
||||
*
|
||||
* The action and the close button are both drawn at 40px and render the foundation's
|
||||
* `md-state-layer`, `md-focus-ring` and `md-touch-target` (foundation/interaction.css) to reach
|
||||
* M3's 48px target (ACT-18); nothing here copies their rules.
|
||||
* M3's 48px target; nothing here copies their rules.
|
||||
*
|
||||
* It enters on a translate and a fade on the fast spatial spring, `@starting-style` giving both a
|
||||
* start. No state icon: M3 says to avoid one in a snackbar (ACT-20). The live region is the host
|
||||
* itself, in the page before any message is, never the snackbar that comes and goes (ACT-02);
|
||||
* start. No state icon: M3 says to avoid one in a snackbar. The live region is the host
|
||||
* itself, in the page before any message is, never the snackbar that comes and goes;
|
||||
* resources/js/snackbar.js queues, times and dismisses a toast, including on Escape while it
|
||||
* holds the focus and on Alt+G, which moves the focus to one carrying an action (ACT-34).
|
||||
* holds the focus and on Alt+G, which moves the focus to one carrying an action.
|
||||
*/
|
||||
|
||||
@layer material.reset, material.tokens, material.base, material.layout, material.components, material.text, material.visibility;
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* 8px at its ends and 4px between controls; `vertical` stands it on end
|
||||
*
|
||||
* Placed over the page, a horizontal toolbar keeps 16dp from the window's edge and a vertical one
|
||||
* 24dp, which is M3's minimum for each (N-12).
|
||||
* 24dp, which is M3's minimum for each.
|
||||
*
|
||||
* On web and large screens a docked toolbar "can be rounded", and dividers can organise its
|
||||
* controls into groups: `rounded` does the first from `expanded` (840px), and a divider in the
|
||||
@@ -23,7 +23,7 @@
|
||||
*
|
||||
* `<x-button>` and `<x-fab>` draw their own ink from `data-md-color`/`data-md-variant`, not a
|
||||
* utility, so a toolbar's recolouring rules — vibrant's icon buttons, a standard toolbar's primary
|
||||
* ones (N-13), a docked FAB's flattened shadow — sit in this file's own `material.components`
|
||||
* ones, a docked FAB's flattened shadow — sit in this file's own `material.components`
|
||||
* layer like everything else, each more specific than the button.css or fab.css rule it overrides,
|
||||
* whichever file an application imports first. The recolouring leaves a disabled button alone, so
|
||||
* button.css's disabled colours still apply inside a toolbar.
|
||||
@@ -82,7 +82,7 @@
|
||||
}
|
||||
|
||||
/* M3's colour list for a standard toolbar ends "Standard button (Primary)", as the vibrant list
|
||||
ends "Standard button (On primary container)" — the row above (N-13). Both rows name the
|
||||
ends "Standard button (On primary container)" — the row above. Both rows name the
|
||||
*standard* button, so a button that fills its own container is left alone: it carries the
|
||||
matching label colour (`filled` on-primary, `tonal` on-tone, either selected), and painting
|
||||
that label primary put a primary icon on a primary fill — the current page's button in a
|
||||
@@ -140,7 +140,7 @@
|
||||
* A toolbar at the bottom shares the screen region with a navigation bar, so it clears the one
|
||||
* <x-scaffold> publishes as --material-bottom-bar, exactly as the FAB and the snackbar do —
|
||||
* `max()`, not a sum, because that height already swallows the bottom safe area; without a bar
|
||||
* the safe area alone applies (N-02). A *docked* toolbar and a navigation bar must never be on
|
||||
* the safe area alone applies. A *docked* toolbar and a navigation bar must never be on
|
||||
* screen together at all; the offset is the backstop, not a licence.
|
||||
*/
|
||||
[data-md-toolbar-place='bottom'] {
|
||||
@@ -160,7 +160,7 @@
|
||||
}
|
||||
|
||||
/* "Horizontal toolbars should have a minimum 16dp margin from the edge of the window. Vertical
|
||||
toolbars should have a minimum 24dp margin" (N-12). */
|
||||
toolbars should have a minimum 24dp margin". */
|
||||
[data-md-toolbar][data-md-vertical][data-md-toolbar-place='end'],
|
||||
[data-md-toolbar-group][data-md-vertical][data-md-toolbar-place='end'] {
|
||||
inset-inline-end: calc(var(--md-sys-measurement-space300) + var(--material-safe-right, env(safe-area-inset-right)));
|
||||
|
||||
Vendored
+9
-2
@@ -10,7 +10,8 @@
|
||||
* Every rule of the package sits in a sub-layer of `material`, in this order, lowest first:
|
||||
*
|
||||
* material.reset foundation/reset.css — the browser's defaults taken back
|
||||
* material.tokens foundation/tokens.css — every `--md-sys-*` and `--md-ref-*` property
|
||||
* material.tokens tokens/*.css, imported here directly — every `--md-sys-*` and
|
||||
* `--md-ref-*` property
|
||||
* material.base foundation/base.css, foundation/interaction.css — the page, the font
|
||||
* face, and md-state-layer, md-focus-ring, md-touch-target, md-link
|
||||
* material.layout the layout components: scaffold, panes, the canonical layouts
|
||||
@@ -33,7 +34,13 @@
|
||||
|
||||
@import './foundation/reset.css';
|
||||
@import './foundation/hidden.css';
|
||||
@import './foundation/tokens.css';
|
||||
@import './tokens/scheme.css';
|
||||
@import './tokens/shape.css';
|
||||
@import './tokens/elevation.css';
|
||||
@import './tokens/motion.css';
|
||||
@import './tokens/type.css';
|
||||
@import './tokens/state.css';
|
||||
@import './tokens/spacing.css';
|
||||
@import './foundation/base.css';
|
||||
@import './foundation/interaction.css';
|
||||
@import './text.css';
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
* The tokens: every `--md-sys-*` and `--md-ref-*` custom property the package reads.
|
||||
*
|
||||
* Each token file wraps its own declarations in `material.tokens`, because an `@import` cannot sit
|
||||
* inside a layer block and `layer()` on the import would nest the layer a second time. Being the
|
||||
* lowest layer but one, a token here loses to the same property declared anywhere an application
|
||||
* writes it: its generated `material-scheme.css`, unlayered, replaces the default scheme below
|
||||
* whatever its selectors, and a typeface or a spacing step is overridden the same way.
|
||||
*
|
||||
* scheme the colour roles of M3's baseline scheme, light and dark, three contrast levels
|
||||
* shape the corner scale
|
||||
* elevation the five shadow levels
|
||||
* motion the springs of both motion schemes and M3's legacy easings
|
||||
* type the 30 type styles and the brand typeface
|
||||
* state the state-layer and disabled opacities
|
||||
* spacing the measurement scale, space25 … space900
|
||||
*/
|
||||
|
||||
@layer material.reset, material.tokens, material.base, material.layout, material.components, material.text, material.visibility;
|
||||
|
||||
@import '../tokens/scheme.css';
|
||||
@import '../tokens/shape.css';
|
||||
@import '../tokens/elevation.css';
|
||||
@import '../tokens/motion.css';
|
||||
@import '../tokens/type.css';
|
||||
@import '../tokens/state.css';
|
||||
@import '../tokens/spacing.css';
|
||||
@@ -24,12 +24,10 @@
|
||||
* bar, the FAB wrapper and `<main>` stack regardless of the row's own display.
|
||||
*
|
||||
* `[data-md-scaffold-actions]`'s column layout is `rail-collapsed:flex-col`, the one Tailwind
|
||||
* variant scaffold.blade.php still used (`resources/css/tailwind.css`, removed with this rule):
|
||||
* written out branch for branch as the navigation rail's own rewrite did for its internal parts
|
||||
* (`resources/css/components/navigation-rail.css`) — the three width-independent conditions in one
|
||||
* `:where()` group, the four width-gated ones each in their own `@media` block, since CSS cannot
|
||||
* merge different queries. Only the "descendant of a collapsed rail" half of each pair applies:
|
||||
* the actions row can never be the rail element itself.
|
||||
* variant scaffold.blade.php still used (`resources/css/tailwind.css`, removed with this rule): the
|
||||
* actions row is always inside a rail, never the rail element itself, so it reads
|
||||
* `--md-navigation-rail-value` with `@container style()` like any other application content does
|
||||
* (`resources/css/components/navigation-rail.css`), rather than copying the rail's own conditions.
|
||||
*
|
||||
* `[data-md-scaffold-bar]` pins the navigation bar to the window's bottom edge below `medium`, at
|
||||
* z-index 30: over the page, under the rail's scrim (40) and the snackbar (50, toast.css). While a
|
||||
@@ -137,39 +135,9 @@
|
||||
padding-block-start: var(--md-sys-measurement-space100);
|
||||
padding-inline: 20px;
|
||||
|
||||
&:where(
|
||||
[data-md-navigation-rail='collapsed'] *,
|
||||
[data-rail='collapsed'] [data-md-navigation-rail='collapsible']:not([data-md-open]) *,
|
||||
[data-md-navigation-rail='modal']:not([data-md-open]) *
|
||||
) {
|
||||
@container style(--md-navigation-rail-value: collapsed) {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
@media (width < 600px) {
|
||||
&:where([data-md-navigation-rail='collapsible']:not([data-md-open]) *) {
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width < 840px) {
|
||||
&:where([data-md-navigation-rail='adaptive']:not([data-md-open]) *) {
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width >= 840px) {
|
||||
@media (width < 1200px) {
|
||||
&:where(:is([data-rail='collapsed'], [data-rail-auto]) [data-md-navigation-rail='adaptive']:not([data-md-open]) *) {
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (width >= 1200px) {
|
||||
&:where([data-rail='collapsed'] [data-md-navigation-rail='adaptive']:not([data-md-open]) *) {
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[data-md-scaffold-content] > main {
|
||||
|
||||
@@ -144,53 +144,17 @@
|
||||
}
|
||||
|
||||
/* Shape: a corner swatch, filled with a tonal colour that is decoration only (never meaning,
|
||||
same as the corner it demonstrates), one per corner token. */
|
||||
same as the corner it demonstrates), one per corner token. The swatch is a `<x-surface>`
|
||||
hook (`data-md-surface`, layout/surface.css) for its `data-md-corner` table alone — this
|
||||
rule's own background outranks surface.css's, `material.components` over `material.layout`
|
||||
whatever either's specificity, so the swatch keeps its tonal fill rather than surface.css's
|
||||
default surface-container. */
|
||||
[data-md-showcase-shape-swatch] {
|
||||
display: block;
|
||||
height: 80px;
|
||||
background-color: var(--md-sys-color-primary-container);
|
||||
}
|
||||
|
||||
[data-md-showcase-shape-swatch][data-md-corner='none'] {
|
||||
border-radius: var(--md-sys-shape-corner-none);
|
||||
}
|
||||
|
||||
[data-md-showcase-shape-swatch][data-md-corner='xs'] {
|
||||
border-radius: var(--md-sys-shape-corner-xs);
|
||||
}
|
||||
|
||||
[data-md-showcase-shape-swatch][data-md-corner='sm'] {
|
||||
border-radius: var(--md-sys-shape-corner-sm);
|
||||
}
|
||||
|
||||
[data-md-showcase-shape-swatch][data-md-corner='md'] {
|
||||
border-radius: var(--md-sys-shape-corner-md);
|
||||
}
|
||||
|
||||
[data-md-showcase-shape-swatch][data-md-corner='lg'] {
|
||||
border-radius: var(--md-sys-shape-corner-lg);
|
||||
}
|
||||
|
||||
[data-md-showcase-shape-swatch][data-md-corner='lg-increased'] {
|
||||
border-radius: var(--md-sys-shape-corner-lg-increased);
|
||||
}
|
||||
|
||||
[data-md-showcase-shape-swatch][data-md-corner='xl'] {
|
||||
border-radius: var(--md-sys-shape-corner-xl);
|
||||
}
|
||||
|
||||
[data-md-showcase-shape-swatch][data-md-corner='xl-increased'] {
|
||||
border-radius: var(--md-sys-shape-corner-xl-increased);
|
||||
}
|
||||
|
||||
[data-md-showcase-shape-swatch][data-md-corner='xxl'] {
|
||||
border-radius: var(--md-sys-shape-corner-xxl);
|
||||
}
|
||||
|
||||
[data-md-showcase-shape-swatch][data-md-corner='full'] {
|
||||
border-radius: var(--md-sys-shape-corner-full);
|
||||
}
|
||||
|
||||
/* Elevation: a tile at one shadow level, on the surface-container-high M3 pairs a shadow with. */
|
||||
[data-md-showcase-elevation-tile] {
|
||||
display: flex;
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
*
|
||||
* The brand typeface is Google Sans Flex (font.css). Emphasized styles are one weight step
|
||||
* heavier and fully rounded ("ROND" 100) — the axis that typeface exists for, verified by
|
||||
* `npm run check:font` — and they carry their own tracking, because M3 widens four of them and
|
||||
* takes Display Large's negative tracking back to zero.
|
||||
* tests/Feature/FontTest.php — and they carry their own tracking, because M3 widens four of them
|
||||
* and takes Display Large's negative tracking back to zero.
|
||||
*
|
||||
* `--md-ref-typeface-mono` is the package's, not M3's (M3 names a brand and a plain typeface and
|
||||
* nothing for code): the platform's own monospace faces, nothing downloaded, for what a person
|
||||
|
||||
Reference in New Issue
Block a user