diff --git a/labs/gb/components/appbar/_app-bar-tokens.scss b/labs/gb/components/appbar/_app-bar-tokens.scss
new file mode 100644
index 0000000000..0424790130
--- /dev/null
+++ b/labs/gb/components/appbar/_app-bar-tokens.scss
@@ -0,0 +1,136 @@
+//
+// Copyright 2026 Google LLC
+// SPDX-License-Identifier: Apache-2.0
+//
+
+// Auto-generated by cascade_tokens
+// Add `// EDIT:` comments for manual adjustments.
+//
+// --prefix=md.comp.app-bar
+// --states=":small|[medium-flexible=medium]|[large-flexible=large],with-subtitle,search,on-scroll"
+// --exclude=".medium.,.large."
+
+@mixin root {
+ // LINT.IfChange
+ // md.comp.app-bar.avatar.size
+ --avatar-size: 32px;
+ // md.comp.app-bar.container.color
+ --container-color: var(--md-sys-color-surface);
+ // md.comp.app-bar.container.elevation
+ --container-elevation: var(--md-sys-elevation-shadow-0);
+ // md.comp.app-bar.small.container.height
+ --container-height: 64px;
+ // md.comp.app-bar.container.shape
+ --container-shape: var(--md-sys-shape-corner-none);
+ // md.comp.app-bar.icon-button-space
+ --icon-button-space: var(--md-sys-space-0);
+ // md.comp.app-bar.icon.size
+ --icon-size: 24px;
+ --label-text: unset;
+ --label-text-axes: unset;
+ --label-text-tracking: unset;
+ --label-color: unset;
+ // md.comp.app-bar.leading-icon.color
+ --leading-icon-color: var(--md-sys-color-on-surface);
+ // md.comp.app-bar.leading-space
+ --leading-space: var(--md-sys-space-50);
+ // ┌ md.comp.app-bar.small.subtitle.font
+ --subtitle: var(--md-sys-typescale-label-md);
+ // ┌┄ md.comp.app-bar.small.subtitle
+ --subtitle-axes: var(--md-sys-typescale-label-md-axes);
+ // md.comp.app-bar.subtitle.color
+ --subtitle-color: var(--md-sys-color-on-surface-variant);
+ // ┌┄ md.comp.app-bar.small.subtitle
+ --subtitle-tracking: var(--md-sys-typescale-label-md-tracking);
+ // ┌ md.comp.app-bar.small.title.font
+ --title: var(--md-sys-typescale-title-lg);
+ // ┌┄ md.comp.app-bar.small.title
+ --title-axes: var(--md-sys-typescale-title-lg-axes);
+ // md.comp.app-bar.title.color
+ --title-color: var(--md-sys-color-on-surface);
+ // ┌┄ md.comp.app-bar.small.title
+ --title-tracking: var(--md-sys-typescale-title-lg-tracking);
+ // md.comp.app-bar.trailing-icon.color
+ --trailing-icon-color: var(--md-sys-color-on-surface-variant);
+ // md.comp.app-bar.trailing-space
+ --trailing-space: var(--md-sys-space-50);
+ // LINT.ThenChange(md-gb-app-bar.ts) keep in sync with `@cssprop` jsdoc tags
+}
+
+@mixin medium {
+ // md.comp.app-bar.medium-flexible.container.height
+ --container-height: 112px;
+ // ┌ md.comp.app-bar.medium-flexible.subtitle.font
+ --subtitle: var(--md-sys-typescale-label-lg);
+ // ┌┄ md.comp.app-bar.medium-flexible.subtitle
+ --subtitle-axes: var(--md-sys-typescale-label-lg-axes);
+ // ┌┄ md.comp.app-bar.medium-flexible.subtitle
+ --subtitle-tracking: var(--md-sys-typescale-label-lg-tracking);
+ // ┌ md.comp.app-bar.medium-flexible.title.font
+ --title: var(--md-sys-typescale-headline-md);
+ // ┌┄ md.comp.app-bar.medium-flexible.title
+ --title-axes: var(--md-sys-typescale-headline-md-axes);
+ // ┌┄ md.comp.app-bar.medium-flexible.title
+ --title-tracking: var(--md-sys-typescale-headline-md-tracking);
+}
+
+@mixin large {
+ // md.comp.app-bar.large-flexible.container.height
+ --container-height: 120px;
+ // ┌ md.comp.app-bar.large-flexible.subtitle.font
+ --subtitle: var(--md-sys-typescale-title-md);
+ // ┌┄ md.comp.app-bar.large-flexible.subtitle
+ --subtitle-axes: var(--md-sys-typescale-title-md-axes);
+ // ┌┄ md.comp.app-bar.large-flexible.subtitle
+ --subtitle-tracking: var(--md-sys-typescale-title-md-tracking);
+ // ┌ md.comp.app-bar.large-flexible.title.font
+ --title: var(--md-sys-typescale-display-sm);
+ // ┌┄ md.comp.app-bar.large-flexible.title
+ --title-axes: var(--md-sys-typescale-display-sm-axes);
+ // ┌┄ md.comp.app-bar.large-flexible.title
+ --title-tracking: var(--md-sys-typescale-display-sm-tracking);
+}
+
+@mixin with-subtitle {
+ // ┌ md.comp.app-bar.medium-flexible.with-subtitle.container.height
+ --container-height: 136px;
+}
+
+@mixin with-subtitle-large {
+ // md.comp.app-bar.large-flexible.with-subtitle.container.height
+ --container-height: 152px;
+}
+
+@mixin search {
+ // md.comp.app-bar.search.container.color
+ --container-color: var(--md-sys-color-surface-container);
+ // md.comp.app-bar.small.search.container.height
+ --container-height: 56px;
+ // md.comp.app-bar.small.search.container.shape
+ --container-shape: var(--md-sys-shape-corner-full);
+ // ┌ md.comp.app-bar.small.search.label-text.font
+ --label-text: var(--md-sys-typescale-body-lg);
+ // ┌┄ md.comp.app-bar.small.search.label-text
+ --label-text-axes: var(--md-sys-typescale-body-lg-axes);
+ // ┌┄ md.comp.app-bar.small.search.label-text
+ --label-text-tracking: var(--md-sys-typescale-body-lg-tracking);
+ // md.comp.app-bar.search.label.color
+ --label-color: var(--md-sys-color-on-surface-variant);
+ // md.comp.app-bar.search.leading-space
+ --leading-space: var(--md-sys-space-100);
+ // md.comp.app-bar.search.trailing-space
+ --trailing-space: var(--md-sys-space-100);
+}
+
+@mixin on-scroll {
+ // md.comp.app-bar.on-scroll.container.color
+ --container-color: var(--md-sys-color-surface-container);
+ // md.comp.app-bar.on-scroll.container.elevation
+ --container-elevation: var(--md-sys-elevation-shadow-2);
+}
+
+@mixin on-scroll-search {
+ // md.comp.app-bar.search.on-scroll.container.color
+ --container-color: var(--md-sys-color-surface-container-highest);
+}
+
diff --git a/labs/gb/components/appbar/app-bar-element.ts b/labs/gb/components/appbar/app-bar-element.ts
new file mode 100644
index 0000000000..ce6fede1ca
--- /dev/null
+++ b/labs/gb/components/appbar/app-bar-element.ts
@@ -0,0 +1,139 @@
+/**
+ * @license
+ * Copyright 2026 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import {css, CSSResultOrNative, html, LitElement} from 'lit';
+import {property, state} from 'lit/decorators.js';
+
+import {appBar, type AppBarSize, type AppBarVariant} from './app-bar.js';
+import {styles as appBarStyles} from './app-bar.cssresult.js';
+
+/**
+ * A Material Design Expressive App Bar component (`md-gb-app-bar`).
+ *
+ * @slot - Used to display the primary title text of the app bar.
+ * @slot subtitle - Used to display an optional subtitle below the title in medium/large bars.
+ * @slot leading - Used to display the leading navigation icon button (e.g. menu or back).
+ * @slot trailing - Used to display trailing action buttons and/or user avatar.
+ * @slot search - Used to display search bar input or controls when `variant="search"`.
+ * @fires {CustomEvent<{scrolled: boolean}>} scrollstatechange - Fired when the scrolled state changes. --bubbles --composed
+ * @csspart app-bar - The root container element.
+ * @cssprop --avatar-size
+ * @cssprop --container-color
+ * @cssprop --container-elevation
+ * @cssprop --container-height
+ * @cssprop --container-shape
+ * @cssprop --icon-button-space
+ * @cssprop --icon-size
+ * @cssprop --label-text
+ * @cssprop --label-text-axes
+ * @cssprop --label-text-tracking
+ * @cssprop --label-color
+ * @cssprop --leading-icon-color
+ * @cssprop --leading-space
+ * @cssprop --subtitle
+ * @cssprop --subtitle-axes
+ * @cssprop --subtitle-color
+ * @cssprop --subtitle-tracking
+ * @cssprop --title
+ * @cssprop --title-axes
+ * @cssprop --title-color
+ * @cssprop --title-tracking
+ * @cssprop --trailing-icon-color
+ * @cssprop --trailing-space
+ */
+export class AppBarElement extends LitElement {
+ static override styles: CSSResultOrNative[] = [
+ appBarStyles,
+ css`
+ :host {
+ display: flex;
+ width: 100%;
+ position: relative;
+ }
+ `,
+ ];
+
+ /** The size of the app bar (`sm`, `md`, `lg`). Defaults to `sm`. */
+ @property({reflect: true}) size: AppBarSize = 'sm';
+
+ /** The behavioral variant of the app bar (`standard` or `search`). Defaults to `standard`. */
+ @property({reflect: true}) variant: AppBarVariant = 'standard';
+
+ /** Whether the app bar is in its scrolled state. Defaults to `false`. */
+ @property({type: Boolean, reflect: true}) scrolled = false;
+
+ @state() private hasSubtitle = false;
+
+ protected override render() {
+ const withSubtitle = this.size !== 'sm' && this.hasSubtitle;
+ const directive = appBar({
+ size: this.size,
+ withSubtitle,
+ variant: this.variant,
+ scrolled: this.scrolled,
+ });
+
+ if (this.variant === 'search') {
+ return html`
`;
+ }
+
+ if (this.size !== 'sm') {
+ return html``;
+ }
+
+ return html``;
+ }
+
+ private handleSubtitleSlotChange(event: Event) {
+ const slot = event.target as HTMLSlotElement;
+ this.hasSubtitle = slot.assignedNodes({flatten: true}).length > 0;
+ }
+}
diff --git a/labs/gb/components/appbar/app-bar.scss b/labs/gb/components/appbar/app-bar.scss
new file mode 100644
index 0000000000..e475fbc532
--- /dev/null
+++ b/labs/gb/components/appbar/app-bar.scss
@@ -0,0 +1,167 @@
+/*!
+ * Copyright 2026 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+// go/keep-sorted start by_regex='(.+) prefix_order=sass:
+@use 'app-bar-tokens';
+// go/keep-sorted end
+
+@layer md.sys;
+@layer md.comp.app-bar {
+ // Component tokens
+ .app-bar {
+ @include app-bar-tokens.root;
+ }
+ .app-bar-md {
+ @include app-bar-tokens.medium;
+ }
+ .app-bar-lg {
+ @include app-bar-tokens.large;
+ }
+ .app-bar-with-subtitle {
+ @include app-bar-tokens.with-subtitle;
+ }
+ .app-bar-with-subtitle.app-bar-lg {
+ @include app-bar-tokens.with-subtitle-large;
+ }
+ .app-bar-search {
+ @include app-bar-tokens.search;
+ }
+ .app-bar-scrolled {
+ @include app-bar-tokens.on-scroll;
+ }
+ .app-bar-scrolled.app-bar-search {
+ @include app-bar-tokens.on-scroll-search;
+ }
+
+ // Component styles
+ .app-bar {
+ box-sizing: border-box;
+ display: flex;
+ position: relative;
+ width: 100%;
+ min-height: var(--container-height);
+ background-color: var(--container-color);
+ border-radius: var(--container-shape);
+ box-shadow: var(--container-elevation);
+ color: var(--title-color);
+ transition:
+ background-color 200ms ease,
+ box-shadow 200ms ease,
+ min-height 200ms ease;
+ padding-inline: var(--leading-space) var(--trailing-space);
+ }
+
+ // Small and Search layouts (single row)
+ .app-bar-sm,
+ .app-bar-search {
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-between;
+ }
+
+ // Medium and Large layouts (two rows)
+ .app-bar-md,
+ .app-bar-lg {
+ flex-direction: column;
+ justify-content: space-between;
+ align-items: stretch;
+
+ .app-bar-top-row {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-between;
+ min-height: 64px;
+ width: 100%;
+ }
+
+ .app-bar-bottom-row {
+ display: flex;
+ flex-direction: column;
+ justify-content: flex-end;
+ padding-bottom: 24px;
+ padding-inline: 12px;
+ flex: 1 1 auto;
+ min-height: 0;
+ }
+ }
+
+ // Slot containers
+ .app-bar-leading,
+ .app-bar-trailing {
+ display: flex;
+ align-items: center;
+ gap: var(--icon-button-space);
+ flex-shrink: 0;
+ }
+
+ .app-bar-leading {
+ color: var(--leading-icon-color);
+ }
+
+ .app-bar-trailing {
+ color: var(--trailing-icon-color);
+ }
+
+ .app-bar-title-wrapper {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ flex: 1 1 auto;
+ min-width: 0;
+ overflow: hidden;
+ }
+
+ .app-bar-sm .app-bar-title-wrapper {
+ margin-inline: 4px;
+ }
+
+ .app-bar-title {
+ margin: 0;
+ font: var(--title);
+ font-variation-settings: var(--title-axes);
+ letter-spacing: var(--title-tracking);
+ color: var(--title-color);
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+
+ ::slotted(*) {
+ margin: 0;
+ font: inherit;
+ font-variation-settings: inherit;
+ letter-spacing: inherit;
+ color: inherit;
+ }
+ }
+
+ .app-bar-subtitle {
+ margin: 0;
+ margin-top: 2px;
+ font: var(--subtitle);
+ font-variation-settings: var(--subtitle-axes);
+ letter-spacing: var(--subtitle-tracking);
+ color: var(--subtitle-color);
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+
+ ::slotted(*) {
+ margin: 0;
+ font: inherit;
+ font-variation-settings: inherit;
+ letter-spacing: inherit;
+ color: inherit;
+ }
+ }
+
+ .app-bar-search-container {
+ display: flex;
+ flex: 1 1 auto;
+ align-items: center;
+ min-width: 0;
+ margin-inline: 8px;
+ }
+}
diff --git a/labs/gb/components/appbar/app-bar.ts b/labs/gb/components/appbar/app-bar.ts
new file mode 100644
index 0000000000..7e4a857115
--- /dev/null
+++ b/labs/gb/components/appbar/app-bar.ts
@@ -0,0 +1,134 @@
+/**
+ * @license
+ * Copyright 2026 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import {type ClassInfo} from 'lit/directives/class-map.js';
+
+import {createClassMapDirective} from '../shared/directives.js';
+
+/** App Bar size configuration types. */
+export type AppBarSize = 'sm' | 'md' | 'lg';
+
+/** App Bar size configurations. */
+export const APP_BAR_SIZES = {
+ sm: 'sm',
+ md: 'md',
+ lg: 'lg',
+} as const;
+
+/** App Bar variant configuration types. */
+export type AppBarVariant = 'standard' | 'search';
+
+/** App Bar variant configurations. */
+export const APP_BAR_VARIANTS = {
+ standard: 'standard',
+ search: 'search',
+} as const;
+
+/** App Bar classes. */
+export const APP_BAR_CLASSES = {
+ appBar: 'app-bar',
+ appBarSm: 'app-bar-sm',
+ appBarMd: 'app-bar-md',
+ appBarLg: 'app-bar-lg',
+ appBarWithSubtitle: 'app-bar-with-subtitle',
+ appBarSearch: 'app-bar-search',
+ appBarScrolled: 'app-bar-scrolled',
+} as const;
+
+/** The state provided to the `appBarClasses()` function. */
+export interface AppBarClassesState {
+ /** The size of the app bar (`sm`, `md`, `lg`). */
+ size?: AppBarSize;
+ /** Whether the app bar has a subtitle. */
+ withSubtitle?: boolean;
+ /** The behavior variant (`standard` or `search`). */
+ variant?: AppBarVariant;
+ /** Whether the app bar is in a scrolled or docked state (`.app-bar-scrolled`). */
+ scrolled?: boolean;
+}
+
+/**
+ * Returns the app bar classes to apply to an element based on the given state.
+ *
+ * @param state The state of the app bar.
+ * @return An object of class names and truthy values if they apply.
+ */
+export function appBarClasses({
+ size = 'sm',
+ withSubtitle = false,
+ variant = 'standard',
+ scrolled = false,
+}: AppBarClassesState = {}): ClassInfo {
+ return {
+ [APP_BAR_CLASSES.appBar]: true,
+ [APP_BAR_CLASSES.appBarSm]: size === APP_BAR_SIZES.sm || !size,
+ [APP_BAR_CLASSES.appBarMd]: size === APP_BAR_SIZES.md,
+ [APP_BAR_CLASSES.appBarLg]: size === APP_BAR_SIZES.lg,
+ [APP_BAR_CLASSES.appBarWithSubtitle]: withSubtitle,
+ [APP_BAR_CLASSES.appBarSearch]: variant === APP_BAR_VARIANTS.search,
+ [APP_BAR_CLASSES.appBarScrolled]: scrolled,
+ };
+}
+
+/**
+ * Sets up optional scroll target tracking for the given app bar element when an explicit `scrollTarget` is provided.
+ *
+ * @param appBar The element on which to set up app bar functionality.
+ * @param opts Setup options, containing an explicit `scrollTarget` and optional cleanup `signal`.
+ */
+export function setupAppBar(
+ appBar: HTMLElement,
+ opts?: {signal?: AbortSignal; scrollTarget?: HTMLElement | Window},
+): void {
+ if (!opts?.scrollTarget) {
+ return;
+ }
+ const target = opts.scrollTarget;
+ const signal = opts.signal;
+
+ const onScroll = () => {
+ if (signal?.aborted) return;
+ let scrollTop = 0;
+ if (target instanceof Window) {
+ scrollTop = target.scrollY || target.document.documentElement.scrollTop;
+ } else if (target instanceof HTMLElement) {
+ scrollTop = target.scrollTop;
+ }
+ const isScrolled = scrollTop > 0;
+ const wasScrolled = appBar.classList.contains(
+ APP_BAR_CLASSES.appBarScrolled,
+ );
+ if (isScrolled !== wasScrolled) {
+ appBar.classList.toggle(APP_BAR_CLASSES.appBarScrolled, isScrolled);
+ appBar.dispatchEvent(
+ new CustomEvent('scrollstatechange', {
+ bubbles: true,
+ composed: true,
+ detail: {scrolled: isScrolled},
+ }),
+ );
+ }
+ };
+
+ target.addEventListener('scroll', onScroll, {passive: true, signal});
+ onScroll();
+}
+
+/**
+ * A Lit directive that adds app bar styling and optional scroll tracking functionality to its element.
+ *
+ * @example
+ * ```ts
+ * html``;
+ * ```
+ */
+export const appBar = createClassMapDirective({
+ getClasses: appBarClasses,
+ setupElement: setupAppBar,
+});
diff --git a/labs/gb/components/appbar/demo/demo.ts b/labs/gb/components/appbar/demo/demo.ts
new file mode 100644
index 0000000000..3c9ed84c27
--- /dev/null
+++ b/labs/gb/components/appbar/demo/demo.ts
@@ -0,0 +1,46 @@
+/**
+ * @license
+ * Copyright 2026 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import './material-collection.js';
+import './index.js';
+
+import {
+ KnobTypesToKnobs,
+ MaterialCollection,
+ materialInitsToStoryInits,
+ setUpDemo,
+} from './material-collection.js';
+import {boolInput, Knob, selectDropdown} from './index.js';
+
+import {stories, StoryKnobs} from './stories.js';
+
+const collection = new MaterialCollection>(
+ 'App Bar',
+ [
+ new Knob('size', {
+ ui: selectDropdown({
+ options: [
+ {value: 'sm', label: 'Small (sm)'},
+ {value: 'md', label: 'Medium (md)'},
+ {value: 'lg', label: 'Large (lg)'},
+ ],
+ }),
+ }),
+ new Knob('variant', {
+ ui: selectDropdown({
+ options: [
+ {value: 'standard', label: 'Standard'},
+ {value: 'search', label: 'Search'},
+ ],
+ }),
+ }),
+ new Knob('scrolled', {ui: boolInput()}),
+ ],
+);
+
+collection.addStories(...materialInitsToStoryInits(stories));
+
+setUpDemo(collection, {fonts: 'roboto', icons: 'material-symbols'});
diff --git a/labs/gb/components/appbar/demo/stories.ts b/labs/gb/components/appbar/demo/stories.ts
new file mode 100644
index 0000000000..1e039dcbbf
--- /dev/null
+++ b/labs/gb/components/appbar/demo/stories.ts
@@ -0,0 +1,206 @@
+/**
+ * @license
+ * Copyright 2026 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import '@material/web/labs/gb/components/appbar/md-gb-app-bar.js';
+import '@material/web/labs/gb/components/iconbutton/md-gb-icon-button.js';
+import '@material/web/labs/gb/styles/icon/md-gb-icon.js';
+
+import {MaterialStoryInit} from './material-collection.js';
+import {
+ type AppBarSize,
+ type AppBarVariant,
+} from '@material/web/labs/gb/components/appbar/app-bar.js';
+import {adoptStyles} from '@material/web/labs/gb/styles/adopt-styles.js';
+import {styles as m3Styles} from '@material/web/labs/gb/styles/m3.cssresult.js';
+import {css, html, nothing} from 'lit';
+
+/** Knob types for app bar stories. */
+export interface StoryKnobs {
+ size?: AppBarSize;
+ variant?: AppBarVariant;
+ scrolled: boolean;
+}
+
+adoptStyles(document, [
+ m3Styles,
+ css`
+ :root {
+ --md-icon-font: 'Material Symbols Outlined';
+ }
+ `,
+]);
+
+const styles = css`
+ .demo-container {
+ border: 1px solid var(--md-sys-color-outline-variant);
+ border-radius: 16px;
+ overflow: hidden;
+ margin-bottom: 24px;
+ background-color: var(--md-sys-color-surface);
+ box-shadow: var(--md-sys-elevation-shadow-1);
+ }
+`;
+
+const playground: MaterialStoryInit = {
+ name: 'Playground',
+ styles,
+ render(knobs) {
+ const size = knobs.size || 'sm';
+ const variant = knobs.variant || 'standard';
+ const scrolled = Boolean(knobs.scrolled);
+
+ if (variant === 'search') {
+ return html`
+
+
+
+ menu
+
+
+
+ account_circle
+
+
+
+ `;
+ }
+
+ const showSubtitle = size === 'md' || size === 'lg';
+
+ return html`
+
+
+
+ menu
+
+ Expressive App Bar (${size})
+ ${showSubtitle
+ ? html`Two-tier expressive hierarchy (${size})`
+ : nothing}
+
+ search
+
+
+ more_vert
+
+
+
+ `;
+ },
+};
+
+const allSizes: MaterialStoryInit = {
+ name: 'Expressive Sizes & Variants',
+ styles,
+ render() {
+ return html`
+
+
+
+
+ menu
+
+ Small App Bar (sm)
+
+ search
+
+
+ account_circle
+
+
+
+
+
+
+
+ arrow_back
+
+ Medium App Bar (md)
+
+ more_vert
+
+
+
+
+
+
+
+ menu
+
+ Medium App Bar with Subtitle
+ Two-tier expressive hierarchy
+
+ edit
+
+
+
+
+
+
+
+ menu
+
+ Large App Bar (lg)
+
+ settings
+
+
+
+
+
+
+
+ menu
+
+ Large App Bar with Subtitle
+ Dynamic headline layout
+
+ account_circle
+
+
+
+
+
+
+
+ search
+
+
+
+ close
+
+
+
+
+
+
+
+ menu
+
+ Scrolled App Bar (Declarative property)
+ Demonstrating elevated scrolled style
+
+ filter_list
+
+
+
+
+ `;
+ },
+};
+
+/** App Bar stories. */
+export const stories = [playground, allSizes];
diff --git a/labs/gb/components/appbar/md-gb-app-bar.ts b/labs/gb/components/appbar/md-gb-app-bar.ts
new file mode 100644
index 0000000000..623e9c913c
--- /dev/null
+++ b/labs/gb/components/appbar/md-gb-app-bar.ts
@@ -0,0 +1,16 @@
+/**
+ * @license
+ * Copyright 2026 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import {AppBarElement} from './app-bar-element.js';
+
+declare global {
+ interface HTMLElementTagNameMap {
+ /** A Material Design app bar component. */
+ 'md-gb-app-bar': AppBarElement;
+ }
+}
+
+customElements.define('md-gb-app-bar', AppBarElement);