Files
Andreas Reinhold / reiniandClaude Opus 5 54d88ebc3b Correct three containment headers
Plan step 36 review. The list's header sent dividers to list.css, which
list-item.css draws since 9ff5a7a8; the carousel item's label overlay
shows the `label` prop, not the "n of m" name; the dialog's 560/280px
are its maximum and minimum width, in that order.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9
2026-09-14 22:08:05 +02:00

113 lines
4.9 KiB
CSS
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* <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).
*
* [data-md-carousel-item] the tab stop (C-18), 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
* [data-md-carousel-label-text]
*
* The item renders the shared `md-focus-ring` class (foundation/interaction.css) rather than a
* hand-rolled ring — the box the class draws *is* the item's own whole hit area — refined here to
* an inset ring, 3px in, its own width (the old `focus-visible:-outline-offset-3`): items sit 8px
* apart with the row clipping them, so the class's own 2px *outward* offset would be cut off at the
* row's edges and crowd the next item.
*
* Full-screen: edge to edge, no corner, no mask — `--material-carousel-shift`/`-inset` go unread.
* Multi-aspect: the view writes the item's own `aspect-ratio` inline (`aspect`, a prop, held
* inside M3's 9:1616:9 range); the extra-large corner still applies but nothing masks it, since
* an Arrangement describes items of one size and a multi-aspect row has none. Selectors use `>`
* throughout, matching carousel.css, so a carousel nested inside an item never inherits its
* parent's layout rules.
*
* 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).
*/
@layer material.reset, material.tokens, material.base, material.layout, material.components, material.text, material.visibility;
@layer material.components {
[data-md-carousel-item] {
position: relative;
height: 100%;
flex-shrink: 0;
scroll-snap-align: start;
scroll-snap-stop: always;
}
[data-md-carousel-item]:focus-visible {
outline-offset: -3px;
}
[data-md-carousel='full-screen'] > [data-md-carousel-scroller] > [data-md-carousel-item] {
width: 100%;
}
[data-md-carousel='multi-aspect'] > [data-md-carousel-scroller] > [data-md-carousel-item] {
width: auto;
border-radius: var(--md-sys-shape-corner-xl);
}
[data-md-carousel]:not([data-md-carousel='full-screen']):not([data-md-carousel='multi-aspect']) > [data-md-carousel-scroller] > [data-md-carousel-item] {
width: var(--material-carousel-slot);
max-width: 100%;
border-radius: var(--md-sys-shape-corner-xl);
}
[data-md-carousel-item] > [data-md-carousel-surface] {
position: relative;
width: 100%;
height: 100%;
overflow: hidden;
background-color: var(--md-sys-color-surface-container-highest);
color: var(--md-sys-color-on-surface);
}
[data-md-carousel='multi-aspect'] > [data-md-carousel-scroller] > [data-md-carousel-item] > [data-md-carousel-surface] {
border-radius: var(--md-sys-shape-corner-xl);
}
[data-md-carousel]:not([data-md-carousel='full-screen']):not([data-md-carousel='multi-aspect']) > [data-md-carousel-scroller] > [data-md-carousel-item] > [data-md-carousel-surface] {
border-radius: var(--md-sys-shape-corner-xl);
translate: var(--material-carousel-shift) 0;
clip-path: inset(0 var(--material-carousel-inset, 0px) round var(--md-sys-shape-corner-xl));
}
[data-md-carousel-surface] > [data-md-carousel-content] {
width: 100%;
height: 100%;
& > img {
width: 100%;
height: 100%;
object-fit: cover;
}
}
[data-md-carousel-surface] > [data-md-carousel-label] {
pointer-events: none;
position: absolute;
inset-inline: 0;
bottom: 0;
display: flex;
padding: var(--md-sys-measurement-space500) var(--md-sys-measurement-space200) var(--md-sys-measurement-space200);
background: linear-gradient(to top, color-mix(in srgb, var(--md-sys-color-scrim) 60%, transparent), transparent);
opacity: var(--material-carousel-label);
}
[data-md-carousel-label] > [data-md-carousel-label-text] {
overflow: hidden;
color: white;
font: var(--md-sys-typescale-title-md);
letter-spacing: var(--md-sys-typescale-title-md-tracking);
text-overflow: ellipsis;
white-space: nowrap;
translate: var(--material-carousel-label-shift) 0;
}
}