@expressivecss/expressive 0.8.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/CHANGELOG.md +48 -1
  2. package/README.md +69 -26
  3. package/dist/css/expressive.css +657 -85
  4. package/dist/css/expressive.css.map +1 -1
  5. package/dist/css/expressive.min.css +1 -1
  6. package/dist/css/expressive.min.css.map +1 -1
  7. package/dist/fonts/LICENSE-material-symbols +93 -0
  8. package/dist/fonts/LICENSE-noto-sans +93 -0
  9. package/dist/fonts/LICENSE-roboto +93 -0
  10. package/dist/fonts/material-symbols-outlined.woff2 +0 -0
  11. package/dist/fonts/material-symbols-rounded.woff2 +0 -0
  12. package/dist/fonts/material-symbols-sharp.woff2 +0 -0
  13. package/dist/fonts/noto-sans-latin-400.woff2 +0 -0
  14. package/dist/fonts/noto-sans-latin-500.woff2 +0 -0
  15. package/dist/fonts/roboto-latin-400.woff2 +0 -0
  16. package/dist/fonts/roboto-latin-500.woff2 +0 -0
  17. package/dist/js/expressive.cjs +501 -144
  18. package/dist/js/expressive.cjs.map +4 -4
  19. package/dist/js/expressive.js +501 -144
  20. package/dist/js/expressive.js.map +4 -4
  21. package/dist/js/expressive.min.js +10 -10
  22. package/dist/js/expressive.min.js.map +4 -4
  23. package/dist/js/expressive.mjs +501 -144
  24. package/dist/js/expressive.mjs.map +4 -4
  25. package/dist/types/components/appBar.d.ts +26 -0
  26. package/dist/types/components/buttonGroup.d.ts +39 -0
  27. package/dist/types/components/cards.d.ts +11 -13
  28. package/dist/types/components/expandingCard.d.ts +1 -1
  29. package/dist/types/components/index.d.ts +2 -0
  30. package/dist/types/components/menu.d.ts +4 -0
  31. package/dist/types/components/registry.d.ts +10 -0
  32. package/dist/types/components/timepicker.d.ts +0 -1
  33. package/dist/types/components/tooltip.d.ts +1 -0
  34. package/dist/types/index.d.ts +1 -1
  35. package/package.json +25 -3
  36. package/src/sass/abstracts/_mixins.scss +52 -0
  37. package/src/sass/abstracts/_variables.scss +19 -0
  38. package/src/sass/base/_fonts.scss +63 -0
  39. package/src/sass/components/_badges.scss +1 -2
  40. package/src/sass/components/_button-groups.scss +252 -80
  41. package/src/sass/components/_cards.scss +108 -93
  42. package/src/sass/components/_expanding-card.scss +1 -35
  43. package/src/sass/components/_icon-buttons.scss +2 -24
  44. package/src/sass/components/_icons-material-design.scss +6 -6
  45. package/src/sass/components/_navbar.scss +180 -27
  46. package/src/sass/components/_navigation-bar.scss +9 -1
  47. package/src/sass/components/_navigation-rail.scss +9 -1
  48. package/src/sass/components/_transitions.scss +8 -1
  49. package/src/sass/components/forms/_select.scss +38 -0
  50. package/src/sass/expressive.scss +5 -0
@@ -0,0 +1,26 @@
1
+ import { Component, BaseOptions, InitElements, InitElement } from '../core/component';
2
+ /**
3
+ * Collapse medium/large flexible app bars on scroll, and open the related
4
+ * search view when the search field in a search app bar is selected.
5
+ *
6
+ * Observation is IntersectionObserver on a 1px sentinel ahead of the header.
7
+ * A scroll listener would re-enter layout on every tick; this does not.
8
+ */
9
+ export declare class AppBar extends Component<BaseOptions> {
10
+ private _observer;
11
+ private _sentinel;
12
+ private _input;
13
+ private _view;
14
+ private _suppressSearchOpen;
15
+ constructor(el: HTMLElement, options: Partial<BaseOptions>);
16
+ static get defaults(): BaseOptions;
17
+ static init(el: HTMLElement, options?: Partial<BaseOptions>): AppBar;
18
+ static init(els: InitElements<InitElement>, options?: Partial<BaseOptions>): AppBar[];
19
+ static getInstance(el: HTMLElement): AppBar;
20
+ destroy(): void;
21
+ private _setupCollapse;
22
+ private _onIntersect;
23
+ private _setupSearch;
24
+ private _onSearchViewClose;
25
+ private _onSearchFocus;
26
+ }
@@ -0,0 +1,39 @@
1
+ import { Component, BaseOptions, InitElements, InitElement } from "../core/component";
2
+ export interface ButtonGroupOptions extends BaseOptions {
3
+ }
4
+ /**
5
+ * Coordinates Material button-group press geometry and optional toggle state.
6
+ *
7
+ * Standard groups redistribute the pressed item's 15% width growth from its
8
+ * immediate neighbors. `data-selection="single|multiple"` also enables
9
+ * `aria-pressed` state management.
10
+ */
11
+ export declare class ButtonGroup extends Component<ButtonGroupOptions> {
12
+ private _pressedStyles;
13
+ private _releaseStyles;
14
+ private _releaseTimer;
15
+ private _originalPressed;
16
+ private _activeItem;
17
+ constructor(el: HTMLElement, options?: Partial<ButtonGroupOptions>);
18
+ static get defaults(): ButtonGroupOptions;
19
+ static init(el: HTMLElement, options?: Partial<ButtonGroupOptions>): ButtonGroup;
20
+ static init(els: InitElements<InitElement>, options?: Partial<ButtonGroupOptions>): ButtonGroup[];
21
+ static getInstance(el: HTMLElement): ButtonGroup;
22
+ destroy(): void;
23
+ private get _selectionMode();
24
+ private get _items();
25
+ private get _toggleItems();
26
+ private _normalizeSelection;
27
+ private _itemFromEvent;
28
+ private _isDisabled;
29
+ private _handleClick;
30
+ private _rememberPressed;
31
+ private _handlePointerDown;
32
+ private _handleKeyDown;
33
+ private _handleKeyUp;
34
+ private _handleFocusOut;
35
+ private _startPress;
36
+ private _compressionCapacity;
37
+ private _resetPress;
38
+ private _finishRelease;
39
+ }
@@ -4,20 +4,21 @@ export interface CardsOptions extends BaseOptions {
4
4
  onClose: (el: Element) => void;
5
5
  }
6
6
  /**
7
- * What counts as a card.
7
+ * What counts as a card reveal.
8
8
  *
9
- * Shared with `components/registry.ts` rather than written out twice: the
10
- * registry used to claim `.cards`, which matches nothing this component
11
- * actually initializes, so the AutoInit entry was dead while `Cards.Init()`
12
- * quietly did the work through the selector below.
9
+ * Shared with `components/registry.ts` so `Cards.Init()` and `AutoInit()` use
10
+ * the same semantic selector.
13
11
  */
14
- export declare const CARDS_SELECTOR = "article:has(> aside)";
12
+ export declare const CARDS_SELECTOR = "article:has(> aside[id]:not([id=\"\"])):not(:has(> aside ~ aside)):has(> button.card-reveal-trigger[type=\"button\"], > :not(aside) button.card-reveal-trigger[type=\"button\"])";
13
+ export declare function isCardReveal(el: Element): el is HTMLElement;
15
14
  export declare class Cards extends Component<CardsOptions> implements Openable {
16
15
  isOpen: boolean;
17
16
  private readonly cardReveal;
18
17
  private _activators;
19
- private cardRevealClose;
20
- constructor(el: HTMLElement, options: Partial<CardsOptions>);
18
+ private _ownsRevealInitializedClass;
19
+ private _initialAriaControls;
20
+ private _lastActivator;
21
+ constructor(el: HTMLElement, options?: Partial<CardsOptions>);
21
22
  static get defaults(): CardsOptions;
22
23
  /**
23
24
  * Initializes instance of Cards.
@@ -38,12 +39,9 @@ export declare class Cards extends Component<CardsOptions> implements Openable {
38
39
  destroy(): void;
39
40
  _setupEventHandlers: () => void;
40
41
  _removeEventHandlers: () => void;
41
- _handleClickInteraction: () => void;
42
- _handleKeypressEvent: (e: KeyboardEvent) => void;
42
+ _handleClickInteraction: (event: MouseEvent) => void;
43
+ _handleKeydownEvent: (event: KeyboardEvent) => void;
43
44
  _handleRevealEvent: () => void;
44
- _setupRevealCloseEventHandlers: () => void;
45
- _removeRevealCloseEventHandlers: () => void;
46
- _handleKeypressCloseEvent: (e: KeyboardEvent) => void;
47
45
  /**
48
46
  * Show card reveal.
49
47
  */
@@ -12,7 +12,7 @@ export declare class ExpandingCard extends Component<ExpandingCardOptions> imple
12
12
  private readonly trigger;
13
13
  private readonly dialog;
14
14
  private readonly closeButton;
15
- private closeTimer;
15
+ private closeGeneration;
16
16
  constructor(el: HTMLElement, options: Partial<ExpandingCardOptions>);
17
17
  static get defaults(): ExpandingCardOptions;
18
18
  static init(el: HTMLElement, options?: Partial<ExpandingCardOptions>): ExpandingCard;
@@ -1,5 +1,7 @@
1
1
  export { Autocomplete } from "./autocomplete";
2
+ export { AppBar } from "./appBar";
2
3
  export { FloatingActionButton } from "./buttons";
4
+ export { ButtonGroup } from "./buttonGroup";
3
5
  export { Cards } from "./cards";
4
6
  export { ExpandingCard } from "./expandingCard";
5
7
  export { Carousel } from "./carousel";
@@ -91,6 +91,8 @@ export declare class Menu extends Component<MenuOptions> implements Openable {
91
91
  focusedIndex: number;
92
92
  filterQuery: string[];
93
93
  filterTimeout: ReturnType<typeof setTimeout>;
94
+ private _pendingTimers;
95
+ private _transition;
94
96
  constructor(el: HTMLElement, options: Partial<MenuOptions>);
95
97
  static get defaults(): MenuOptions;
96
98
  /**
@@ -145,6 +147,8 @@ export declare class Menu extends Component<MenuOptions> implements Openable {
145
147
  height: number;
146
148
  width: number;
147
149
  };
150
+ private _schedule;
151
+ private _clearPendingTimers;
148
152
  _animateIn(): void;
149
153
  _animateOut(): void;
150
154
  private _getClosestAncestor;
@@ -1,4 +1,5 @@
1
1
  import * as Components from "./index";
2
+ import { isCardReveal } from "./cards";
2
3
  /**
3
4
  * The components `AutoInit()` starts, in initialization order, with the
4
5
  * selector each one claims.
@@ -13,13 +14,22 @@ import * as Components from "./index";
13
14
  * CharacterCounter, Range, ...) simply stays out of this table.
14
15
  */
15
16
  export declare const AUTO_INIT_COMPONENTS: {
17
+ AppBar: {
18
+ component: typeof Components.AppBar;
19
+ selector: string;
20
+ };
16
21
  Autocomplete: {
17
22
  component: typeof Components.Autocomplete;
18
23
  selector: string;
19
24
  };
25
+ ButtonGroup: {
26
+ component: typeof Components.ButtonGroup;
27
+ selector: string;
28
+ };
20
29
  Cards: {
21
30
  component: typeof Components.Cards;
22
31
  selector: string;
32
+ filter: typeof isCardReveal;
23
33
  };
24
34
  ExpandingCard: {
25
35
  component: typeof Components.ExpandingCard;
@@ -165,7 +165,6 @@ export declare class Timepicker extends Component<TimepickerOptions> {
165
165
  _removeEventHandlers(): void;
166
166
  _handleInputClick: () => void;
167
167
  _handleInputKeydown: (e: KeyboardEvent) => void;
168
- _handleTimeInputEnterKey: (e: KeyboardEvent) => void;
169
168
  _handleClockClickStart: (e: PointerEvent) => void;
170
169
  _handleDocumentClickMove: (e: PointerEvent) => void;
171
170
  _handleDocumentClickEnd: (e: PointerEvent) => void;
@@ -69,6 +69,7 @@ export declare class Tooltip extends Component<TooltipOptions> {
69
69
  tooltipEl: HTMLElement;
70
70
  private _exitDelayTimeout;
71
71
  private _enterDelayTimeout;
72
+ private _animationTimeout;
72
73
  xMovement: number;
73
74
  yMovement: number;
74
75
  constructor(el: HTMLElement, options: Partial<TooltipOptions>);
@@ -5,4 +5,4 @@ export { SideSheets } from "./behaviors/sideSheets";
5
5
  export { Forms } from "./behaviors/forms";
6
6
  export { AutoInit } from "./components/registry";
7
7
  export type { AutoInitOptions } from "./components/registry";
8
- export declare const version = "0.8.0";
8
+ export declare const version = "0.9.0";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@expressivecss/expressive",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "description": "ExpressiveCSS - a Material Design 3 front-end framework.",
5
5
  "license": "MIT",
6
6
  "author": "BaezFJ <baezdevs@gmail.com>",
@@ -45,6 +45,7 @@
45
45
  },
46
46
  "./css": "./dist/css/expressive.css",
47
47
  "./css/min": "./dist/css/expressive.min.css",
48
+ "./fonts/*": "./dist/fonts/*",
48
49
  "./scss": "./src/sass/expressive.scss",
49
50
  "./scss/*": "./src/sass/*"
50
51
  },
@@ -60,7 +61,8 @@
60
61
  "prepack": "npm run build",
61
62
  "clean": "node -e \"require('fs').rmSync('dist', { recursive: true, force: true })\"",
62
63
  "build": "run-s clean build:css build:js build:types",
63
- "build:css": "run-s build:css:expanded build:css:min",
64
+ "build:fonts": "node scripts/copy-fonts.mjs",
65
+ "build:css": "run-s build:fonts build:css:expanded build:css:min",
64
66
  "build:css:expanded": "sass src/sass/expressive.scss dist/css/expressive.css --style=expanded --source-map --load-path=src/sass",
65
67
  "build:css:min": "sass src/sass/expressive.scss dist/css/expressive.min.css --style=compressed --source-map --load-path=src/sass",
66
68
  "build:js": "run-s build:js:esm build:js:cjs build:js:iife build:js:iife-min",
@@ -69,7 +71,11 @@
69
71
  "build:js:iife": "esbuild src/ts/index.ts --bundle --format=iife --global-name=Expressive --target=es2020 --outfile=dist/js/expressive.js --sourcemap",
70
72
  "build:js:iife-min": "esbuild src/ts/index.ts --bundle --format=iife --global-name=Expressive --target=es2020 --outfile=dist/js/expressive.min.js --minify --sourcemap",
71
73
  "build:types": "tsc -p tsconfig.build.json",
74
+ "build:skill": "node scripts/gen-expressivecss-skill.mjs && node mcp/expressivecss/scripts/sync-guides.mjs",
72
75
  "build:semantics": "node scripts/gen-semantics.mjs",
76
+ "resolve:expressivecss": "node skills/expressivecss/scripts/resolve-version.mjs",
77
+ "test:skill": "node --test tests/expressivecss-skill.test.js tests/expressivecss-version-resolution.test.js tests/expressivecss-component-decisions.test.js tests/expressivecss-skill-evals.test.js tests/expressivecss-codex-adapter.test.js tests/expressivecss-skill-benchmark.test.js tests/expressivecss-eval-browser.test.js tests/expressivecss-interface-quality.test.js tests/expressivecss-material-quality.test.js tests/expressivecss-eval-provenance.test.js tests/expressivecss-natural-discovery.test.js && npm run test:skill-evals",
78
+ "test:skill-evals": "node scripts/eval-expressivecss-skill.mjs --responses=tests/fixtures/expressivecss-skill-evals/passing-responses.json",
73
79
  "docs:dev": "run-s build docs:watch",
74
80
  "docs:watch": "run-p watch:css watch:js docs:server",
75
81
  "docs:server": "astro dev --root docs",
@@ -80,12 +86,21 @@
80
86
  "typecheck": "tsc -p tsconfig.json --noEmit",
81
87
  "test": "run-s build:js build:css test:run",
82
88
  "test:run": "node --test",
89
+ "test:browser": "run-s build:js build:css test:browser:run",
90
+ "test:browser:critical": "node scripts/check-browser.mjs && node --test tests/expressivecss-cross-browser.test.js",
91
+ "test:browser:run": "node scripts/check-browser.mjs && node --test tests/*-browser.test.js",
83
92
  "test:watch": "node --test --watch",
84
93
  "test:visual": "node visual/run.mjs",
85
94
  "test:visual:report": "playwright show-report visual/report",
86
95
  "watch": "run-p watch:css watch:js",
87
96
  "watch:css": "sass --watch src/sass/expressive.scss:dist/css/expressive.css --style=expanded --source-map --load-path=src/sass",
88
- "watch:js": "esbuild src/ts/index.ts --bundle --format=iife --global-name=Expressive --target=es2020 --outfile=dist/js/expressive.js --sourcemap --watch=forever"
97
+ "watch:js": "esbuild src/ts/index.ts --bundle --format=iife --global-name=Expressive --target=es2020 --outfile=dist/js/expressive.js --sourcemap --watch=forever",
98
+ "check:generated": "node scripts/gen-semantics.mjs --check && node scripts/gen-expressivecss-skill.mjs --check && node mcp/expressivecss/scripts/sync-guides.mjs --check",
99
+ "verify": "run-s build typecheck test:run check:generated docs:build:astro docs:verify",
100
+ "verify:packages": "node scripts/verify-packages.mjs",
101
+ "test:node": "node scripts/run-node-tests.mjs",
102
+ "record:capabilities": "node scripts/record-capability-evidence.mjs --record",
103
+ "verify:consumer": "node scripts/lib/verify-consumer.mjs"
89
104
  },
90
105
  "engines": {
91
106
  "node": ">=20"
@@ -97,12 +112,19 @@
97
112
  "not dead"
98
113
  ],
99
114
  "devDependencies": {
115
+ "@fontsource-variable/material-symbols-outlined": "^5.3.4",
116
+ "@fontsource-variable/material-symbols-rounded": "^5.3.4",
117
+ "@fontsource-variable/material-symbols-sharp": "^5.3.4",
118
+ "@fontsource/noto-sans": "^5.3.0",
119
+ "@fontsource/roboto": "^5.3.0",
100
120
  "@playwright/test": "^1.56.0",
101
121
  "astro": "^7.2.8",
102
122
  "esbuild": "^0.28.2",
123
+ "fallow": "^3.23.0",
103
124
  "jsdom": "^30.0.1",
104
125
  "npm-run-all2": "^9.0.3",
105
126
  "sass": "^1.102.0",
127
+ "smol-toml": "^1.8.0",
106
128
  "turndown": "^7.2.4",
107
129
  "turndown-plugin-gfm": "^1.0.2",
108
130
  "typescript": "^7.0.2"
@@ -251,3 +251,55 @@ $_state-layers: ("hover", "focus", "pressed", "dragged");
251
251
  --md-comp-filled-button-icon-label-space: #{map.get($s, gap)};
252
252
  --md-comp-filled-button-outline-width: #{map.get($s, outline)};
253
253
  }
254
+
255
+ /// The icon-button tokens for one rung of `$icon-button-sizes`.
256
+ @mixin icon-button-size($name) {
257
+ $s: map.get($icon-button-sizes, $name);
258
+
259
+ --md-comp-icon-button-container-height: #{map.get($s, height)};
260
+ --md-comp-icon-button-icon-size: #{map.get($s, icon)};
261
+ --md-comp-icon-button-leading-space: #{map.get($s, space)};
262
+ --md-comp-icon-button-trailing-space: #{map.get($s, space)};
263
+ --md-comp-icon-button-narrow-space: #{map.get($s, narrow)};
264
+ --md-comp-icon-button-wide-space: #{map.get($s, wide)};
265
+ --md-comp-icon-button-container-shape-square: #{map.get($s, square)};
266
+ --md-comp-icon-button-pressed-container-shape: #{map.get($s, pressed)};
267
+ --md-comp-icon-button-outline-width: #{map.get($s, outline)};
268
+ }
269
+
270
+ // Media-covering triggers share the card state layer and focus indicator.
271
+ @mixin card-media-trigger {
272
+ position: absolute;
273
+ inset: 0;
274
+ z-index: 1;
275
+ display: block;
276
+ width: 100%;
277
+ height: 100%;
278
+ min-width: 0;
279
+ min-height: 0;
280
+ margin: 0;
281
+ padding: 0;
282
+ background: none;
283
+ border: 0;
284
+ border-radius: inherit;
285
+ box-shadow: none;
286
+ color: transparent;
287
+ cursor: pointer;
288
+
289
+ &:hover {
290
+ background-color: color-mix(in oklab, var(--md-comp-card-state-layer-color) calc(var(--md-comp-card-hover-state-layer-opacity) * 100%), transparent);
291
+ box-shadow: none;
292
+ }
293
+
294
+ &:focus-visible {
295
+ background-color: color-mix(in oklab, var(--md-comp-card-state-layer-color) calc(var(--md-comp-card-focus-state-layer-opacity) * 100%), transparent);
296
+ box-shadow: none;
297
+ outline: var(--md-comp-card-focus-indicator-thickness) solid var(--md-comp-card-focus-indicator-color);
298
+ outline-offset: calc(-1 * var(--md-comp-card-focus-indicator-thickness));
299
+ }
300
+
301
+ &:active {
302
+ background-color: color-mix(in oklab, var(--md-comp-card-state-layer-color) calc(var(--md-comp-card-pressed-state-layer-opacity) * 100%), transparent);
303
+ box-shadow: none;
304
+ }
305
+ }
@@ -64,6 +64,14 @@ $element-bottom-margin: math.div($gutter-width * 2, 3) !default;
64
64
  // M3's typeface tokens choose Roboto by default. Noto Sans is the first
65
65
  // fallback so unsupported scripts keep a compatible visual style.
66
66
  $font-stack: var(--md-ref-typeface-plain), var(--md-ref-typeface-fallback) !default;
67
+
68
+ // Self-hosted woff2 directory, relative to the compiled CSS file. The npm
69
+ // build writes CSS to dist/css/ and fonts to dist/fonts/. Override when
70
+ // compiling Sass to a different location. Set $expressive-include-fonts to
71
+ // false to emit no @font-face rules (for example when the page already
72
+ // loads these families from elsewhere).
73
+ $expressive-font-path: "../fonts" !default;
74
+ $expressive-include-fonts: true !default;
67
75
  $text-color: var(--md-sys-color-on-background) !default;
68
76
 
69
77
  // Modern browsers default to 16px. M3's web conversion is SP_SIZE / 16 = rem;
@@ -104,3 +112,14 @@ $button-sizes: (
104
112
  "large": (height: 96px, icon: 32px, space: 48px, gap: 12px, outline: 2px, label: "headline-small"),
105
113
  "xlarge": (height: 136px, icon: 40px, space: 64px, gap: 16px, outline: 3px, label: "headline-large"),
106
114
  );
115
+
116
+ // Icon-button geometry is shared with button groups. A group-size class must
117
+ // reach both common buttons and icon buttons without asking authors to repeat
118
+ // the size on every child.
119
+ $icon-button-sizes: (
120
+ "xsmall": (height: 32px, icon: 20px, space: 6px, narrow: 4px, wide: 10px, square: 12px, pressed: 8px, outline: 1px),
121
+ "small": (height: 40px, icon: 24px, space: 8px, narrow: 4px, wide: 14px, square: 12px, pressed: 8px, outline: 1px),
122
+ "medium": (height: 56px, icon: 24px, space: 16px, narrow: 12px, wide: 24px, square: 16px, pressed: 12px, outline: 1px),
123
+ "large": (height: 96px, icon: 32px, space: 32px, narrow: 16px, wide: 48px, square: 28px, pressed: 16px, outline: 2px),
124
+ "xlarge": (height: 136px, icon: 40px, space: 48px, narrow: 32px, wide: 72px, square: 28px, pressed: 16px, outline: 3px),
125
+ );
@@ -0,0 +1,63 @@
1
+ @use "../abstracts" as *;
2
+
3
+ // Self-hosted faces for the families the tokens and icon classes name.
4
+ // Unlayered on purpose: @font-face inside a cascade layer is unreliable.
5
+ // $expressive-font-path is relative to the compiled CSS (dist/css -> dist/fonts).
6
+
7
+ @if $expressive-include-fonts {
8
+ @font-face {
9
+ font-family: "Material Symbols Outlined";
10
+ font-style: normal;
11
+ font-weight: 100 700;
12
+ font-display: block;
13
+ src: url("#{$expressive-font-path}/material-symbols-outlined.woff2") format("woff2");
14
+ }
15
+
16
+ @font-face {
17
+ font-family: "Material Symbols Rounded";
18
+ font-style: normal;
19
+ font-weight: 100 700;
20
+ font-display: block;
21
+ src: url("#{$expressive-font-path}/material-symbols-rounded.woff2") format("woff2");
22
+ }
23
+
24
+ @font-face {
25
+ font-family: "Material Symbols Sharp";
26
+ font-style: normal;
27
+ font-weight: 100 700;
28
+ font-display: block;
29
+ src: url("#{$expressive-font-path}/material-symbols-sharp.woff2") format("woff2");
30
+ }
31
+
32
+ @font-face {
33
+ font-family: "Roboto";
34
+ font-style: normal;
35
+ font-weight: 400;
36
+ font-display: swap;
37
+ src: url("#{$expressive-font-path}/roboto-latin-400.woff2") format("woff2");
38
+ }
39
+
40
+ @font-face {
41
+ font-family: "Roboto";
42
+ font-style: normal;
43
+ font-weight: 500;
44
+ font-display: swap;
45
+ src: url("#{$expressive-font-path}/roboto-latin-500.woff2") format("woff2");
46
+ }
47
+
48
+ @font-face {
49
+ font-family: "Noto Sans";
50
+ font-style: normal;
51
+ font-weight: 400;
52
+ font-display: swap;
53
+ src: url("#{$expressive-font-path}/noto-sans-latin-400.woff2") format("woff2");
54
+ }
55
+
56
+ @font-face {
57
+ font-family: "Noto Sans";
58
+ font-style: normal;
59
+ font-weight: 500;
60
+ font-display: swap;
61
+ src: url("#{$expressive-font-path}/noto-sans-latin-500.woff2") format("woff2");
62
+ }
63
+ }
@@ -73,8 +73,7 @@
73
73
  inset-inline-end: calc((100% - var(--md-comp-badge-icon-size)) / 2);
74
74
  transform: translate(50%, -50%);
75
75
 
76
- &:dir(rtl),
77
- [dir="rtl"] & {
76
+ &:dir(rtl) {
78
77
  transform: translate(-50%, -50%);
79
78
  }
80
79
  }