diff --git a/resources/css/foundation.css b/resources/css/foundation.css index ff936aaf..6409a60c 100644 --- a/resources/css/foundation.css +++ b/resources/css/foundation.css @@ -35,3 +35,4 @@ @import './foundation/tokens.css'; @import './foundation/base.css'; @import './foundation/interaction.css'; +@import './text.css'; diff --git a/resources/css/text.css b/resources/css/text.css new file mode 100644 index 00000000..ce14f112 --- /dev/null +++ b/resources/css/text.css @@ -0,0 +1,323 @@ +/* + * The text classes: a fixed, documented set for text on plain elements. A component sets its own + * type and ink; these are for the headings, paragraphs and captions an application writes around + * them, and the set the package's own views use for text once they leave Tailwind. + * + * Type — one per text element, the whole style at once (size, line height, weight, tracking; + * tokens/type.css), never assembled by hand. Roles from docs/reference/m3/styles.md § Typography: + * + * md-type-display-{lg|md|sm} the largest text on a screen: short, important text or numerals, + * best on large screens + * md-type-headline-{lg|md|sm} short, high-emphasis text: page and section titles + * md-type-title-{lg|md|sm} medium-emphasis, relatively short text: card, dialog and + * list-section titles + * md-type-body-{lg|md|sm} longer passages and paragraphs; body-lg for reading + * md-type-label-{lg|md|sm} small, utilitarian text inside components, and captions + * + * `md-type-emphasized-*` is the same style one weight step heavier and fully rounded, with its own + * tracking. M3's components do not use it by default: it is a deliberate choice for a selected + * item, a primary action, a headline or a badge, not decoration. `font-variation-settings` + * inherits, so every regular class resets it and body copy inside an emphasized heading reads as + * itself again. The heading level is structure; the class is appearance. + * + * Ink — an M3 role, never an opacity (38% means disabled): + * + * md-ink on-surface: default text + * md-ink-variant on-surface-variant: lower emphasis — secondary text, metadata + * md-ink-quiet outline: decoration only, never text that must be read + * md-ink-primary primary: a link, together with `md-link` + * md-ink-error error: the text of an error + * md-ink-success, md-ink-warning, md-ink-info: the text of that state, and nothing else + * md-ink-inverse inverse-on-surface: text on an inverse surface (a snackbar) + * + * On a container, the ink is the container's `on-` role, which the component sets; these inks are + * for the surface roles. + * + * Layout of text: + * + * md-text-start|center|end logical alignment, so it turns with the writing direction + * md-truncate one line with an ellipsis — only where the whole text can be read + * elsewhere, because M3's text must scale to 200% without loss + * md-line-clamp-2|3 at most two or three lines, the same caveat + * md-nowrap never wraps: a figure with its unit, a short label + * md-tabular tabular figures, where digits change often (tables, clocks, + * counters), so the layout does not shift + * md-visually-hidden read by assistive technology, not drawn: a label a picture already + * gives the eye + * + * In `material.text`, above every component: a text class on a component's root or on an element + * inside it wins over the component's own type and ink. The `md-type-*` declarations are the + * `type-*` utilities' (tokens/utilities.css), which the components still written in Tailwind use. + */ + +@layer material.reset, material.tokens, material.base, material.layout, material.components, material.text, material.visibility; + +@layer material.text { + .md-type-display-lg { + font: var(--md-sys-typescale-display-lg); + letter-spacing: var(--md-sys-typescale-display-lg-tracking); + font-variation-settings: normal; + } + + .md-type-emphasized-display-lg { + font: var(--md-sys-typescale-emphasized-display-lg); + letter-spacing: var(--md-sys-typescale-emphasized-display-lg-tracking); + font-variation-settings: "ROND" 100; + } + + .md-type-display-md { + font: var(--md-sys-typescale-display-md); + letter-spacing: var(--md-sys-typescale-display-md-tracking); + font-variation-settings: normal; + } + + .md-type-emphasized-display-md { + font: var(--md-sys-typescale-emphasized-display-md); + letter-spacing: var(--md-sys-typescale-emphasized-display-md-tracking); + font-variation-settings: "ROND" 100; + } + + .md-type-display-sm { + font: var(--md-sys-typescale-display-sm); + letter-spacing: var(--md-sys-typescale-display-sm-tracking); + font-variation-settings: normal; + } + + .md-type-emphasized-display-sm { + font: var(--md-sys-typescale-emphasized-display-sm); + letter-spacing: var(--md-sys-typescale-emphasized-display-sm-tracking); + font-variation-settings: "ROND" 100; + } + + .md-type-headline-lg { + font: var(--md-sys-typescale-headline-lg); + letter-spacing: var(--md-sys-typescale-headline-lg-tracking); + font-variation-settings: normal; + } + + .md-type-emphasized-headline-lg { + font: var(--md-sys-typescale-emphasized-headline-lg); + letter-spacing: var(--md-sys-typescale-emphasized-headline-lg-tracking); + font-variation-settings: "ROND" 100; + } + + .md-type-headline-md { + font: var(--md-sys-typescale-headline-md); + letter-spacing: var(--md-sys-typescale-headline-md-tracking); + font-variation-settings: normal; + } + + .md-type-emphasized-headline-md { + font: var(--md-sys-typescale-emphasized-headline-md); + letter-spacing: var(--md-sys-typescale-emphasized-headline-md-tracking); + font-variation-settings: "ROND" 100; + } + + .md-type-headline-sm { + font: var(--md-sys-typescale-headline-sm); + letter-spacing: var(--md-sys-typescale-headline-sm-tracking); + font-variation-settings: normal; + } + + .md-type-emphasized-headline-sm { + font: var(--md-sys-typescale-emphasized-headline-sm); + letter-spacing: var(--md-sys-typescale-emphasized-headline-sm-tracking); + font-variation-settings: "ROND" 100; + } + + .md-type-title-lg { + font: var(--md-sys-typescale-title-lg); + letter-spacing: var(--md-sys-typescale-title-lg-tracking); + font-variation-settings: normal; + } + + .md-type-emphasized-title-lg { + font: var(--md-sys-typescale-emphasized-title-lg); + letter-spacing: var(--md-sys-typescale-emphasized-title-lg-tracking); + font-variation-settings: "ROND" 100; + } + + .md-type-title-md { + font: var(--md-sys-typescale-title-md); + letter-spacing: var(--md-sys-typescale-title-md-tracking); + font-variation-settings: normal; + } + + .md-type-emphasized-title-md { + font: var(--md-sys-typescale-emphasized-title-md); + letter-spacing: var(--md-sys-typescale-emphasized-title-md-tracking); + font-variation-settings: "ROND" 100; + } + + .md-type-title-sm { + font: var(--md-sys-typescale-title-sm); + letter-spacing: var(--md-sys-typescale-title-sm-tracking); + font-variation-settings: normal; + } + + .md-type-emphasized-title-sm { + font: var(--md-sys-typescale-emphasized-title-sm); + letter-spacing: var(--md-sys-typescale-emphasized-title-sm-tracking); + font-variation-settings: "ROND" 100; + } + + .md-type-body-lg { + font: var(--md-sys-typescale-body-lg); + letter-spacing: var(--md-sys-typescale-body-lg-tracking); + font-variation-settings: normal; + } + + .md-type-emphasized-body-lg { + font: var(--md-sys-typescale-emphasized-body-lg); + letter-spacing: var(--md-sys-typescale-emphasized-body-lg-tracking); + font-variation-settings: "ROND" 100; + } + + .md-type-body-md { + font: var(--md-sys-typescale-body-md); + letter-spacing: var(--md-sys-typescale-body-md-tracking); + font-variation-settings: normal; + } + + .md-type-emphasized-body-md { + font: var(--md-sys-typescale-emphasized-body-md); + letter-spacing: var(--md-sys-typescale-emphasized-body-md-tracking); + font-variation-settings: "ROND" 100; + } + + .md-type-body-sm { + font: var(--md-sys-typescale-body-sm); + letter-spacing: var(--md-sys-typescale-body-sm-tracking); + font-variation-settings: normal; + } + + .md-type-emphasized-body-sm { + font: var(--md-sys-typescale-emphasized-body-sm); + letter-spacing: var(--md-sys-typescale-emphasized-body-sm-tracking); + font-variation-settings: "ROND" 100; + } + + .md-type-label-lg { + font: var(--md-sys-typescale-label-lg); + letter-spacing: var(--md-sys-typescale-label-lg-tracking); + font-variation-settings: normal; + } + + .md-type-emphasized-label-lg { + font: var(--md-sys-typescale-emphasized-label-lg); + letter-spacing: var(--md-sys-typescale-emphasized-label-lg-tracking); + font-variation-settings: "ROND" 100; + } + + .md-type-label-md { + font: var(--md-sys-typescale-label-md); + letter-spacing: var(--md-sys-typescale-label-md-tracking); + font-variation-settings: normal; + } + + .md-type-emphasized-label-md { + font: var(--md-sys-typescale-emphasized-label-md); + letter-spacing: var(--md-sys-typescale-emphasized-label-md-tracking); + font-variation-settings: "ROND" 100; + } + + .md-type-label-sm { + font: var(--md-sys-typescale-label-sm); + letter-spacing: var(--md-sys-typescale-label-sm-tracking); + font-variation-settings: normal; + } + + .md-type-emphasized-label-sm { + font: var(--md-sys-typescale-emphasized-label-sm); + letter-spacing: var(--md-sys-typescale-emphasized-label-sm-tracking); + font-variation-settings: "ROND" 100; + } + + .md-ink { + color: var(--md-sys-color-on-surface); + } + + .md-ink-variant { + color: var(--md-sys-color-on-surface-variant); + } + + .md-ink-quiet { + color: var(--md-sys-color-outline); + } + + .md-ink-primary { + color: var(--md-sys-color-primary); + } + + .md-ink-error { + color: var(--md-sys-color-error); + } + + .md-ink-success { + color: var(--md-sys-color-success); + } + + .md-ink-warning { + color: var(--md-sys-color-warning); + } + + .md-ink-info { + color: var(--md-sys-color-info); + } + + .md-ink-inverse { + color: var(--md-sys-color-inverse-on-surface); + } + + .md-text-start { + text-align: start; + } + + .md-text-center { + text-align: center; + } + + .md-text-end { + text-align: end; + } + + .md-truncate { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + .md-line-clamp-2 { + overflow: hidden; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + } + + .md-line-clamp-3 { + overflow: hidden; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 3; + } + + .md-nowrap { + white-space: nowrap; + } + + .md-tabular { + font-variant-numeric: tabular-nums; + } + + .md-visually-hidden { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip-path: inset(50%); + white-space: nowrap; + border-width: 0; + } +}