Files
livewire-material/resources/css/showcase.css
T
Andreas Reinhold / reiniandClaude Sonnet 5 295673554e Rewrite the showcase's Carousel section without Tailwind
Plan step 38 (last batch): every item's colour role pair moves from a
Tailwind bg-*/text-*/bg-linear-to-br utility string to a plain
`background-color`/`color`/`background: linear-gradient(...)` inline
style built from --md-sys-color-* tokens (the same "caller's own
style" mechanism as the foundation pages' colour swatch), and each
<x-shape> takes its px size as a prop instead of a size-* class.
data-md-showcase-carousel-swatch only sizes and centres the shape
inside the item.

Every #carousel id and data-md-carousel-item/multi-aspect selector the
Chromium CarouselTest reads is unchanged.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9
2026-09-15 05:32:15 +02:00

501 lines
19 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.
*
* Batch 4 (the last: containment, carousel, bars, navigation, pages) adds the standard side
* sheet demo's own breakpoint (a `<x-row>` beats its own `stack-below` alignment back to `stretch`
* once collapsed to a column, which an `align` the row mode needs would otherwise leave
* shrink-wrapped), a bordered app-bar/toolbar frame (plain, `visible` for the search bar whose
* docked suggestions must not clip, `rounded` for the large-screen docked toolbar), a narrow
* scrollable-tabs box, and the navigation bar and rail demo frames (`bar`, `bar-wide` inside its
* own horizontal-scroll wrapper, `rail`, `rail-wide`) with their filler "page" and content panes.
* Every per-item carousel colour stays the caller's own inline `style`, the same mechanism as the
* colour swatch above.
*/
@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;
}
/* Data: the table's own horizontal scroll stays the caller's, as table.css's header says. */
[data-md-showcase-table-scroll] {
width: 100%;
overflow-x: auto;
}
/* Containment: the standard side sheet demo is a row from `expanded` (840px), M3's own
condition for a co-planar sheet, and a column below it — `<x-row>`'s own `stack-below`
stacks it there, but leaves the `align="start"` the row layout needs (so the sheet does not
stretch to the text column's height) in place, which would otherwise shrink-wrap both
columns instead of stacking them full width. */
@media (width < 840px) {
[data-md-showcase-side-sheet-demo] {
align-items: stretch;
}
}
/* Carousel: an item's own colour is the caller's inline `style` (its role pair is chosen per
item), the same mechanism as the colour swatch above; this only sizes and centres it. */
[data-md-showcase-carousel-swatch] {
display: grid;
place-items: center;
width: 100%;
height: 100%;
}
}
/* 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;
}
/* <x-slider> forwards only class, style and wire:key to its wrapper, which the label and hint
share with the track — so the vertical demo's shared height is a class too. */
.showcase-slider-vertical {
height: 256px;
}