@rblabs-dev/axiom 0.0.0-stage → 1.2.1
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.
- package/LICENSE +21 -0
- package/README.md +155 -2
- package/brand/favicon.template.svg +21 -0
- package/brand/og-image.template.svg +37 -0
- package/brand/rb-monogram.svg +16 -0
- package/cli/axiom.mjs +56 -0
- package/cli/build-brand-assets.mjs +115 -0
- package/cli/build-icon-font.mjs +134 -0
- package/cli/check-style-literals.mjs +94 -0
- package/cli/project.mjs +105 -0
- package/cli/verify-production-assets.mjs +146 -0
- package/fesm2022/rblabs-dev-axiom-showcase.mjs +1027 -0
- package/fesm2022/rblabs-dev-axiom-showcase.mjs.map +1 -0
- package/fesm2022/rblabs-dev-axiom.mjs +2955 -0
- package/fesm2022/rblabs-dev-axiom.mjs.map +1 -0
- package/material-symbols-icons.txt +24 -0
- package/package.json +67 -4
- package/showcase/package.json +4 -0
- package/styles/_base.scss +135 -0
- package/styles/_breakpoints.scss +35 -0
- package/styles/_components.scss +560 -0
- package/styles/_fonts.scss +63 -0
- package/styles/_index.scss +72 -0
- package/styles/_material-overrides.scss +79 -0
- package/styles/_palette.scss +139 -0
- package/styles/_theme.scss +183 -0
- package/styles/_tokens.scss +341 -0
- package/types/rblabs-dev-axiom-showcase.d.ts +81 -0
- package/types/rblabs-dev-axiom.d.ts +675 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rblabs-dev-axiom-showcase.mjs","names":[],"sources":["../../../projects/axiom/showcase/src/shell-example/shell-example.ts","../../../projects/axiom/showcase/src/shell-example/shell-example.html","../../../projects/axiom/showcase/src/design-system-showcase.ts","../../../projects/axiom/showcase/src/design-system-showcase.html"],"sourcesContent":["import { NgTemplateOutlet } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, computed, inject, input } from '@angular/core';\nimport { toSignal } from '@angular/core/rxjs-interop';\nimport { MatButton, MatIconButton } from '@angular/material/button';\nimport { MatIcon } from '@angular/material/icon';\nimport { MatTooltip } from '@angular/material/tooltip';\nimport { ActivatedRoute, RouterLink } from '@angular/router';\nimport { map } from 'rxjs';\n\nimport {\n RbAppShellComponent,\n RbCentralSignInComponent,\n RbPageHeaderComponent,\n RbPanelComponent,\n RbPublicShellComponent,\n} from '@rblabs-dev/axiom';\n\nexport type RbShellExampleKind = 'app-sidenav' | 'app-modules' | 'public' | 'sign-in';\n\nexport const RB_SHELL_EXAMPLE_KINDS: readonly RbShellExampleKind[] = [\n 'app-sidenav',\n 'app-modules',\n 'public',\n 'sign-in',\n];\n\ninterface ExampleLink {\n id: string;\n label: string;\n icon: string;\n}\n\nconst SIDENAV_SECTIONS: { label: string; links: ExampleLink[] }[] = [\n { label: 'Workspace', links: [{ id: 'overview', label: 'Overview', icon: 'space_dashboard' }] },\n {\n label: 'Administration',\n links: [\n { id: 'users', label: 'Users', icon: 'group' },\n { id: 'applications', label: 'Applications', icon: 'apps' },\n { id: 'services', label: 'Services', icon: 'dns' },\n { id: 'audit', label: 'Registry audit', icon: 'history' },\n ],\n },\n];\n\nconst MODULE_LINKS: ExampleLink[] = [\n { id: 'launch', label: 'Launch', icon: 'add_box' },\n { id: 'datasets', label: 'Datasets', icon: 'inbox' },\n { id: 'jobs', label: 'Jobs', icon: 'autorenew' },\n { id: 'artifacts', label: 'Artifacts', icon: 'deployed_code' },\n];\n\n/**\n * Full-page shell examples for the showcase (`/design-system?example=<kind>`), so each shell is\n * shown in a document of its own: with its own landmarks, at the real viewport width.\n */\n@Component({\n selector: 'rb-showcase-shell-example',\n imports: [\n MatButton,\n MatIcon,\n MatIconButton,\n MatTooltip,\n NgTemplateOutlet,\n RbAppShellComponent,\n RbCentralSignInComponent,\n RbPageHeaderComponent,\n RbPanelComponent,\n RbPublicShellComponent,\n RouterLink,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './shell-example.html',\n styleUrl: './shell-example.scss',\n})\nexport class RbShellExampleComponent {\n readonly kind = input.required<RbShellExampleKind>();\n\n protected readonly sidenavSections = SIDENAV_SECTIONS;\n protected readonly moduleLinks = MODULE_LINKS;\n\n private readonly section = toSignal(\n inject(ActivatedRoute).queryParamMap.pipe(map((params) => params.get('section'))),\n { initialValue: null },\n );\n\n /** The current link: the `section` query parameter, or the first link of the example. */\n protected readonly current = computed(() => {\n const links =\n this.kind() === 'app-modules'\n ? MODULE_LINKS\n : SIDENAV_SECTIONS.flatMap((section) => section.links);\n return links.find((link) => link.id === this.section()) ?? links[0];\n });\n}\n","@switch (kind()) {\n @case ('app-sidenav') {\n <rb-app-shell appName=\"Admin\" homeLink=\"/design-system\" navigation=\"sidenav\">\n <span rbShellTitle>Administration workspace</span>\n <button\n rbShellActions\n matIconButton\n type=\"button\"\n aria-label=\"Sign out\"\n matTooltip=\"Sign out\"\n >\n <mat-icon aria-hidden=\"true\">logout</mat-icon>\n </button>\n\n <nav rbShellSidenav aria-label=\"Administration\">\n @for (section of sidenavSections; track section.label) {\n <h2 class=\"rb-shell-nav-heading\">{{ section.label }}</h2>\n @for (link of section.links; track link.id) {\n <a\n class=\"rb-shell-nav-link\"\n routerLink=\".\"\n [queryParams]=\"{ example: kind(), section: link.id }\"\n [attr.aria-current]=\"current().id === link.id ? 'page' : null\"\n >\n <mat-icon aria-hidden=\"true\">{{ link.icon }}</mat-icon>\n <span>{{ link.label }}</span>\n </a>\n }\n }\n </nav>\n\n <ng-container [ngTemplateOutlet]=\"page\" />\n </rb-app-shell>\n }\n @case ('app-modules') {\n <rb-app-shell appName=\"Photogrammetry\" homeLink=\"/design-system\" navigation=\"modules\">\n <span rbShellTitle>Workspace · {{ current().label }}</span>\n <button\n rbShellActions\n matIconButton\n type=\"button\"\n aria-label=\"Sign out\"\n matTooltip=\"Sign out\"\n >\n <mat-icon aria-hidden=\"true\">logout</mat-icon>\n </button>\n\n <nav rbShellModuleNav aria-label=\"Workspace modules\">\n @for (link of moduleLinks; track link.id) {\n <a\n class=\"rb-shell-nav-link\"\n routerLink=\".\"\n [queryParams]=\"{ example: kind(), section: link.id }\"\n [attr.aria-current]=\"current().id === link.id ? 'page' : null\"\n >\n <mat-icon aria-hidden=\"true\">{{ link.icon }}</mat-icon>\n <span>{{ link.label }}</span>\n </a>\n }\n </nav>\n\n <span rbShellFooter>\n <mat-icon class=\"shell-example__footer-icon\" aria-hidden=\"true\">lock</mat-icon>\n Protected access\n </span>\n\n <ng-container [ngTemplateOutlet]=\"page\" />\n </rb-app-shell>\n }\n @case ('public') {\n <rb-public-shell appName=\"Auth\" homeLink=\"/design-system\">\n <a rbShellFooter routerLink=\"/design-system\">Design system</a>\n\n <section class=\"shell-example__card\" aria-labelledby=\"shell-example-sign-in\">\n <h1 id=\"shell-example-sign-in\" class=\"shell-example__card-title\">Sign in to RB Labs</h1>\n <p class=\"shell-example__card-text\">One account for Admin, Rover and Photogrammetry.</p>\n <form class=\"rb-stack\" (submit)=\"$event.preventDefault()\">\n <div class=\"rb-field\">\n <label class=\"rb-field__label\" for=\"shell-example-email\">Email</label>\n <input\n id=\"shell-example-email\"\n class=\"rb-field__control\"\n type=\"email\"\n autocomplete=\"email\"\n />\n </div>\n <div class=\"rb-field\">\n <label class=\"rb-field__label\" for=\"shell-example-password\">Password</label>\n <input\n id=\"shell-example-password\"\n class=\"rb-field__control\"\n type=\"password\"\n autocomplete=\"current-password\"\n />\n </div>\n <button matButton=\"filled\" type=\"submit\">Sign in</button>\n </form>\n </section>\n </rb-public-shell>\n }\n @case ('sign-in') {\n <rb-public-shell appName=\"Admin\" homeLink=\"/design-system\">\n <a rbShellFooter routerLink=\"/design-system\">Design system</a>\n\n <rb-central-sign-in\n appName=\"Admin\"\n eyebrow=\"Administration workspace\"\n note=\"Restricted to active RB Labs administrators.\"\n backLink=\"/design-system\"\n />\n </rb-public-shell>\n }\n}\n\n<ng-template #page>\n <div class=\"rb-stack\">\n <rb-page-header\n eyebrow=\"Shell example\"\n [title]=\"current().label\"\n description=\"Placeholder content inside the shell's content column.\"\n />\n <div class=\"shell-example__grid\">\n <rb-panel title=\"Content column\" [headingLevel]=\"2\">\n <p class=\"shell-example__text\">\n The column is centered and stops at <code>--rb-size-content-max</code>. Its gutter is\n <code>--rb-space-page</code>.\n </p>\n </rb-panel>\n <rb-panel title=\"Navigation\" variant=\"soft\" [headingLevel]=\"2\">\n <p class=\"shell-example__text\">\n Choose another item: the current one carries <code>aria-current=\"page\"</code>, and below\n <code>lg</code> the drawer closes on navigation.\n </p>\n </rb-panel>\n </div>\n <rb-panel title=\"Recent activity\" [headingLevel]=\"2\">\n <button rbActions matButton type=\"button\">\n <mat-icon aria-hidden=\"true\">refresh</mat-icon>\n Refresh\n </button>\n <div class=\"rb-stack rb-stack--sm\" aria-hidden=\"true\">\n @for (row of [1, 2, 3, 4, 5, 6]; track row) {\n <span class=\"rb-skeleton\"></span>\n }\n </div>\n </rb-panel>\n </div>\n</ng-template>\n","import { ChangeDetectionStrategy, Component, computed, inject, signal } from '@angular/core';\nimport { toSignal } from '@angular/core/rxjs-interop';\nimport { MatButton, MatIconButton } from '@angular/material/button';\nimport { MatChipGrid, MatChipRemove, MatChipRow } from '@angular/material/chips';\nimport { MatFormField, MatHint, MatLabel } from '@angular/material/form-field';\nimport { MatIcon } from '@angular/material/icon';\nimport { MatInput } from '@angular/material/input';\nimport { MatTableModule } from '@angular/material/table';\nimport { MatTooltip } from '@angular/material/tooltip';\nimport { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';\nimport { ActivatedRoute, RouterLink } from '@angular/router';\nimport { map } from 'rxjs';\n\nimport {\n RB_DESIGN_SYSTEM_VERSION,\n RbBrandLockupComponent,\n RbConfirmDialogData,\n RbConfirmDialogResult,\n RbConfirmDialogService,\n RbEmptyStateComponent,\n RbMessageComponent,\n RbMessageTone,\n RbMonogramComponent,\n RbPageHeaderComponent,\n RbPageHeaderMetric,\n RbPanelComponent,\n RbStatusChipComponent,\n RbStatusTone,\n RbTechnicalValueComponent,\n RbThemeToggleComponent,\n ThemeService,\n} from '@rblabs-dev/axiom';\n\nimport {\n RB_SHELL_EXAMPLE_KINDS,\n RbShellExampleComponent,\n RbShellExampleKind,\n} from './shell-example/shell-example';\n\ninterface ColorGroup {\n title: string;\n roles: { token: string; on?: string }[];\n}\n\nconst COLOR_GROUPS: ColorGroup[] = [\n {\n title: 'Primary and tertiary',\n roles: [\n { token: 'primary', on: 'on-primary' },\n { token: 'primary-hover', on: 'on-primary' },\n { token: 'primary-soft', on: 'on-primary-soft' },\n { token: 'tertiary', on: 'on-tertiary' },\n ],\n },\n {\n title: 'Surfaces',\n roles: [\n { token: 'bg', on: 'text' },\n { token: 'surface-sunken', on: 'text' },\n { token: 'surface', on: 'text' },\n { token: 'surface-raised', on: 'text' },\n { token: 'surface-hover', on: 'text' },\n { token: 'surface-nav', on: 'text' },\n { token: 'control', on: 'text-strong' },\n ],\n },\n {\n title: 'Text and borders',\n roles: [\n { token: 'text-strong' },\n { token: 'text' },\n { token: 'text-muted' },\n { token: 'text-subtle' },\n { token: 'text-disabled' },\n { token: 'border' },\n { token: 'border-strong' },\n { token: 'outline' },\n { token: 'focus' },\n ],\n },\n {\n title: 'Status',\n roles: [\n { token: 'info', on: 'on-info' },\n { token: 'info-soft', on: 'info' },\n { token: 'success', on: 'on-success' },\n { token: 'success-soft', on: 'success' },\n { token: 'warning', on: 'on-warning' },\n { token: 'warning-soft', on: 'warning' },\n { token: 'danger', on: 'on-danger' },\n { token: 'danger-soft', on: 'danger' },\n ],\n },\n];\n\nconst TYPE_ROLES = [\n 'hero',\n 'page-title',\n 'display-small',\n 'headline-large',\n 'headline-medium',\n 'headline-small',\n 'title-large',\n 'title-medium',\n 'title-small',\n 'body-large',\n 'body-medium',\n 'body-small',\n 'label-large',\n 'label-medium',\n 'label-small',\n];\n\nconst MESSAGE_SAMPLES: { tone: RbMessageTone; title: string; body: string }[] = [\n { tone: 'neutral', title: 'Read-only', body: 'Registry entries are managed by the deploy job.' },\n { tone: 'info', title: 'Sync scheduled', body: 'The registry syncs again in 5 minutes.' },\n { tone: 'success', title: 'Application saved', body: 'Redirect URIs take effect immediately.' },\n { tone: 'warning', title: 'Key expires soon', body: 'Rotate it before 1 November 2026.' },\n { tone: 'danger', title: 'Sync failed', body: 'The registry could not be reached.' },\n];\n\nconst CHIP_SAMPLES: { tone: RbStatusTone; label: string }[] = [\n { tone: 'active', label: 'Running' },\n { tone: 'success', label: 'Active' },\n { tone: 'warning', label: 'Disabled' },\n { tone: 'danger', label: 'Revoked' },\n { tone: 'neutral', label: 'Draft' },\n];\n\nexport interface ShowcaseRow {\n name: string;\n clientId: string;\n status: { tone: RbStatusTone; label: string };\n updated: string;\n}\n\nconst TABLE_ROWS: ShowcaseRow[] = [\n {\n name: 'RB Labs Auth',\n clientId: 'app_01HZX9K4T7Q2M8R5W3N6B1C0DE',\n status: { tone: 'success', label: 'Active' },\n updated: '19 Oct 2026',\n },\n {\n name: 'Photogrammetry workspace',\n clientId: 'app_01J2B7F9P4L6X3V8S1D5G0HAKM',\n status: { tone: 'warning', label: 'Disabled' },\n updated: '2 Oct 2026',\n },\n {\n name: 'Rover control',\n clientId: 'app_01J3C1A8E5N2Y7U4Q9T6R0ZWXP',\n status: { tone: 'danger', label: 'Revoked' },\n updated: '14 Sep 2026',\n },\n];\n\nconst SHELL_EXAMPLES: { kind: RbShellExampleKind; title: string; description: string }[] = [\n {\n kind: 'app-sidenav',\n title: 'App shell with sidenav',\n description: 'Admin-style navigation rail; an overlay drawer below lg.',\n },\n {\n kind: 'app-modules',\n title: 'App shell with module nav',\n description: 'Photogrammetry-style modules; a row below lg and a tab bar below sm.',\n },\n {\n kind: 'public',\n title: 'Public shell',\n description: 'Landing, sign-in and other public pages.',\n },\n {\n kind: 'sign-in',\n title: 'Central sign-in',\n description: 'The page that hands off to RB Labs Auth, alone in the public shell.',\n },\n];\n\nconst DEFAULT_SCOPES = ['openid', 'profile', 'email', 'offline_access'];\n\nconst ICON_TILES = [\n { icon: 'group', overline: 'rb-icon-tile', label: 'Users and roles' },\n { icon: 'apps', overline: 'rb-overline', label: 'Registered applications' },\n { icon: 'history', overline: 'rb-table__link', label: 'Registry audit' },\n];\n\nconst MONOGRAM_SIZES = [\n { token: '--rb-size-monogram', value: 'var(--rb-size-monogram)' },\n { token: '--rb-size-monogram-sm', value: 'var(--rb-size-monogram-sm)' },\n { token: 'favicon (16px)', value: 'var(--rb-size-icon-sm)' },\n];\n\nconst BUTTON_ROLES = [\n { role: 'Primary', markup: 'matButton=\"filled\"', legacy: 'mat-flat-button' },\n { role: 'Secondary', markup: 'matButton=\"outlined\"', legacy: 'mat-stroked-button' },\n { role: 'Tertiary', markup: 'matButton', legacy: 'mat-button' },\n {\n role: 'Danger',\n markup: 'matButton=\"filled\" color=\"warn\"',\n legacy: 'mat-flat-button color=\"warn\"',\n },\n { role: 'Icon', markup: 'matIconButton', legacy: 'mat-icon-button' },\n];\n\n/**\n * Living reference of the kit (docs/design-system.md): tokens, type, spacing, shape, elevation,\n * Material components, the content components and the kit style classes, in the active theme.\n */\n@Component({\n selector: 'rb-design-system-showcase',\n imports: [\n MatButton,\n MatChipGrid,\n MatChipRemove,\n MatChipRow,\n MatFormField,\n MatHint,\n MatIcon,\n MatIconButton,\n MatInput,\n MatLabel,\n MatTableModule,\n MatTooltip,\n RbBrandLockupComponent,\n RbEmptyStateComponent,\n RbMessageComponent,\n RbMonogramComponent,\n RbPageHeaderComponent,\n RbPanelComponent,\n RbStatusChipComponent,\n RbShellExampleComponent,\n RbTechnicalValueComponent,\n RbThemeToggleComponent,\n RouterLink,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './design-system-showcase.html',\n styleUrl: './design-system-showcase.scss',\n // `rb-scope` activates the kit in apps that still include it scoped.\n host: { class: 'rb-scope', '[class.showcase--example]': 'example() !== null' },\n})\nexport class DesignSystemShowcaseComponent {\n protected readonly theme = inject(ThemeService);\n private readonly confirmDialog = inject(RbConfirmDialogService);\n\n protected readonly version = RB_DESIGN_SYSTEM_VERSION;\n protected readonly colorGroups = COLOR_GROUPS;\n protected readonly typeRoles = TYPE_ROLES;\n protected readonly spaceSteps = ['1', '2', '3', '4', '5', '6', '8', '10', '12', '16'];\n protected readonly radii = ['xs', 'sm', 'md', 'lg', 'xl', 'full'];\n protected readonly elevations = ['0', '1', '2', '3'];\n protected readonly messageSamples = MESSAGE_SAMPLES;\n protected readonly chipSamples = CHIP_SAMPLES;\n protected readonly tableRows = TABLE_ROWS;\n protected readonly tableColumns = ['name', 'clientId', 'status', 'updated'];\n protected readonly buttonRoles = BUTTON_ROLES;\n protected readonly monogramSizes = MONOGRAM_SIZES;\n protected readonly iconTiles = ICON_TILES;\n\n /** `?example=<kind>` renders one shell example full page instead of the reference. */\n protected readonly example = toSignal(\n inject(ActivatedRoute).queryParamMap.pipe(\n map((params) => {\n const kind = params.get('example') as RbShellExampleKind | null;\n return kind && RB_SHELL_EXAMPLE_KINDS.includes(kind) ? kind : null;\n }),\n ),\n { initialValue: null },\n );\n\n // Relative to the base href: the showcase is routed at `design-system` in every app. The frames\n // are re-created when the theme changes (see the template), so they pick up a stored choice.\n private readonly sanitizer = inject(DomSanitizer);\n protected readonly shellExamples = SHELL_EXAMPLES.map((example) => ({\n ...example,\n src: this.sanitizer.bypassSecurityTrustResourceUrl(\n `design-system?example=${example.kind}`,\n ) as SafeResourceUrl,\n }));\n\n protected readonly headerMetrics = computed<RbPageHeaderMetric[]>(() => [\n { label: 'Kit version', value: this.version },\n { label: 'Theme', value: this.theme.isDark() ? 'Dark' : 'Light' },\n { label: 'Components', value: 12 },\n { label: 'Contrast', value: 'WCAG 2.2 AA', tone: 'success' },\n ]);\n\n protected readonly defaultScopes = DEFAULT_SCOPES;\n protected readonly scopes = signal(DEFAULT_SCOPES);\n\n /** Mounted from the start so the result of each dialog is announced (section 9.5). */\n protected readonly dialogResult = signal('No confirmation opened yet.');\n protected readonly dialogResultTone = signal<RbMessageTone>('neutral');\n\n protected async openConfirm(kind: 'primary' | 'danger' | 'reason'): Promise<void> {\n const data: RbConfirmDialogData =\n kind === 'primary'\n ? {\n title: 'Publish release notes?',\n description: 'Every signed-in user sees the notes on their next visit.',\n confirmLabel: 'Publish notes',\n }\n : {\n title: 'Revoke this credential?',\n description: 'Clients using it stop working immediately. This cannot be undone.',\n confirmLabel: 'Revoke credential',\n tone: 'danger',\n ...(kind === 'reason'\n ? { reason: { label: 'Reason for revoking', hint: 'Recorded in the audit log.' } }\n : {}),\n };\n this.showResult(await this.confirmDialog.confirm(data));\n }\n\n protected removeScope(scope: string): void {\n this.scopes.update((scopes) => scopes.filter((item) => item !== scope));\n }\n\n protected resetScopes(): void {\n this.scopes.set(DEFAULT_SCOPES);\n }\n\n private showResult(result: RbConfirmDialogResult): void {\n this.dialogResultTone.set(result.confirmed ? 'success' : 'neutral');\n this.dialogResult.set(\n result.confirmed\n ? `Confirmed${result.reason ? ` with reason “${result.reason}”` : ''}.`\n : 'Cancelled. Nothing changed.',\n );\n }\n}\n","@if (example(); as kind) {\n <rb-showcase-shell-example [kind]=\"kind\" />\n} @else {\n <!-- Focuses main itself: under <base href=\"/\"> the bare fragment would load the root route. -->\n <a\n class=\"rb-skip-link\"\n href=\"#rb-showcase-main\"\n (click)=\"$event.preventDefault(); showcaseMain.focus()\"\n >Skip to main content</a\n >\n\n <main\n #showcaseMain\n id=\"rb-showcase-main\"\n class=\"showcase__main\"\n tabindex=\"-1\"\n aria-label=\"Design system reference\"\n >\n <rb-page-header\n class=\"showcase__header\"\n eyebrow=\"RB Labs Design System\"\n title=\"Foundations and components\"\n [description]=\"\n theme.preference() === null\n ? 'Tokens, Material components and the content kit, following the operating system theme.'\n : 'Tokens, Material components and the content kit.'\n \"\n [metrics]=\"headerMetrics()\"\n >\n <rb-theme-toggle rbActions />\n </rb-page-header>\n\n <section class=\"showcase__section\" aria-labelledby=\"showcase-color\">\n <h2 id=\"showcase-color\" class=\"showcase__heading\">Color roles</h2>\n @for (group of colorGroups; track group.title) {\n <h3 class=\"showcase__subheading\">{{ group.title }}</h3>\n <ul class=\"showcase__swatches\">\n @for (role of group.roles; track role.token) {\n <li class=\"showcase__swatch\">\n <span\n class=\"showcase__chip\"\n [style.background-color]=\"'var(--rb-color-' + role.token + ')'\"\n [style.color]=\"role.on ? 'var(--rb-color-' + role.on + ')' : null\"\n aria-hidden=\"true\"\n >{{ role.on ? 'Aa' : '' }}</span\n >\n <code>--rb-color-{{ role.token }}</code>\n @if (role.on) {\n <span class=\"showcase__note\">text: {{ role.on }}</span>\n }\n </li>\n }\n </ul>\n }\n </section>\n\n <section class=\"showcase__section\" aria-labelledby=\"showcase-type\">\n <h2 id=\"showcase-type\" class=\"showcase__heading\">Type scale</h2>\n <ul class=\"showcase__list\">\n @for (role of typeRoles; track role) {\n <li class=\"showcase__type-row\">\n <code>{{ role }}</code>\n <span\n class=\"showcase__type-sample\"\n [style.font]=\"'var(--rb-type-' + role + ')'\"\n [style.letter-spacing]=\"'var(--rb-type-' + role + '-tracking)'\"\n >Operate RB Labs</span\n >\n </li>\n }\n </ul>\n <p class=\"showcase__mono\">ui-monospace · usr_01HZX9 · sha256:2b4f69c9</p>\n </section>\n\n <section class=\"showcase__section\" aria-labelledby=\"showcase-space\">\n <h2 id=\"showcase-space\" class=\"showcase__heading\">Spacing</h2>\n <ul class=\"showcase__list\">\n @for (step of spaceSteps; track step) {\n <li class=\"showcase__space-row\">\n <code>--rb-space-{{ step }}</code>\n <span\n class=\"showcase__space-bar\"\n [style.inline-size]=\"'var(--rb-space-' + step + ')'\"\n aria-hidden=\"true\"\n ></span>\n </li>\n }\n </ul>\n </section>\n\n <section class=\"showcase__section\" aria-labelledby=\"showcase-shape\">\n <h2 id=\"showcase-shape\" class=\"showcase__heading\">Radius and elevation</h2>\n <ul class=\"showcase__tiles\">\n @for (radius of radii; track radius) {\n <li class=\"showcase__tile\" [style.border-radius]=\"'var(--rb-radius-' + radius + ')'\">\n <code>radius-{{ radius }}</code>\n </li>\n }\n </ul>\n <ul class=\"showcase__tiles\">\n @for (level of elevations; track level) {\n <li\n class=\"showcase__tile showcase__tile--raised\"\n [style.box-shadow]=\"'var(--rb-elevation-' + level + ')'\"\n >\n <code>elevation-{{ level }}</code>\n </li>\n }\n </ul>\n </section>\n\n <section class=\"showcase__section\" aria-labelledby=\"showcase-material\">\n <h2 id=\"showcase-material\" class=\"showcase__heading\">Buttons</h2>\n <p class=\"showcase__lead\">\n There is no kit button component. Each role maps to an Angular Material button variant.\n </p>\n <div class=\"rb-table-scroll\">\n <table class=\"rb-table\">\n <caption class=\"rb-visually-hidden\">\n Button roles and their Material markup\n </caption>\n <thead>\n <tr>\n <th scope=\"col\">Role</th>\n <th scope=\"col\">Markup</th>\n <th scope=\"col\">Equivalent selector</th>\n </tr>\n </thead>\n <tbody>\n @for (button of buttonRoles; track button.role) {\n <tr>\n <td data-label=\"Role\">{{ button.role }}</td>\n <td data-label=\"Markup\">\n <code>{{ button.markup }}</code>\n </td>\n <td data-label=\"Equivalent selector\">\n <code>{{ button.legacy }}</code>\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n <div class=\"rb-action-group\">\n <button matButton=\"filled\" type=\"button\">Primary</button>\n <button matButton=\"outlined\" type=\"button\">Secondary</button>\n <button matButton type=\"button\">Tertiary</button>\n <button matButton=\"tonal\" type=\"button\">Tonal</button>\n <button matButton=\"filled\" type=\"button\" disabled>Disabled</button>\n </div>\n <div class=\"rb-action-group\">\n <button matButton=\"filled\" color=\"warn\" type=\"button\">\n <mat-icon aria-hidden=\"true\">delete</mat-icon>\n Delete\n </button>\n <button matButton=\"outlined\" color=\"warn\" type=\"button\">Revoke</button>\n <button matButton color=\"warn\" type=\"button\">Remove</button>\n <button\n matIconButton\n color=\"warn\"\n type=\"button\"\n aria-label=\"Delete item\"\n matTooltip=\"Delete item\"\n >\n <mat-icon aria-hidden=\"true\">delete</mat-icon>\n </button>\n <button matIconButton type=\"button\" aria-label=\"Edit item\" matTooltip=\"Edit item\">\n <mat-icon aria-hidden=\"true\">edit</mat-icon>\n </button>\n </div>\n <p class=\"showcase__lead\">\n A link that navigates uses the same variants on an <code><a></code>. On coarse\n pointers it reaches the touch target like a button.\n </p>\n <div class=\"rb-action-group\">\n <a matButton=\"filled\" routerLink=\".\" fragment=\"showcase-material\">Primary link</a>\n <a matButton=\"outlined\" routerLink=\".\" fragment=\"showcase-material\">Secondary link</a>\n <a matButton routerLink=\".\" fragment=\"showcase-material\">Tertiary link</a>\n <a matButton=\"tonal\" routerLink=\".\" fragment=\"showcase-material\">Tonal link</a>\n <a\n matIconButton\n routerLink=\".\"\n fragment=\"showcase-material\"\n aria-label=\"Go to buttons\"\n matTooltip=\"Go to buttons\"\n >\n <mat-icon aria-hidden=\"true\">arrow_forward</mat-icon>\n </a>\n </div>\n </section>\n\n <section class=\"showcase__section\" aria-labelledby=\"showcase-shells\">\n <h2 id=\"showcase-shells\" class=\"showcase__heading\">Shells and brand</h2>\n\n <h3 class=\"showcase__subheading\">Brand lockup and monogram</h3>\n <div class=\"showcase__brand-row\">\n <rb-brand-lockup appName=\"Admin\" link=\"/design-system\" />\n <rb-brand-lockup appName=\"Photogrammetry\" link=\"/design-system\" />\n <rb-brand-lockup appName=\"Rover\" link=\"/design-system\" compact />\n </div>\n <ul class=\"showcase__brand-row showcase__brand-row--list\" aria-label=\"Monogram sizes\">\n @for (size of monogramSizes; track size.token) {\n <li class=\"showcase__monogram\">\n <rb-monogram [style.inline-size]=\"size.value\" />\n <code>{{ size.token }}</code>\n </li>\n }\n </ul>\n\n <p class=\"showcase__lead\">\n Each preview is a frame whose width is the viewport, so on narrow screens the sidenav\n becomes a drawer and the module nav a tab bar. The previews are inert, so their landmarks do\n not repeat in this page; open the full page to use an example.\n </p>\n @for (example of shellExamples; track example.kind + theme.theme()) {\n <h3 class=\"showcase__subheading\">{{ example.title }}</h3>\n <p class=\"showcase__lead\">\n {{ example.description }}\n <a routerLink=\".\" [queryParams]=\"{ example: example.kind }\">Open full page</a>\n </p>\n <iframe\n class=\"showcase__frame\"\n [title]=\"example.title + ' example'\"\n [src]=\"example.src\"\n loading=\"lazy\"\n inert\n ></iframe>\n }\n </section>\n\n <section class=\"showcase__section\" aria-labelledby=\"showcase-components\">\n <h2 id=\"showcase-components\" class=\"showcase__heading\">Content components</h2>\n\n <h3 class=\"showcase__subheading\">Page header</h3>\n <p class=\"showcase__lead\">\n The header of this page is an <code>rb-page-header</code> with an eyebrow, description,\n metrics and the theme toggle as its action. A page has exactly one.\n </p>\n\n <h3 class=\"showcase__subheading\">Panel</h3>\n <div class=\"showcase__grid\">\n <rb-panel title=\"Default\" description=\"Cards and grouped content.\" [headingLevel]=\"4\">\n <button rbActions matButton type=\"button\">\n <mat-icon aria-hidden=\"true\">refresh</mat-icon>\n Refresh\n </button>\n <p class=\"showcase__text\">Surface background, border and elevation 1.</p>\n </rb-panel>\n <rb-panel\n title=\"Soft\"\n description=\"Secondary or inset content.\"\n variant=\"soft\"\n [headingLevel]=\"4\"\n >\n <p class=\"showcase__text\">Sunken surface, no shadow.</p>\n </rb-panel>\n <rb-panel\n title=\"Elevated\"\n description=\"Content that floats above the page.\"\n variant=\"elevated\"\n [headingLevel]=\"4\"\n >\n <p class=\"showcase__text\">Raised surface and elevation 2.</p>\n </rb-panel>\n <rb-panel\n title=\"Danger zone\"\n description=\"Destructive settings.\"\n variant=\"danger\"\n [headingLevel]=\"4\"\n >\n <button rbActions matButton=\"outlined\" color=\"warn\" type=\"button\">Delete</button>\n <p class=\"showcase__text\">Danger border and title; the title names the risk.</p>\n </rb-panel>\n </div>\n\n <h3 class=\"showcase__subheading\">Message</h3>\n <div class=\"rb-stack rb-stack--sm\">\n @for (sample of messageSamples; track sample.tone) {\n <rb-message [tone]=\"sample.tone\" [title]=\"sample.title\" live=\"off\">\n {{ sample.body }}\n </rb-message>\n }\n </div>\n\n <h3 class=\"showcase__subheading\">Empty state</h3>\n <div class=\"showcase__grid\">\n <rb-panel title=\"Applications\" [headingLevel]=\"4\">\n <rb-empty-state\n icon=\"apps\"\n title=\"No applications yet\"\n description=\"Register a client to issue credentials for RB Labs sign-in.\"\n actionLabel=\"Register application\"\n [headingLevel]=\"5\"\n />\n </rb-panel>\n <rb-panel title=\"Audit history\" variant=\"soft\" [headingLevel]=\"4\">\n <rb-empty-state\n icon=\"history\"\n title=\"Nothing recorded\"\n description=\"Changes to this application appear here.\"\n layout=\"inline\"\n [headingLevel]=\"5\"\n />\n </rb-panel>\n </div>\n\n <h3 class=\"showcase__subheading\">Status chip</h3>\n <div class=\"rb-action-group\">\n @for (chip of chipSamples; track chip.tone) {\n <rb-status-chip [tone]=\"chip.tone\" [label]=\"chip.label\" />\n }\n </div>\n <div class=\"rb-action-group\">\n @for (chip of chipSamples; track chip.tone) {\n <rb-status-chip [tone]=\"chip.tone\" [label]=\"chip.label\" size=\"compact\" />\n }\n <rb-status-chip label=\"Locked\" icon=\"lock\" size=\"compact\" />\n </div>\n\n <h3 class=\"showcase__subheading\">Technical value</h3>\n <dl class=\"rb-meta-grid\">\n <div class=\"rb-meta-grid__item\">\n <dt class=\"rb-meta-grid__label\">Fits</dt>\n <dd class=\"rb-meta-grid__value\"><rb-technical-value value=\"usr_01HZX9\" /></dd>\n </div>\n <div class=\"rb-meta-grid__item showcase__narrow\">\n <dt class=\"rb-meta-grid__label\">Truncated</dt>\n <dd class=\"rb-meta-grid__value\">\n <rb-technical-value\n value=\"https://auth.rblabs.dev/oauth/callback/photogrammetry-workspace\"\n />\n </dd>\n </div>\n <div class=\"rb-meta-grid__item\">\n <dt class=\"rb-meta-grid__label\">Shortened</dt>\n <dd class=\"rb-meta-grid__value\">\n <rb-technical-value\n value=\"sha256:2b4f69c9d1e0a7b35c8e6f41a9d2c7b0e3f5a8c1d4b7e0f2a5c8d1e4b7a0c3f6\"\n displayValue=\"sha256:2b4f69c9…\"\n />\n </dd>\n </div>\n </dl>\n\n <h3 class=\"showcase__subheading\">Confirmation dialog</h3>\n <div class=\"rb-action-group\">\n <button matButton=\"outlined\" type=\"button\" (click)=\"openConfirm('primary')\">\n Confirm an action\n </button>\n <button matButton=\"outlined\" color=\"warn\" type=\"button\" (click)=\"openConfirm('danger')\">\n Confirm a destructive action\n </button>\n <button matButton=\"outlined\" color=\"warn\" type=\"button\" (click)=\"openConfirm('reason')\">\n Confirm with a reason\n </button>\n </div>\n <rb-message [tone]=\"dialogResultTone()\" title=\"Last result\">{{ dialogResult() }}</rb-message>\n </section>\n\n <section class=\"showcase__section\" aria-labelledby=\"showcase-classes\">\n <h2 id=\"showcase-classes\" class=\"showcase__heading\">Style classes</h2>\n\n <h3 class=\"showcase__subheading\">Forms</h3>\n <form class=\"rb-form-grid\" (submit)=\"$event.preventDefault()\">\n <div class=\"rb-field\">\n <label class=\"rb-field__label\" for=\"showcase-field-name\">Application name</label>\n <input\n id=\"showcase-field-name\"\n class=\"rb-field__control\"\n type=\"text\"\n value=\"Photogrammetry workspace\"\n aria-describedby=\"showcase-field-name-hint\"\n />\n <p id=\"showcase-field-name-hint\" class=\"rb-field__hint\">Shown on the consent screen.</p>\n </div>\n <div class=\"rb-field\">\n <label class=\"rb-field__label\" for=\"showcase-field-environment\">Environment</label>\n <select id=\"showcase-field-environment\" class=\"rb-field__control\">\n <option>Production</option>\n <option>Staging</option>\n </select>\n </div>\n <div class=\"rb-field rb-field--invalid\">\n <label class=\"rb-field__label\" for=\"showcase-field-uri\">Redirect URI</label>\n <input\n id=\"showcase-field-uri\"\n class=\"rb-field__control\"\n type=\"url\"\n value=\"http://photogrammetry\"\n aria-invalid=\"true\"\n aria-describedby=\"showcase-field-uri-error\"\n />\n <p id=\"showcase-field-uri-error\" class=\"rb-field__error\">\n Enter an https:// address, for example https://app.rblabs.dev/callback.\n </p>\n </div>\n <div class=\"rb-field rb-field--disabled\">\n <label class=\"rb-field__label\" for=\"showcase-field-client\">Client ID</label>\n <input\n id=\"showcase-field-client\"\n class=\"rb-field__control\"\n type=\"text\"\n value=\"app_01J2B7F9P4L6X3V8S1D5G0HAKM\"\n disabled\n aria-describedby=\"showcase-field-client-hint\"\n />\n <p id=\"showcase-field-client-hint\" class=\"rb-field__hint\">\n Generated at registration and cannot be changed.\n </p>\n </div>\n <div class=\"rb-field rb-form-grid__full\">\n <label class=\"rb-field__label\" for=\"showcase-field-notes\">Notes</label>\n <textarea\n id=\"showcase-field-notes\"\n class=\"rb-field__control\"\n placeholder=\"Optional context for other administrators\"\n ></textarea>\n </div>\n <mat-form-field appearance=\"outline\">\n <mat-label>Display name (mat-form-field)</mat-label>\n <input matInput value=\"Photogrammetry\" />\n <mat-hint>Material fields sit in the same grid.</mat-hint>\n </mat-form-field>\n <div class=\"rb-field rb-form-grid__full\">\n <span id=\"showcase-field-scopes\" class=\"rb-field__label\"\n >Granted scopes (mat-chip-grid)</span\n >\n @if (scopes().length > 0) {\n <mat-chip-grid aria-labelledby=\"showcase-field-scopes\">\n @for (scope of scopes(); track scope) {\n <mat-chip-row (removed)=\"removeScope(scope)\">\n {{ scope }}\n <button matChipRemove [attr.aria-label]=\"'Remove ' + scope\">\n <mat-icon aria-hidden=\"true\">close</mat-icon>\n </button>\n </mat-chip-row>\n }\n </mat-chip-grid>\n } @else {\n <p class=\"rb-field__hint\">No scopes granted.</p>\n }\n <p class=\"rb-field__hint\">\n Remove buttons are at least 24px on fine pointers and 44px on coarse pointers.\n @if (scopes().length < defaultScopes.length) {\n <button matButton type=\"button\" (click)=\"resetScopes()\">Restore scopes</button>\n }\n </p>\n </div>\n </form>\n\n <h3 class=\"showcase__subheading\">Tables</h3>\n <p class=\"showcase__lead\">\n Below the <code>md</code> breakpoint each row becomes a stacked record labelled from\n <code>data-label</code>.\n </p>\n <div class=\"rb-table-scroll\">\n <table class=\"rb-table\">\n <caption class=\"rb-visually-hidden\">\n Registered applications\n </caption>\n <thead>\n <tr>\n <th scope=\"col\">Name</th>\n <th scope=\"col\">Client ID</th>\n <th scope=\"col\">Status</th>\n <th scope=\"col\">Updated</th>\n <th scope=\"col\"><span class=\"rb-visually-hidden\">Actions</span></th>\n </tr>\n </thead>\n <tbody>\n @for (row of tableRows; track row.clientId) {\n <tr>\n <td data-label=\"Name\">{{ row.name }}</td>\n <td data-label=\"Client ID\" class=\"showcase__cell-id\">\n <rb-technical-value [value]=\"row.clientId\" />\n </td>\n <td data-label=\"Status\">\n <rb-status-chip\n [tone]=\"row.status.tone\"\n [label]=\"row.status.label\"\n size=\"compact\"\n />\n </td>\n <td data-label=\"Updated\">{{ row.updated }}</td>\n <td>\n <div class=\"rb-table__actions\">\n <button\n matIconButton\n type=\"button\"\n [attr.aria-label]=\"'Edit ' + row.name\"\n [matTooltip]=\"'Edit ' + row.name\"\n >\n <mat-icon aria-hidden=\"true\">edit</mat-icon>\n </button>\n <button\n matIconButton\n color=\"warn\"\n type=\"button\"\n [attr.aria-label]=\"'Delete ' + row.name\"\n [matTooltip]=\"'Delete ' + row.name\"\n >\n <mat-icon aria-hidden=\"true\">delete</mat-icon>\n </button>\n </div>\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n\n <div class=\"showcase__grid\">\n <div class=\"rb-table-scroll\">\n <table class=\"rb-table\" aria-busy=\"true\">\n <caption class=\"rb-visually-hidden\">\n Applications, loading\n </caption>\n <thead>\n <tr>\n <th scope=\"col\">Name</th>\n <th scope=\"col\">Status</th>\n </tr>\n </thead>\n <tbody>\n @for (row of [1, 2, 3]; track row) {\n <tr class=\"rb-table__skeleton-row\" aria-hidden=\"true\">\n <td><span class=\"rb-skeleton\"></span></td>\n <td><span class=\"rb-skeleton\"></span></td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n <div class=\"rb-table-scroll\">\n <table class=\"rb-table\">\n <caption class=\"rb-visually-hidden\">\n Applications matching “rover”\n </caption>\n <thead>\n <tr>\n <th scope=\"col\">Name</th>\n <th scope=\"col\">Status</th>\n </tr>\n </thead>\n <tbody>\n <tr class=\"rb-table__empty-row\">\n <td colspan=\"2\">No applications match “rover”.</td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n\n <p class=\"showcase__lead\">\n <code>mat-table</code> with <code>rb-table--inline</code>: the grid is kept on phones and\n scrolls inside <code>rb-table-scroll</code>, which is focusable so keyboard users can scroll\n it.\n </p>\n <div\n class=\"rb-table-scroll\"\n role=\"region\"\n aria-label=\"Registered applications, scrollable\"\n tabindex=\"0\"\n >\n <table mat-table class=\"rb-table rb-table--inline\" [dataSource]=\"tableRows\">\n <ng-container matColumnDef=\"name\">\n <th mat-header-cell *matHeaderCellDef scope=\"col\">Name</th>\n <td mat-cell *matCellDef=\"let row\" data-label=\"Name\">{{ row.name }}</td>\n </ng-container>\n <ng-container matColumnDef=\"clientId\">\n <th mat-header-cell *matHeaderCellDef scope=\"col\">Client ID</th>\n <td mat-cell *matCellDef=\"let row\" data-label=\"Client ID\">\n <rb-technical-value [value]=\"row.clientId\" />\n </td>\n </ng-container>\n <ng-container matColumnDef=\"status\">\n <th mat-header-cell *matHeaderCellDef scope=\"col\">Status</th>\n <td mat-cell *matCellDef=\"let row\" data-label=\"Status\">\n <rb-status-chip [tone]=\"row.status.tone\" [label]=\"row.status.label\" size=\"compact\" />\n </td>\n </ng-container>\n <ng-container matColumnDef=\"updated\">\n <th mat-header-cell *matHeaderCellDef scope=\"col\">Updated</th>\n <td mat-cell *matCellDef=\"let row\" data-label=\"Updated\">{{ row.updated }}</td>\n </ng-container>\n <tr mat-header-row *matHeaderRowDef=\"tableColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: tableColumns\"></tr>\n <tr *matNoDataRow>\n <td [attr.colspan]=\"tableColumns.length\">No applications.</td>\n </tr>\n </table>\n </div>\n\n <h3 class=\"showcase__subheading\">Layout</h3>\n <div class=\"rb-master-detail\">\n <rb-panel\n title=\"rb-master-detail\"\n description=\"List on the left, detail on the right.\"\n variant=\"soft\"\n [headingLevel]=\"4\"\n >\n <div class=\"rb-stack rb-stack--sm\">\n <span class=\"rb-skeleton\" aria-hidden=\"true\"></span>\n <span class=\"rb-skeleton\" aria-hidden=\"true\"></span>\n <span class=\"rb-skeleton\" aria-hidden=\"true\"></span>\n </div>\n </rb-panel>\n <rb-panel title=\"Detail\" description=\"Stacks below the xl breakpoint.\" [headingLevel]=\"4\">\n <div class=\"rb-stack\">\n <dl class=\"rb-meta-grid\">\n <div class=\"rb-meta-grid__item\">\n <dt class=\"rb-meta-grid__label\">Owner</dt>\n <dd class=\"rb-meta-grid__value\">Platform team</dd>\n </div>\n <div class=\"rb-meta-grid__item\">\n <dt class=\"rb-meta-grid__label\">Created</dt>\n <dd class=\"rb-meta-grid__value\">3 Mar 2026</dd>\n </div>\n <div class=\"rb-meta-grid__item\">\n <dt class=\"rb-meta-grid__label\">Scopes</dt>\n <dd class=\"rb-meta-grid__value\">openid profile</dd>\n </div>\n </dl>\n <span class=\"rb-skeleton rb-skeleton--heading\" aria-hidden=\"true\"></span>\n <span class=\"rb-skeleton rb-skeleton--control\" aria-hidden=\"true\"></span>\n <div class=\"rb-action-group rb-action-group--between rb-action-group--mobile-stack\">\n <button matButton color=\"warn\" type=\"button\">Delete</button>\n <div class=\"rb-action-group rb-action-group--end rb-action-group--mobile-stack\">\n <button matButton=\"outlined\" type=\"button\">Cancel</button>\n <button matButton=\"filled\" type=\"button\">Save changes</button>\n </div>\n </div>\n </div>\n </rb-panel>\n </div>\n\n <h3 class=\"showcase__subheading\">Text and landing</h3>\n <p class=\"showcase__lead\">\n The hero, tags and icon tiles of the public home pages, and the two uppercase label roles.\n </p>\n <div class=\"rb-hero\">\n <div class=\"rb-hero__copy\">\n <p class=\"rb-eyebrow\">\n <mat-icon aria-hidden=\"true\">deployed_code</mat-icon>\n rb-eyebrow\n </p>\n <p class=\"rb-hero__title\">One standard for every RB Labs app</p>\n <p class=\"rb-hero__lead\">\n <code>.rb-hero__title</code> uses the hero type role; <code>.rb-hero__lead</code> sits\n under it. Below the lg breakpoint the media column moves under the copy.\n </p>\n <ul class=\"rb-tag-list\" aria-label=\"Stack\">\n <li>Angular</li>\n <li>Angular Material 3</li>\n <li>WCAG 2.2 AA</li>\n </ul>\n </div>\n <rb-panel title=\"Media column\" variant=\"soft\" [headingLevel]=\"4\">\n <ul class=\"showcase__icon-tiles\">\n @for (tile of iconTiles; track tile.label) {\n <li>\n <span class=\"rb-icon-tile\" aria-hidden=\"true\">\n <mat-icon>{{ tile.icon }}</mat-icon>\n </span>\n <span>\n <span class=\"rb-overline\">{{ tile.overline }}</span>\n <a class=\"rb-table__link\" routerLink=\".\" fragment=\"showcase-classes\">{{\n tile.label\n }}</a>\n </span>\n </li>\n }\n </ul>\n </rb-panel>\n </div>\n </section>\n </main>\n}\n"],"mappings":"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"}
|