2.0.0 took Tailwind out of the stack, but the texts Boost copies into every application still taught its utilities: the core guideline said "built on Tailwind CSS", the always-on material-3 guideline wrote every rule as `bg-primary`, `type-*`, `rounded-corner-*`, `state-layer` and `medium:`, and both skills' tables and examples did the same. None of those classes exists in 2.0's stylesheets, so an agent following the guideline wrote markup that compiled to nothing. Found moving ReStride onto 2.0: its CLAUDE.md, and SealShare's, carry these texts. The guidelines and skills now teach what 2.0 has: component and layout component props (`gap="space200"`, `hide-from="medium"`), the `md-type-*`, `md-ink-*` and interaction classes, and `--md-sys-*` tokens in the application's own CSS, with breakpoints as range media queries. UPGRADE.md §1, §2 and §4 describe the finished move instead of the in-between state, and header comments that pointed at the removed tokens/utilities.css and tailwind.css, or called a component "still Tailwind", say what is true now. BoostVocabularyTest runs DesignGuard over the code in every shipped guideline and skill (fenced Blade and CSS, and each inline class list), so a text that teaches a class the stylesheets do not define fails the suite; it finds 268 violations in the texts as 2.0.0 shipped them. The guard's own table of what it reports is exempt. BoostResourcesTest now asks the design skill for each breakpoint's prop value and media query instead of the removed `medium:` variants. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
330 lines
11 KiB
CSS
330 lines
11 KiB
CSS
/*
|
|
* 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 their own text.
|
|
*
|
|
* 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-mono the monospace typeface (`--md-ref-typeface-mono`), for a value read
|
|
* character by character outside `<code>`; after an `md-type-*` class,
|
|
* whose `font` would otherwise set the brand face
|
|
* 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.
|
|
*/
|
|
|
|
@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-mono {
|
|
font-family: var(--md-ref-typeface-mono);
|
|
}
|
|
|
|
.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;
|
|
}
|
|
}
|