Browse Patterns
Card Grid
Card grid page layout for browseable collections like infrastructure dashboards, asset catalogs, or media galleries. Use with view-mode toggles for switching between grid and table presentations.
<nve-page>
<nve-page-header slot="header">
<nve-logo slot="prefix" size="sm" color="brand-green">NV</nve-logo>
<h2 nve-text="heading" slot="prefix">Infrastructure</h2>
<nve-button selected container="flat">Link 1</nve-button>
<nve-button container="flat">Link 2</nve-button>
<nve-icon-button interaction="emphasis" slot="suffix" size="sm">EL</nve-icon-button>
</nve-page-header>
<main nve-layout="column gap:lg pad:lg align:horizontal-stretch">
<nve-search container="flat">
<input type="search" aria-label="search drives" />
</nve-search>
<nve-button-group container="rounded" behavior-select="single" orientation="horizontal">
<nve-icon-button icon-name="view-as-grid" pressed></nve-icon-button>
<nve-icon-button icon-name="table"></nve-icon-button>
<nve-icon-button icon-name="map"></nve-icon-button>
</nve-button-group>
<section nve-layout="grid span-items:3 gap:md">
<nve-card style="height: 100%; width: 100%">
<img src="/static/images/test-image-1.svg" alt="example visualization for media card demo" loading="lazy" style="width: 100%; object-fit: cover" />
<nve-card-content>
<p nve-text="body">โข๏ธโข๏ธโข๏ธ โข๏ธโข๏ธโข๏ธ โข๏ธโข๏ธโข๏ธ</p>
</nve-card-content>
<nve-card-footer>
<div nve-layout="grid span-items:6 gap:xs">
<nve-button>โข๏ธโข๏ธโข๏ธโข๏ธโข๏ธโข๏ธ</nve-button>
<nve-button>โข๏ธโข๏ธโข๏ธโข๏ธโข๏ธโข๏ธ</nve-button>
</div>
</nve-card-footer>
</nve-card>
<nve-card style="height: 100%; width: 100%">
<img src="/static/images/test-image-1.svg" alt="example visualization for media card demo" loading="lazy" style="width: 100%; object-fit: cover" />
<nve-card-content>
<p nve-text="body">โข๏ธโข๏ธโข๏ธ โข๏ธโข๏ธโข๏ธ โข๏ธโข๏ธโข๏ธ</p>
</nve-card-content>
<nve-card-footer>
<div nve-layout="grid span-items:6 gap:xs">
<nve-button>โข๏ธโข๏ธโข๏ธโข๏ธโข๏ธโข๏ธ</nve-button>
<nve-button>โข๏ธโข๏ธโข๏ธโข๏ธโข๏ธโข๏ธ</nve-button>
</div>
</nve-card-footer>
</nve-card>
<nve-card style="height: 100%; width: 100%">
<img src="/static/images/test-image-1.svg" alt="example visualization for media card demo" loading="lazy" style="width: 100%; object-fit: cover" />
<nve-card-content>
<p nve-text="body">โข๏ธโข๏ธโข๏ธ โข๏ธโข๏ธโข๏ธ โข๏ธโข๏ธโข๏ธ</p>
</nve-card-content>
<nve-card-footer>
<div nve-layout="grid span-items:6 gap:xs">
<nve-button>โข๏ธโข๏ธโข๏ธโข๏ธโข๏ธโข๏ธ</nve-button>
<nve-button>โข๏ธโข๏ธโข๏ธโข๏ธโข๏ธโข๏ธ</nve-button>
</div>
</nve-card-footer>
</nve-card>
<nve-card style="height: 100%; width: 100%">
<img src="/static/images/test-image-1.svg" alt="example visualization for media card demo" loading="lazy" style="width: 100%; object-fit: cover" />
<nve-card-content>
<p nve-text="body">โข๏ธโข๏ธโข๏ธ โข๏ธโข๏ธโข๏ธ โข๏ธโข๏ธโข๏ธ</p>
</nve-card-content>
<nve-card-footer>
<div nve-layout="grid span-items:6 gap:xs">
<nve-button>โข๏ธโข๏ธโข๏ธโข๏ธโข๏ธโข๏ธ</nve-button>
<nve-button>โข๏ธโข๏ธโข๏ธโข๏ธโข๏ธโข๏ธ</nve-button>
</div>
</nve-card-footer>
</nve-card>
<nve-card style="height: 100%; width: 100%">
<img src="/static/images/test-image-1.svg" alt="example visualization for media card demo" loading="lazy" style="width: 100%; object-fit: cover" />
<nve-card-content>
<p nve-text="body">โข๏ธโข๏ธโข๏ธ โข๏ธโข๏ธโข๏ธ โข๏ธโข๏ธโข๏ธ</p>
</nve-card-content>
<nve-card-footer>
<div nve-layout="grid span-items:6 gap:xs">
<nve-button>โข๏ธโข๏ธโข๏ธโข๏ธโข๏ธโข๏ธ</nve-button>
<nve-button>โข๏ธโข๏ธโข๏ธโข๏ธโข๏ธโข๏ธ</nve-button>
</div>
</nve-card-footer>
</nve-card>
<nve-card style="height: 100%; width: 100%">
<img src="/static/images/test-image-1.svg" alt="example visualization for media card demo" loading="lazy" style="width: 100%; object-fit: cover" />
<nve-card-content>
<p nve-text="body">โข๏ธโข๏ธโข๏ธ โข๏ธโข๏ธโข๏ธ โข๏ธโข๏ธโข๏ธ</p>
</nve-card-content>
<nve-card-footer>
<div nve-layout="grid span-items:6 gap:xs">
<nve-button>โข๏ธโข๏ธโข๏ธโข๏ธโข๏ธโข๏ธ</nve-button>
<nve-button>โข๏ธโข๏ธโข๏ธโข๏ธโข๏ธโข๏ธ</nve-button>
</div>
</nve-card-footer>
</nve-card>
<nve-card style="height: 100%; width: 100%">
<img src="/static/images/test-image-1.svg" alt="example visualization for media card demo" loading="lazy" style="width: 100%; object-fit: cover" />
<nve-card-content>
<p nve-text="body">โข๏ธโข๏ธโข๏ธ โข๏ธโข๏ธโข๏ธ โข๏ธโข๏ธโข๏ธ</p>
</nve-card-content>
<nve-card-footer>
<div nve-layout="grid span-items:6 gap:xs">
<nve-button>โข๏ธโข๏ธโข๏ธโข๏ธโข๏ธโข๏ธ</nve-button>
<nve-button>โข๏ธโข๏ธโข๏ธโข๏ธโข๏ธโข๏ธ</nve-button>
</div>
</nve-card-footer>
</nve-card>
<nve-card style="height: 100%; width: 100%">
<img src="/static/images/test-image-1.svg" alt="example visualization for media card demo" loading="lazy" style="width: 100%; object-fit: cover" />
<nve-card-content>
<p nve-text="body">โข๏ธโข๏ธโข๏ธ โข๏ธโข๏ธโข๏ธ โข๏ธโข๏ธโข๏ธ</p>
</nve-card-content>
<nve-card-footer>
<div nve-layout="grid span-items:6 gap:xs">
<nve-button>โข๏ธโข๏ธโข๏ธโข๏ธโข๏ธโข๏ธ</nve-button>
<nve-button>โข๏ธโข๏ธโข๏ธโข๏ธโข๏ธโข๏ธ</nve-button>
</div>
</nve-card-footer>
</nve-card>
<nve-card style="height: 100%; width: 100%">
<img src="/static/images/test-image-1.svg" alt="example visualization for media card demo" loading="lazy" style="width: 100%; object-fit: cover" />
<nve-card-content>
<p nve-text="body">โข๏ธโข๏ธโข๏ธ โข๏ธโข๏ธโข๏ธ โข๏ธโข๏ธโข๏ธ</p>
</nve-card-content>
<nve-card-footer>
<div nve-layout="grid span-items:6 gap:xs">
<nve-button>โข๏ธโข๏ธโข๏ธโข๏ธโข๏ธโข๏ธ</nve-button>
<nve-button>โข๏ธโข๏ธโข๏ธโข๏ธโข๏ธโข๏ธ</nve-button>
</div>
</nve-card-footer>
</nve-card>
<nve-card style="height: 100%; width: 100%">
<img src="/static/images/test-image-1.svg" alt="example visualization for media card demo" loading="lazy" style="width: 100%; object-fit: cover" />
<nve-card-content>
<p nve-text="body">โข๏ธโข๏ธโข๏ธ โข๏ธโข๏ธโข๏ธ โข๏ธโข๏ธโข๏ธ</p>
</nve-card-content>
<nve-card-footer>
<div nve-layout="grid span-items:6 gap:xs">
<nve-button>โข๏ธโข๏ธโข๏ธโข๏ธโข๏ธโข๏ธ</nve-button>
<nve-button>โข๏ธโข๏ธโข๏ธโข๏ธโข๏ธโข๏ธ</nve-button>
</div>
</nve-card-footer>
</nve-card>
<nve-card style="height: 100%; width: 100%">
<img src="/static/images/test-image-1.svg" alt="example visualization for media card demo" loading="lazy" style="width: 100%; object-fit: cover" />
<nve-card-content>
<p nve-text="body">โข๏ธโข๏ธโข๏ธ โข๏ธโข๏ธโข๏ธ โข๏ธโข๏ธโข๏ธ</p>
</nve-card-content>
<nve-card-footer>
<div nve-layout="grid span-items:6 gap:xs">
<nve-button>โข๏ธโข๏ธโข๏ธโข๏ธโข๏ธโข๏ธ</nve-button>
<nve-button>โข๏ธโข๏ธโข๏ธโข๏ธโข๏ธโข๏ธ</nve-button>
</div>
</nve-card-footer>
</nve-card>
<nve-card style="height: 100%; width: 100%">
<img src="/static/images/test-image-1.svg" alt="example visualization for media card demo" loading="lazy" style="width: 100%; object-fit: cover" />
<nve-card-content>
<p nve-text="body">โข๏ธโข๏ธโข๏ธ โข๏ธโข๏ธโข๏ธ โข๏ธโข๏ธโข๏ธ</p>
</nve-card-content>
<nve-card-footer>
<div nve-layout="grid span-items:6 gap:xs">
<nve-button>โข๏ธโข๏ธโข๏ธโข๏ธโข๏ธโข๏ธ</nve-button>
<nve-button>โข๏ธโข๏ธโข๏ธโข๏ธโข๏ธโข๏ธ</nve-button>
</div>
</nve-card-footer>
</nve-card>
<nve-card style="height: 100%; width: 100%">
<img src="/static/images/test-image-1.svg" alt="example visualization for media card demo" loading="lazy" style="width: 100%; object-fit: cover" />
<nve-card-content>
<p nve-text="body">โข๏ธโข๏ธโข๏ธ โข๏ธโข๏ธโข๏ธ โข๏ธโข๏ธโข๏ธ</p>
</nve-card-content>
<nve-card-footer>
<div nve-layout="grid span-items:6 gap:xs">
<nve-button>โข๏ธโข๏ธโข๏ธโข๏ธโข๏ธโข๏ธ</nve-button>
<nve-button>โข๏ธโข๏ธโข๏ธโข๏ธโข๏ธโข๏ธ</nve-button>
</div>
</nve-card-footer>
</nve-card>
<nve-card style="height: 100%; width: 100%">
<img src="/static/images/test-image-1.svg" alt="example visualization for media card demo" loading="lazy" style="width: 100%; object-fit: cover" />
<nve-card-content>
<p nve-text="body">โข๏ธโข๏ธโข๏ธ โข๏ธโข๏ธโข๏ธ โข๏ธโข๏ธโข๏ธ</p>
</nve-card-content>
<nve-card-footer>
<div nve-layout="grid span-items:6 gap:xs">
<nve-button>โข๏ธโข๏ธโข๏ธโข๏ธโข๏ธโข๏ธ</nve-button>
<nve-button>โข๏ธโข๏ธโข๏ธโข๏ธโข๏ธโข๏ธ</nve-button>
</div>
</nve-card-footer>
</nve-card>
<nve-card style="height: 100%; width: 100%">
<img src="/static/images/test-image-1.svg" alt="example visualization for media card demo" loading="lazy" style="width: 100%; object-fit: cover" />
<nve-card-content>
<p nve-text="body">โข๏ธโข๏ธโข๏ธ โข๏ธโข๏ธโข๏ธ โข๏ธโข๏ธโข๏ธ</p>
</nve-card-content>
<nve-card-footer>
<div nve-layout="grid span-items:6 gap:xs">
<nve-button>โข๏ธโข๏ธโข๏ธโข๏ธโข๏ธโข๏ธ</nve-button>
<nve-button>โข๏ธโข๏ธโข๏ธโข๏ธโข๏ธโข๏ธ</nve-button>
</div>
</nve-card-footer>
</nve-card>
<nve-card style="height: 100%; width: 100%">
<img src="/static/images/test-image-1.svg" alt="example visualization for media card demo" loading="lazy" style="width: 100%; object-fit: cover" />
<nve-card-content>
<p nve-text="body">โข๏ธโข๏ธโข๏ธ โข๏ธโข๏ธโข๏ธ โข๏ธโข๏ธโข๏ธ</p>
</nve-card-content>
<nve-card-footer>
<div nve-layout="grid span-items:6 gap:xs">
<nve-button>โข๏ธโข๏ธโข๏ธโข๏ธโข๏ธโข๏ธ</nve-button>
<nve-button>โข๏ธโข๏ธโข๏ธโข๏ธโข๏ธโข๏ธ</nve-button>
</div>
</nve-card-footer>
</nve-card>
<nve-card style="height: 100%; width: 100%">
<img src="/static/images/test-image-1.svg" alt="example visualization for media card demo" loading="lazy" style="width: 100%; object-fit: cover" />
<nve-card-content>
<p nve-text="body">โข๏ธโข๏ธโข๏ธ โข๏ธโข๏ธโข๏ธ โข๏ธโข๏ธโข๏ธ</p>
</nve-card-content>
<nve-card-footer>
<div nve-layout="grid span-items:6 gap:xs">
<nve-button>โข๏ธโข๏ธโข๏ธโข๏ธโข๏ธโข๏ธ</nve-button>
<nve-button>โข๏ธโข๏ธโข๏ธโข๏ธโข๏ธโข๏ธ</nve-button>
</div>
</nve-card-footer>
</nve-card>
<nve-card style="height: 100%; width: 100%">
<img src="/static/images/test-image-1.svg" alt="example visualization for media card demo" loading="lazy" style="width: 100%; object-fit: cover" />
<nve-card-content>
<p nve-text="body">โข๏ธโข๏ธโข๏ธ โข๏ธโข๏ธโข๏ธ โข๏ธโข๏ธโข๏ธ</p>
</nve-card-content>
<nve-card-footer>
<div nve-layout="grid span-items:6 gap:xs">
<nve-button>โข๏ธโข๏ธโข๏ธโข๏ธโข๏ธโข๏ธ</nve-button>
<nve-button>โข๏ธโข๏ธโข๏ธโข๏ธโข๏ธโข๏ธ</nve-button>
</div>
</nve-card-footer>
</nve-card>
<nve-card style="height: 100%; width: 100%">
<img src="/static/images/test-image-1.svg" alt="example visualization for media card demo" loading="lazy" style="width: 100%; object-fit: cover" />
<nve-card-content>
<p nve-text="body">โข๏ธโข๏ธโข๏ธ โข๏ธโข๏ธโข๏ธ โข๏ธโข๏ธโข๏ธ</p>
</nve-card-content>
<nve-card-footer>
<div nve-layout="grid span-items:6 gap:xs">
<nve-button>โข๏ธโข๏ธโข๏ธโข๏ธโข๏ธโข๏ธ</nve-button>
<nve-button>โข๏ธโข๏ธโข๏ธโข๏ธโข๏ธโข๏ธ</nve-button>
</div>
</nve-card-footer>
</nve-card>
<nve-card style="height: 100%; width: 100%">
<img src="/static/images/test-image-1.svg" alt="example visualization for media card demo" loading="lazy" style="width: 100%; object-fit: cover" />
<nve-card-content>
<p nve-text="body">โข๏ธโข๏ธโข๏ธ โข๏ธโข๏ธโข๏ธ โข๏ธโข๏ธโข๏ธ</p>
</nve-card-content>
<nve-card-footer>
<div nve-layout="grid span-items:6 gap:xs">
<nve-button>โข๏ธโข๏ธโข๏ธโข๏ธโข๏ธโข๏ธ</nve-button>
<nve-button>โข๏ธโข๏ธโข๏ธโข๏ธโข๏ธโข๏ธ</nve-button>
</div>
</nve-card-footer>
</nve-card>
<nve-card style="height: 100%; width: 100%">
<img src="/static/images/test-image-1.svg" alt="example visualization for media card demo" loading="lazy" style="width: 100%; object-fit: cover" />
<nve-card-content>
<p nve-text="body">โข๏ธโข๏ธโข๏ธ โข๏ธโข๏ธโข๏ธ โข๏ธโข๏ธโข๏ธ</p>
</nve-card-content>
<nve-card-footer>
<div nve-layout="grid span-items:6 gap:xs">
<nve-button>โข๏ธโข๏ธโข๏ธโข๏ธโข๏ธโข๏ธ</nve-button>
<nve-button>โข๏ธโข๏ธโข๏ธโข๏ธโข๏ธโข๏ธ</nve-button>
</div>
</nve-card-footer>
</nve-card>
<nve-card style="height: 100%; width: 100%">
<img src="/static/images/test-image-1.svg" alt="example visualization for media card demo" loading="lazy" style="width: 100%; object-fit: cover" />
<nve-card-content>
<p nve-text="body">โข๏ธโข๏ธโข๏ธ โข๏ธโข๏ธโข๏ธ โข๏ธโข๏ธโข๏ธ</p>
</nve-card-content>
<nve-card-footer>
<div nve-layout="grid span-items:6 gap:xs">
<nve-button>โข๏ธโข๏ธโข๏ธโข๏ธโข๏ธโข๏ธ</nve-button>
<nve-button>โข๏ธโข๏ธโข๏ธโข๏ธโข๏ธโข๏ธ</nve-button>
</div>
</nve-card-footer>
</nve-card>
<nve-card style="height: 100%; width: 100%">
<img src="/static/images/test-image-1.svg" alt="example visualization for media card demo" loading="lazy" style="width: 100%; object-fit: cover" />
<nve-card-content>
<p nve-text="body">โข๏ธโข๏ธโข๏ธ โข๏ธโข๏ธโข๏ธ โข๏ธโข๏ธโข๏ธ</p>
</nve-card-content>
<nve-card-footer>
<div nve-layout="grid span-items:6 gap:xs">
<nve-button>โข๏ธโข๏ธโข๏ธโข๏ธโข๏ธโข๏ธ</nve-button>
<nve-button>โข๏ธโข๏ธโข๏ธโข๏ธโข๏ธโข๏ธ</nve-button>
</div>
</nve-card-footer>
</nve-card>
<nve-card style="height: 100%; width: 100%">
<img src="/static/images/test-image-1.svg" alt="example visualization for media card demo" loading="lazy" style="width: 100%; object-fit: cover" />
<nve-card-content>
<p nve-text="body">โข๏ธโข๏ธโข๏ธ โข๏ธโข๏ธโข๏ธ โข๏ธโข๏ธโข๏ธ</p>
</nve-card-content>
<nve-card-footer>
<div nve-layout="grid span-items:6 gap:xs">
<nve-button>โข๏ธโข๏ธโข๏ธโข๏ธโข๏ธโข๏ธ</nve-button>
<nve-button>โข๏ธโข๏ธโข๏ธโข๏ธโข๏ธโข๏ธ</nve-button>
</div>
</nve-card-footer>
</nve-card>
</section>
</main>
</nve-page> Filterable Browse
Searchable collection with a persistent facet panel, active-filter feedback, result counts, and sorting. Use when people need to narrow a broad catalog without losing filter context.
<nve-page id="filterable-browse-pattern">
<style>
#filterable-browse-pattern nve-accordion {
--header-padding: var(--nve-ref-size-200) var(--nve-ref-size-400);
}
</style>
<nve-page-header slot="header">
<nve-logo slot="prefix" size="sm" color="brand-green">NV</nve-logo>
<h2 slot="prefix" nve-text="heading">Model Registry</h2>
</nve-page-header>
<nve-page-panel slot="subheader">
<nve-page-panel-content>
<div nve-layout="row gap:md align:wrap align:space-between align:vertical-center">
<div nve-layout="column gap:xs">
<h1 id="filterable-browse-title" nve-text="heading lg">Model catalog</h1>
<p nve-text="body sm muted">Find a deployable model by capability, lifecycle status, and owner.</p>
</div>
<nve-search style="width: 220px">
<input id="filterable-browse-search" type="search" aria-label="Search models" placeholder="Search name or capability" />
</nve-search>
</div>
</nve-page-panel-content>
</nve-page-panel>
<nve-page-panel slot="left" size="sm" aria-label="Model filters">
<nve-page-panel-content style="--padding: 0">
<nve-accordion-group container="flat" behavior-expand>
<nve-accordion expanded>
<nve-accordion-header>
<h3 nve-text="label medium">Status</h3>
</nve-accordion-header>
<nve-accordion-content>
<div nve-layout="column gap:sm">
<nve-checkbox>
<label>Ready <span nve-text="body sm muted">(2)</span></label>
<input type="checkbox" data-filter-key="status" value="Ready" />
</nve-checkbox>
<nve-checkbox>
<label>Preview <span nve-text="body sm muted">(1)</span></label>
<input type="checkbox" data-filter-key="status" value="Preview" />
</nve-checkbox>
</div>
</nve-accordion-content>
</nve-accordion>
<nve-accordion expanded>
<nve-accordion-header>
<h3 nve-text="label medium">Capability</h3>
</nve-accordion-header>
<nve-accordion-content>
<div nve-layout="column gap:sm">
<nve-checkbox>
<label>Vision <span nve-text="body sm muted">(1)</span></label>
<input type="checkbox" data-filter-key="capability" value="Vision" />
</nve-checkbox>
<nve-checkbox>
<label>Language <span nve-text="body sm muted">(1)</span></label>
<input type="checkbox" data-filter-key="capability" value="Language" />
</nve-checkbox>
<nve-checkbox>
<label>Simulation <span nve-text="body sm muted">(1)</span></label>
<input type="checkbox" data-filter-key="capability" value="Simulation" />
</nve-checkbox>
</div>
</nve-accordion-content>
</nve-accordion>
</nve-accordion-group>
</nve-page-panel-content>
</nve-page-panel>
<main nve-layout="column gap:md pad:lg">
<div nve-layout="row gap:sm align:wrap align:space-between align:bottom">
<div nve-layout="column gap:xs">
<p id="filterable-browse-count" nve-text="body semibold" aria-live="polite">3 models</p>
<p id="filterable-browse-summary" nve-text="body sm muted">No filters applied</p>
</div>
<nve-select fit-content>
<label>Sort by</label>
<select id="filterable-browse-sort">
<option value="updated">Recently updated</option>
<option value="name">Name</option>
</select>
</nve-select>
</div>
<div id="filterable-browse-results" role="list" nve-layout="column gap:sm">
<nve-card role="listitem" container="flat" data-name="Sim Predict" data-status="ready" data-capability="simulation" data-updated="4">
<nve-card-content>
<div nve-layout="row gap:lg align:space-between">
<div nve-layout="row gap:sm align:vertical-center">
<nve-icon name="sparkles" size="lg" status="accent"></nve-icon>
<div nve-layout="column gap:xs">
<a href="#" nve-text="label medium">Sim Predict</a>
<span nve-text="body sm muted">Simulation</span>
</div>
</div>
<p nve-text="body sm">Generates world states for physical AI validation and planning.</p>
<nve-badge status="success">Ready</nve-badge>
</div>
</nve-card-content>
</nve-card>
<nve-card role="listitem" container="flat" data-name="Vision Inspect" data-status="ready" data-capability="vision" data-updated="3">
<nve-card-content>
<div nve-layout="row gap:lg align:space-between">
<div nve-layout="row gap:sm align:vertical-center">
<nve-icon name="eye" size="lg" status="accent"></nve-icon>
<div nve-layout="column gap:xs">
<a href="#" nve-text="label medium">Vision Inspect</a>
<span nve-text="body sm muted">Vision</span>
</div>
</div>
<p nve-text="body sm">Detects surface defects in high-throughput manufacturing images.</p>
<nve-badge status="success">Ready</nve-badge>
</div>
</nve-card-content>
</nve-card>
<nve-card role="listitem" container="flat" data-name="Document Reasoner" data-status="preview" data-capability="language" data-updated="2">
<nve-card-content>
<div nve-layout="row gap:lg align:space-between">
<div nve-layout="row gap:sm align:vertical-center">
<nve-icon name="document" size="lg" status="accent"></nve-icon>
<div nve-layout="column gap:xs">
<a href="#" nve-text="label medium">Document Reasoner</a>
<span nve-text="body sm muted">Language</span>
</div>
</div>
<p nve-text="body sm">Answers grounded questions across technical document collections.</p>
<nve-badge status="warning">Preview</nve-badge>
</div>
</nve-card-content>
</nve-card>
</div>
</main>
</nve-page>
<script type="module">
const root = document.querySelector("#filterable-browse-pattern");
if (root) {
const search = root.querySelector("#filterable-browse-search");
const sort = root.querySelector("#filterable-browse-sort");
const count = root.querySelector("#filterable-browse-count");
const summary = root.querySelector("#filterable-browse-summary");
const results = root.querySelector("#filterable-browse-results");
const cards = [...root.querySelectorAll("[data-name]")];
const filters = [...root.querySelectorAll("[data-filter-key]")];
const update = () => {
const query = search.value.trim().toLowerCase();
const active = filters.filter((filter) => filter.checked);
const valuesByKey = new Map();
active.forEach((filter) => {
const values = valuesByKey.get(filter.dataset.filterKey) ?? [];
values.push(filter.value.toLowerCase());
valuesByKey.set(filter.dataset.filterKey, values);
});
let visible = 0;
cards.forEach((card) => {
const matchesQuery = !query || card.textContent.toLowerCase().includes(query);
const matchesFilters = [...valuesByKey].every(([key, values]) => values.includes(card.dataset[key]));
card.hidden = !(matchesQuery && matchesFilters);
if (!card.hidden) visible += 1;
});
const orderedCards = [...cards].sort((left, right) => {
if (sort.value === "name") return left.dataset.name.localeCompare(right.dataset.name);
return Number(right.dataset.updated) - Number(left.dataset.updated);
});
orderedCards.forEach((card) => results.append(card));
count.textContent = visible + (visible === 1 ? " model" : " models");
const labels = active.map((filter) => filter.value);
summary.textContent = labels.length ? "Active filters: " + labels.join(", ") : "No filters applied";
};
root.addEventListener("input", update);
root.addEventListener("change", update);
}
</script>Model Registry
Model catalog
Find a deployable model by capability, lifecycle status, and owner.
Status
Capability
3 models
No filters applied
Document Reasoner Language
Answers grounded questions across technical document collections.
Tree-Scoped Browse
Persistent hierarchy in a page navigation panel that scopes the adjacent collection. Use when people need to move among nested domains while retaining location context and direct access to nearby scopes.
<nve-page id="tree-scoped-browse-pattern">
<nve-page-header slot="header">
<nve-logo slot="prefix" size="sm" color="brand-green">NV</nve-logo>
<h2 slot="prefix" nve-text="heading">Asset Library</h2>
</nve-page-header>
<nve-page-panel slot="subheader">
<nve-page-panel-content>
<div nve-layout="row gap:md align:wrap align:space-between align:vertical-center">
<div nve-layout="column gap:xs">
<h1 id="tree-scoped-browse-page-title" nve-text="heading lg">Asset catalog</h1>
<p nve-text="body sm muted">Browse records within a persistent collection hierarchy.</p>
</div>
<nve-button><nve-icon name="add"></nve-icon>Add asset</nve-button>
</div>
</nve-page-panel-content>
</nve-page-panel>
<nve-page-panel slot="left" size="sm" aria-label="Asset collection navigation">
<nve-page-panel-content>
<section nve-layout="column gap:md">
<nve-tree id="tree-scoped-browse-tree" behavior-expand behavior-select selectable="single">
<nve-tree-node data-scope="all" data-label="All assets" selected expanded>
All assets
<nve-tree-node data-scope="vision" data-label="Vision assets" expanded>
Vision
<nve-tree-node data-scope="cameras" data-label="Camera assets">Cameras</nve-tree-node>
<nve-tree-node data-scope="lidar" data-label="LiDAR assets">LiDAR</nve-tree-node>
</nve-tree-node>
<nve-tree-node data-scope="language" data-label="Language assets" expanded>
Language
<nve-tree-node data-scope="documents" data-label="Document assets">Documents</nve-tree-node>
<nve-tree-node data-scope="assistants" data-label="Assistant assets">Assistants</nve-tree-node>
</nve-tree-node>
</nve-tree-node>
</nve-tree>
</section>
</nve-page-panel-content>
</nve-page-panel>
<main nve-layout="column gap:md pad:lg">
<header nve-layout="row gap:sm align:space-between align:bottom">
<div nve-layout="column gap:xs">
<h2 id="tree-scoped-browse-title" nve-text="heading md">All assets</h2>
<p id="tree-scoped-browse-count" nve-text="body sm muted" aria-live="polite">5 records</p>
</div>
</header>
<div id="tree-scoped-browse-results" role="list" nve-layout="column gap:sm">
<nve-card role="listitem" container="flat" data-scopes="all vision cameras">
<nve-card-content>
<div nve-layout="row gap:md align:space-between align:vertical-center">
<div nve-layout="column gap:xs">
<a href="#" nve-text="label medium">Loading dock camera set</a>
<span nve-text="body sm muted">Cameras ยท 12,480 frames</span>
</div>
<nve-badge status="success">Ready</nve-badge>
</div>
</nve-card-content>
</nve-card>
<nve-card role="listitem" container="flat" data-scopes="all vision cameras">
<nve-card-content>
<div nve-layout="row gap:md align:space-between align:vertical-center">
<div nve-layout="column gap:xs">
<a href="#" nve-text="label medium">Aisle obstruction images</a>
<span nve-text="body sm muted">Cameras ยท 8,220 frames</span>
</div>
<nve-badge status="pending">Processing</nve-badge>
</div>
</nve-card-content>
</nve-card>
<nve-card role="listitem" container="flat" data-scopes="all vision lidar">
<nve-card-content>
<div nve-layout="row gap:md align:space-between align:vertical-center">
<div nve-layout="column gap:xs">
<a href="#" nve-text="label medium">Warehouse point clouds</a>
<span nve-text="body sm muted">LiDAR ยท 3,160 captures</span>
</div>
<nve-badge status="success">Ready</nve-badge>
</div>
</nve-card-content>
</nve-card>
<nve-card role="listitem" container="flat" data-scopes="all language documents">
<nve-card-content>
<div nve-layout="row gap:md align:space-between align:vertical-center">
<div nve-layout="column gap:xs">
<a href="#" nve-text="label medium">Service manuals</a>
<span nve-text="body sm muted">Documents ยท 246 files</span>
</div>
<nve-badge status="success">Indexed</nve-badge>
</div>
</nve-card-content>
</nve-card>
<nve-card role="listitem" container="flat" data-scopes="all language assistants">
<nve-card-content>
<div nve-layout="row gap:md align:space-between align:vertical-center">
<div nve-layout="column gap:xs">
<a href="#" nve-text="label medium">Operator assistant prompts</a>
<span nve-text="body sm muted">Assistants ยท 86 conversations</span>
</div>
<nve-badge status="warning">Review</nve-badge>
</div>
</nve-card-content>
</nve-card>
</div>
</main>
</nve-page>
<script type="module">
const root = document.querySelector("#tree-scoped-browse-pattern");
if (root) {
const tree = root.querySelector("#tree-scoped-browse-tree");
const title = root.querySelector("#tree-scoped-browse-title");
const count = root.querySelector("#tree-scoped-browse-count");
const cards = [...root.querySelectorAll("[data-scopes]")];
tree.addEventListener("select", (event) => {
const node = event.detail;
const scope = node.dataset.scope;
if (!scope) return;
let visible = 0;
cards.forEach((card) => {
card.hidden = !card.dataset.scopes.split(" ").includes(scope);
if (!card.hidden) visible += 1;
});
title.textContent = node.dataset.label;
count.textContent = visible + (visible === 1 ? " record" : " records");
});
}
</script>Asset Library
Asset catalog
Browse records within a persistent collection hierarchy.
All assets
5 records
Loading dock camera set Cameras ยท 12,480 frames
Aisle obstruction images Cameras ยท 8,220 frames
Warehouse point clouds LiDAR ยท 3,160 captures
Service manuals Documents ยท 246 files
Operator assistant prompts Assistants ยท 86 conversations
Editable Grid
Directly editable data grid with text, select, checkbox, and date controls visible in every row. Use for compact settings tables where frequent edits should not require a separate edit mode.
<nve-page id="editable-grid-page">
<nve-page-header slot="header">
<nve-logo slot="prefix" size="sm" color="brand-green">NV</nve-logo>
<h2 slot="prefix" nve-text="heading">Deployment Manager</h2>
</nve-page-header>
<nve-page-panel slot="subheader">
<nve-page-panel-content>
<div nve-layout="column gap:xs">
<h1 id="editable-grid-title" nve-text="heading lg">Deployment settings</h1>
<p nve-text="body sm muted">Edit values directly in the grid without entering a separate edit mode.</p>
</div>
</nve-page-panel-content>
</nve-page-panel>
<main nve-layout="column gap:md pad:lg">
<nve-grid id="editable-grid-pattern" container="flat" stripe>
<nve-grid-header>
<nve-grid-column>Name</nve-grid-column>
<nve-grid-column>Environment</nve-grid-column>
<nve-grid-column>Review date</nve-grid-column>
<nve-grid-column>Auto deploy</nve-grid-column>
</nve-grid-header>
<nve-grid-row>
<nve-grid-cell>
<nve-input container="flat">
<input type="text" value="Batch evaluator" required aria-label="Batch evaluator name" />
</nve-input>
</nve-grid-cell>
<nve-grid-cell>
<nve-select container="flat">
<select aria-label="Batch evaluator environment">
<option>Development</option>
<option selected>Staging</option>
<option>Production</option>
</select>
</nve-select>
</nve-grid-cell>
<nve-grid-cell>
<nve-date container="flat">
<input type="date" value="2026-11-03" aria-label="Batch evaluator review date" />
</nve-date>
</nve-grid-cell>
<nve-grid-cell>
<nve-checkbox>
<label>Enable</label>
<input type="checkbox" aria-label="Enable batch evaluator auto deploy" />
</nve-checkbox>
</nve-grid-cell>
</nve-grid-row>
<nve-grid-row>
<nve-grid-cell>
<nve-input container="flat">
<input type="text" value="Safety monitor" required aria-label="Safety monitor name" />
</nve-input>
</nve-grid-cell>
<nve-grid-cell>
<nve-select container="flat">
<select aria-label="Safety monitor environment">
<option selected>Development</option>
<option>Staging</option>
<option>Production</option>
</select>
</nve-select>
</nve-grid-cell>
<nve-grid-cell>
<nve-date container="flat">
<input type="date" value="2026-12-12" aria-label="Safety monitor review date" />
</nve-date>
</nve-grid-cell>
<nve-grid-cell>
<nve-checkbox>
<label>Enable</label>
<input type="checkbox" checked aria-label="Enable safety monitor auto deploy" />
</nve-checkbox>
</nve-grid-cell>
</nve-grid-row>
<nve-grid-row>
<nve-grid-cell>
<nve-input container="flat">
<input type="text" value="Edge inference" required aria-label="Edge inference name" />
</nve-input>
</nve-grid-cell>
<nve-grid-cell>
<nve-select container="flat">
<select aria-label="Edge inference environment">
<option>Development</option>
<option>Staging</option>
<option selected>Production</option>
</select>
</nve-select>
</nve-grid-cell>
<nve-grid-cell>
<nve-date container="flat">
<input type="date" value="2026-10-15" aria-label="Edge inference review date" />
</nve-date>
</nve-grid-cell>
<nve-grid-cell>
<nve-checkbox>
<label>Enable</label>
<input type="checkbox" checked aria-label="Enable edge inference auto deploy" />
</nve-checkbox>
</nve-grid-cell>
</nve-grid-row>
</nve-grid>
</main>
</nve-page>Deployment Manager
Deployment settings
Edit values directly in the grid without entering a separate edit mode.
Content Row
Use for browsable content lists with a horizontal card showing thumbnail, title, description, and icon button actions.
<nve-card role="listitem" container="flat">
<nve-card-content>
<div nve-layout="grid align:vertical-center align:space-between gap:md">
<div nve-layout="span:4 row gap:md align:vertical-center">
<div aria-hidden="true" nve-layout="row align:center" style="width: 100px; aspect-ratio: 3 / 2">
<nve-icon name="image" size="lg"></nve-icon>
</div>
<div nve-layout="column gap:sm">
<h2 nve-text="label medium">Activity Dashboard</h2>
<p nve-text="body sm muted">Last saved: Oct 19, 21 by Camru</p>
</div>
</div>
<p nve-text="body sm" nve-layout="span:5">A dashboard displaying current project activity grouped by User, Host or IP</p>
<div nve-layout="span:3 row gap:sm align:right">
<div nve-layout="row gap:xs">
<nve-icon-button icon-name="eye"></nve-icon-button>
<nve-icon-button icon-name="copy"></nve-icon-button>
<nve-icon-button icon-name="delete"></nve-icon-button>
</div>
<nve-divider orientation="vertical"></nve-divider>
<nve-button>Add Panel</nve-button>
</div>
</div>
</nve-card-content>
</nve-card>Activity Dashboard
Last saved: Oct 19, 21 by Camru
A dashboard displaying current project activity grouped by User, Host or IP