Plan step 38: every two-column layout moves onto <x-grid> with <x-stack> columns; the checkbox group's card, its legend and the two search demos' bespoke geometry (an avatar chip, the compact search-icon-button bar) move to data-md-showcase-* hooks. The two small demo controls and the "Narrower" field's override move to .showcase-w-sm/-xs/-narrow — plain, unlayered classes, since <x-input> and <x-datepicker> forward only class and style to the element that needs sizing, never a data attribute. "Narrower"'s hint is reworded from "A max-w-* class" to "An unlayered rule from the call site wins", since that is now the mechanism being shown. FieldsTest's Chromium selectors run against an isolated fieldProbe fixture, not this page, so nothing there is at risk; #fields and every id (showcase-error, showcase-error-filled, showcase-audience, showcase-radio-theme) is unchanged. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9
459 lines
17 KiB
CSS
459 lines
17 KiB
CSS
/*
|
|
* The showcase's own chrome: what its frame needs beyond the layout components, the text classes
|
|
* and the shared interaction classes (plan step 38) — a brand wordmark, the search box's own
|
|
* geometry, a small icon avatar, an example's card and its code sample. Everything else the frame
|
|
* draws is a layout component with its props, or a `md-*` text class; this file is only what those
|
|
* two do not cover.
|
|
*
|
|
* In `material.components`: the showcase is one more thing drawn over the foundation and the
|
|
* layout components, exactly where `components/error-page.css` sits for the same reason (a whole
|
|
* page's own chrome, not a reusable package component, but still something an application's own
|
|
* unlayered CSS should outrank without a specificity fight). Keyed on `data-md-showcase-*` hooks,
|
|
* never a bare element selector, since this file is always bundled together with `all.css`
|
|
* (`ShowcaseAssetController`) and must not restyle anything outside the showcase's own pages.
|
|
*
|
|
* No imports: batch 1 (the frame — layout, index, section, shell, the example component) uses no
|
|
* selector this file needs to draw over, only tokens already in `all.css`, which the bundle always
|
|
* carries ahead of this file. A later batch that needs a component's own hook imports its
|
|
* stylesheet here, as every other package file does.
|
|
*
|
|
* Batch 2 (the foundation and layout sections) adds the swatches, specimens and demo boxes those
|
|
* pages draw beyond a layout component and a `md-*` text class: a colour swatch (its own fill is
|
|
* the role it shows, so that one declaration is the caller's inline `style`, never a class), a
|
|
* type-scale row, a shape swatch, an elevation tile, a motion track and its moving dot, an icon
|
|
* search result and the Layout page's breakpoint cards.
|
|
*
|
|
* Batch 3 (the component sections) adds each section's own demo geometry: a sized loading
|
|
* indicator, a bounded box for the FAB menu, a narrow chip row that forces its own scroll
|
|
* affordance, a scrolling table wrapper, the legend above a checkbox grid, a bordered demo card,
|
|
* a small circular avatar and a compact search bar, and the two ink colours a menu item's `icon-class`
|
|
* needs beyond the fixed `md-ink-*` set. A handful of call sites (`<x-input>`, `<x-datepicker>`,
|
|
* `<x-slider>`) forward only `class` and `style` to the element that needs sizing, never a data
|
|
* attribute, so a few widths below are plain `.showcase-*` classes instead of `data-md-showcase-*`
|
|
* hooks — the same "caller's class" mechanism any application would reach for, deliberately not
|
|
* named `md-*` since they are not part of the fixed set text.css declares.
|
|
*/
|
|
|
|
@layer material.reset, material.tokens, material.base, material.layout, material.components, material.text, material.visibility;
|
|
|
|
@layer material.components {
|
|
[data-md-showcase] {
|
|
-webkit-font-smoothing: antialiased;
|
|
-moz-osx-font-smoothing: grayscale;
|
|
}
|
|
|
|
/* The rail's wordmark: `md-type-title-lg md-truncate md-focus-ring` cover the type, the
|
|
ellipsis and the ring; `display: block` gives the truncated text a width to ellipsize
|
|
within, and the corner rounds the ring to match the state layer every other rail control
|
|
draws (foundation/interaction.css's `md-focus-ring` takes its shape from the element). */
|
|
[data-md-showcase-brand] {
|
|
display: block;
|
|
border-radius: var(--md-sys-shape-corner-xs);
|
|
}
|
|
|
|
/* The search bar fills the app bar's search slot. */
|
|
[data-md-showcase-search] {
|
|
width: 100%;
|
|
}
|
|
|
|
[data-md-showcase-search-hint] {
|
|
padding: var(--md-sys-measurement-space125) var(--md-sys-measurement-space200);
|
|
}
|
|
|
|
/* A kbd in running text: the search hint's "/", and the intro paragraph's own. */
|
|
[data-md-showcase-kbd] {
|
|
display: inline-block;
|
|
border-radius: var(--md-sys-shape-corner-xs);
|
|
background-color: var(--md-sys-color-surface-container-highest);
|
|
padding: 0 var(--md-sys-measurement-space75);
|
|
}
|
|
|
|
/* One search result: title over kind and context, centred in a 56px row (space700, M3's list
|
|
row) the way a menu item is. */
|
|
[data-md-showcase-search-result] {
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: center;
|
|
min-height: var(--md-sys-measurement-space700);
|
|
padding: var(--md-sys-measurement-space100) var(--md-sys-measurement-space200);
|
|
}
|
|
|
|
/* The bottom breathing room under a showcase page's content, inside the pane's own margins. */
|
|
[data-md-showcase-page] {
|
|
padding-block-end: var(--md-sys-measurement-space600);
|
|
}
|
|
|
|
/* Each section's group of components on the overview: a tonal box behind its icon, the way a
|
|
list's leading icon sits in a container (M3's small tonal container). */
|
|
[data-md-showcase-section-icon] {
|
|
display: grid;
|
|
place-items: center;
|
|
width: var(--md-sys-measurement-space600);
|
|
height: var(--md-sys-measurement-space600);
|
|
border-radius: var(--md-sys-shape-corner-lg);
|
|
background-color: var(--md-sys-color-secondary-container);
|
|
color: var(--md-sys-color-on-secondary-container);
|
|
}
|
|
|
|
/* Each `<section>`'s own `<h2>`, inside a still-Tailwind sections/*.blade.php partial this
|
|
batch does not rewrite: the page's own `<h1>` already names the section, so the heading
|
|
inside it is for assistive technology only — the same declarations as `md-visually-hidden`
|
|
(text.css), applied by structure because a class cannot reach into an @include'd partial. */
|
|
[data-md-showcase-sections] > section > h2 {
|
|
position: absolute;
|
|
width: 1px;
|
|
height: 1px;
|
|
padding: 0;
|
|
margin: -1px;
|
|
overflow: hidden;
|
|
clip-path: inset(50%);
|
|
white-space: nowrap;
|
|
border-width: 0;
|
|
}
|
|
|
|
/* An example: scroll-margin so a hash link (the search result, the "next section" nav) lands
|
|
clear of the sticky app bar above it. */
|
|
[data-md-showcase-example] {
|
|
scroll-margin-top: var(--md-sys-measurement-space900);
|
|
}
|
|
|
|
[data-md-showcase-code-summary] {
|
|
display: inline-block;
|
|
cursor: pointer;
|
|
border-radius: var(--md-sys-shape-corner-xs);
|
|
}
|
|
|
|
[data-md-showcase-code] {
|
|
margin-top: var(--md-sys-measurement-space100);
|
|
overflow-x: auto;
|
|
border-radius: var(--md-sys-shape-corner-sm);
|
|
background-color: var(--md-sys-color-surface-container-highest);
|
|
padding: var(--md-sys-measurement-space125);
|
|
}
|
|
|
|
/* Colour: a role swatch. Its fill is the one declaration that has to be the caller's inline
|
|
`style` (the role it shows decides it), so this rule only gives it a size and an edge; `lg`
|
|
is the big per-theme grid's, the plain attribute the smaller contrast-level list's. */
|
|
[data-md-showcase-swatch] {
|
|
display: block;
|
|
flex-shrink: 0;
|
|
width: var(--md-sys-measurement-space300);
|
|
height: var(--md-sys-measurement-space300);
|
|
border-radius: var(--md-sys-shape-corner-xs);
|
|
border: 1px solid var(--md-sys-color-outline-variant);
|
|
}
|
|
|
|
[data-md-showcase-swatch][data-md-showcase-size='lg'] {
|
|
width: var(--md-sys-measurement-space400);
|
|
height: var(--md-sys-measurement-space400);
|
|
}
|
|
|
|
/* Lets the role name beside a swatch ellipsize inside its row instead of widening the grid. */
|
|
[data-md-showcase-swatch-label] {
|
|
min-width: 0;
|
|
}
|
|
|
|
/* Type: one typescale style beside its label and its emphasized twin, a row of the surface
|
|
they share. A single column below `expanded` (840px), where the label, the regular sample
|
|
and the emphasized one no longer fit a line each. */
|
|
[data-md-showcase-type-row] {
|
|
display: grid;
|
|
gap: var(--md-sys-measurement-space100);
|
|
padding: var(--md-sys-measurement-space200);
|
|
}
|
|
|
|
[data-md-showcase-type-row] + [data-md-showcase-type-row] {
|
|
border-top: 1px solid var(--md-sys-color-outline-variant);
|
|
}
|
|
|
|
@media (width >= 840px) {
|
|
[data-md-showcase-type-row] {
|
|
grid-template-columns: 192px 1fr 1fr;
|
|
align-items: baseline;
|
|
}
|
|
}
|
|
|
|
/* 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. */
|
|
[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;
|
|
align-items: center;
|
|
justify-content: center;
|
|
height: 96px;
|
|
border-radius: var(--md-sys-shape-corner-md);
|
|
background-color: var(--md-sys-color-surface-container-high);
|
|
}
|
|
|
|
[data-md-showcase-elevation-tile][data-md-elevation='1'] {
|
|
box-shadow: var(--md-sys-elevation-1);
|
|
}
|
|
|
|
[data-md-showcase-elevation-tile][data-md-elevation='2'] {
|
|
box-shadow: var(--md-sys-elevation-2);
|
|
}
|
|
|
|
[data-md-showcase-elevation-tile][data-md-elevation='3'] {
|
|
box-shadow: var(--md-sys-elevation-3);
|
|
}
|
|
|
|
[data-md-showcase-elevation-tile][data-md-elevation='4'] {
|
|
box-shadow: var(--md-sys-elevation-4);
|
|
}
|
|
|
|
[data-md-showcase-elevation-tile][data-md-elevation='5'] {
|
|
box-shadow: var(--md-sys-elevation-5);
|
|
}
|
|
|
|
/* Motion: one spring's row (its name, and a track the dot travels), and the dot itself — its
|
|
colour is decoration, its size is the only thing this file fixes; the transition is the
|
|
spring under test, so it stays the view's own inline style. */
|
|
[data-md-showcase-motion-row] {
|
|
display: grid;
|
|
grid-template-columns: 144px 1fr;
|
|
align-items: center;
|
|
gap: var(--md-sys-measurement-space200);
|
|
}
|
|
|
|
[data-md-showcase-motion-track] {
|
|
height: var(--md-sys-measurement-space400);
|
|
}
|
|
|
|
[data-md-showcase-motion-dot] {
|
|
width: var(--md-sys-measurement-space400);
|
|
height: var(--md-sys-measurement-space400);
|
|
border-radius: var(--md-sys-shape-corner-full);
|
|
background-color: var(--md-sys-color-tertiary);
|
|
}
|
|
|
|
/* Icons: one search result's mask (its `mask` shorthand is the fetched symbol, so it stays the
|
|
view's own x-bind:style), 24px by default and 20px once optical size 20 is on — the state a
|
|
script toggles as data-md-showcase-icon-size, never a class. */
|
|
[data-md-showcase-icon-mask] {
|
|
display: block;
|
|
width: 24px;
|
|
height: 24px;
|
|
background-color: currentColor;
|
|
}
|
|
|
|
[data-md-showcase-icon-mask][data-md-showcase-icon-size='20'] {
|
|
width: 20px;
|
|
height: 20px;
|
|
}
|
|
|
|
/* Layout: the five breakpoint cards, each lit by the same range query the layout components'
|
|
own stylesheets use, so the page proves the breakpoints rather than only describing them. */
|
|
[data-md-showcase-breakpoint-card] {
|
|
border-radius: var(--md-sys-shape-corner-md);
|
|
background-color: var(--md-sys-color-surface-container);
|
|
padding: var(--md-sys-measurement-space200);
|
|
}
|
|
|
|
@media (width < 600px) {
|
|
[data-md-showcase-breakpoint-card='compact'] {
|
|
background-color: var(--md-sys-color-primary-container);
|
|
color: var(--md-sys-color-on-primary-container);
|
|
}
|
|
}
|
|
|
|
@media (600px <= width < 840px) {
|
|
[data-md-showcase-breakpoint-card='medium'] {
|
|
background-color: var(--md-sys-color-primary-container);
|
|
color: var(--md-sys-color-on-primary-container);
|
|
}
|
|
}
|
|
|
|
@media (840px <= width < 1200px) {
|
|
[data-md-showcase-breakpoint-card='expanded'] {
|
|
background-color: var(--md-sys-color-primary-container);
|
|
color: var(--md-sys-color-on-primary-container);
|
|
}
|
|
}
|
|
|
|
@media (1200px <= width < 1600px) {
|
|
[data-md-showcase-breakpoint-card='large'] {
|
|
background-color: var(--md-sys-color-primary-container);
|
|
color: var(--md-sys-color-on-primary-container);
|
|
}
|
|
}
|
|
|
|
@media (width >= 1600px) {
|
|
[data-md-showcase-breakpoint-card='extra-large'] {
|
|
background-color: var(--md-sys-color-primary-container);
|
|
color: var(--md-sys-color-on-primary-container);
|
|
}
|
|
}
|
|
|
|
/* Buttons: the loading indicator sized and coloured beyond its 48px primary default, and the
|
|
bounded box a FAB menu opens into (M3 anchors it to a scaffold's own corner; this is only
|
|
room enough to show the menu open). */
|
|
[data-md-showcase-loading='lg'] {
|
|
width: 96px;
|
|
height: 96px;
|
|
color: var(--md-sys-color-tertiary);
|
|
}
|
|
|
|
[data-md-showcase-loading='sm'] {
|
|
width: 32px;
|
|
height: 32px;
|
|
}
|
|
|
|
[data-md-showcase-fab-menu-demo] {
|
|
display: flex;
|
|
align-items: flex-end;
|
|
justify-content: flex-end;
|
|
height: 288px;
|
|
}
|
|
|
|
/* Menus: an item's icon in a colour beyond the fixed md-ink-* set (icon-class covers the
|
|
roles that set already has, md-ink-info among them). */
|
|
[data-md-showcase-icon-color='tertiary'] [data-md-icon] {
|
|
color: var(--md-sys-color-tertiary);
|
|
}
|
|
|
|
[data-md-showcase-icon-color='secondary'] [data-md-icon] {
|
|
color: var(--md-sys-color-secondary);
|
|
}
|
|
|
|
/* Communication: the "plain" badge's own colours (that variant draws none, by design, so the
|
|
caller paints it), a focus ring's corner on a plain span standing in for a control, and the
|
|
illustration's two decorative colours beyond currentColor. */
|
|
[data-md-showcase-badge-plain] {
|
|
background-color: var(--md-sys-color-primary-fixed);
|
|
color: var(--md-sys-color-on-primary-fixed);
|
|
}
|
|
|
|
[data-md-showcase-focus-demo] {
|
|
border-radius: var(--md-sys-shape-corner-xs);
|
|
}
|
|
|
|
[data-md-showcase-illustration='container'] {
|
|
fill: var(--md-sys-color-primary-container);
|
|
}
|
|
|
|
[data-md-showcase-illustration='accent'] {
|
|
fill: var(--md-sys-color-tertiary);
|
|
}
|
|
|
|
[data-md-showcase-illustration='on-accent'] {
|
|
fill: var(--md-sys-color-on-tertiary);
|
|
}
|
|
|
|
/* Progress: one circular indicator drawn larger than its 48px default, to show the ring
|
|
scales with its box. */
|
|
[data-md-showcase-progress-lg] {
|
|
width: 96px;
|
|
height: 96px;
|
|
}
|
|
|
|
/* Chips: a row narrow enough that its set has to scroll, to show the fade and the arrow
|
|
buttons M3 asks an overflowing row for. */
|
|
[data-md-showcase-chip-scroll] {
|
|
width: 100%;
|
|
max-width: 384px;
|
|
}
|
|
|
|
/* Text fields: the legend above a checkbox grid, a bordered demo card at two widths (a form,
|
|
a checkbox group), a small circular avatar for a search bar's trailing slot, and the
|
|
compact search-icon-button bar M3 uses as a secondary entry point. */
|
|
[data-md-showcase-legend] {
|
|
margin-bottom: var(--md-sys-measurement-space200);
|
|
}
|
|
|
|
[data-md-showcase-demo-card] {
|
|
width: 100%;
|
|
}
|
|
|
|
[data-md-showcase-demo-card][data-md-showcase-size='md'] {
|
|
max-width: 576px;
|
|
}
|
|
|
|
[data-md-showcase-demo-card][data-md-showcase-size='lg'] {
|
|
max-width: 672px;
|
|
}
|
|
|
|
[data-md-showcase-avatar] {
|
|
display: grid;
|
|
place-items: center;
|
|
width: var(--md-sys-measurement-space400);
|
|
height: var(--md-sys-measurement-space400);
|
|
border-radius: var(--md-sys-shape-corner-full);
|
|
background-color: var(--md-sys-color-primary-container);
|
|
color: var(--md-sys-color-on-primary-container);
|
|
}
|
|
|
|
[data-md-showcase-search-bar] {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--md-sys-measurement-space100);
|
|
border-radius: var(--md-sys-shape-corner-full);
|
|
background-color: var(--md-sys-color-surface-container-high);
|
|
padding: var(--md-sys-measurement-space50) var(--md-sys-measurement-space100);
|
|
}
|
|
|
|
[data-md-showcase-search-bar-title] {
|
|
flex: 1 1 auto;
|
|
}
|
|
}
|
|
|
|
/* A handful of call sites (<x-input>, <x-datepicker>, <x-slider>) forward only `class` and
|
|
`style` to the element that needs sizing, so these few widths are the caller's own classes
|
|
rather than data-md-showcase-* hooks — see the file header. */
|
|
.showcase-w-sm {
|
|
width: 192px;
|
|
}
|
|
|
|
.showcase-w-xs {
|
|
width: 144px;
|
|
}
|
|
|
|
.showcase-w-narrow {
|
|
max-width: 320px;
|
|
}
|