Theming
CSS token scopes and states
The table theme contract is CSS custom properties. Put tokens on an ancestor of the table and let inheritance flow through the core table, companion controls, and optional render-metrics UI.
Recommended Shape
Use NatTableSurface when you want the shared controller scope and companion-control wiring. The core table is visually headless by default; import the opt-in stock theme (see Opt-in Stock Theme) or scope inherited --nat-table-* custom properties on a wrapper around the table, controls, and optional render-metrics UI.
<section class="orders-table-theme">
<nat-table-surface>
<nat-table-pagination [pageSizeOptions]="[25, 50, 100]" />
<nat-table #table [data]="rows()" [columns]="columns" accessibleName="Orders" />
<nat-table-scroll-control />
<nat-table-column-visibility />
<nat-render-metrics-panel [controller]="table" [store]="renderMetricsStore" />
</nat-table-surface>
</section>
Start with the semantic table palette. The table, bundled controls, and render-metrics components inherit these values.
.orders-table-theme {
--nat-table-color-text: #111827;
--nat-table-color-text-muted: #4b5563;
--nat-table-color-accent: #2563eb;
--nat-table-color-success: #166534;
--nat-table-color-warning: #a16207;
--nat-table-color-danger: #b91c1c;
--nat-table-color-surface: #ffffff;
--nat-table-color-surface-elevated: #ffffff;
--nat-table-color-surface-sticky: #f9fafb;
color-scheme: light;
}
[data-theme='dark'] .orders-table-theme {
--nat-table-color-text: #f9fafb;
--nat-table-color-text-muted: #cbd5e1;
--nat-table-color-accent: #60a5fa;
--nat-table-color-success: #86efac;
--nat-table-color-warning: #fde68a;
--nat-table-color-danger: #fca5a5;
--nat-table-color-surface: rgb(15 23 42 / 92%);
--nat-table-color-surface-elevated: #111827;
--nat-table-color-surface-sticky: #1f2937;
color-scheme: dark;
}
Use direct --nat-table-* overrides when the table needs a table-specific decision that should not affect the rest of the app.
.orders-table-theme {
--nat-table-header-background: #eef2ff;
--nat-table-row-background-hover: #f8fafc;
--nat-table-focus-ring-color: #1d4ed8;
--nat-table-radius-chip: 0.75rem;
}
Theme Scope
Choose the narrowest scope that matches the product decision.
.risk-table {
--nat-table-color-accent: #7c3aed;
--nat-table-header-background: #f5f3ff;
--nat-table-pinned-divider-color: #c4b5fd;
}
For app-wide themes, put table tokens on the app root or theme attribute.
:root {
--nat-table-color-text: #111827;
--nat-table-color-text-muted: #6b7280;
--nat-table-color-accent: #2563eb;
--nat-table-color-surface: #ffffff;
--nat-table-color-surface-elevated: #ffffff;
--nat-table-color-surface-sticky: #f9fafb;
--nat-table-color-success: #15803d;
--nat-table-color-warning: #a16207;
--nat-table-color-danger: #b91c1c;
color-scheme: light;
}
[data-theme='dark'] {
--nat-table-color-text: #f9fafb;
--nat-table-color-text-muted: #9ca3af;
--nat-table-color-accent: #60a5fa;
--nat-table-color-surface: #111827;
--nat-table-color-surface-elevated: #1f2937;
--nat-table-color-surface-sticky: #374151;
--nat-table-color-success: #86efac;
--nat-table-color-warning: #fde68a;
--nat-table-color-danger: #fca5a5;
color-scheme: dark;
}
If controls and the table live in different surfaces, put product tokens on their shared ancestor so both surfaces derive the same theme.
The live example below scopes --nat-table-* tokens on NatTableSurface, with a matching [data-theme='dark'] override. It intentionally avoids private component classes and ::ng-deep, so the same CSS can live in a consumer app stylesheet.
Core Table Tokens
These are the most common stable ng-advanced-table tokens to override directly.
| Token | Purpose |
|---|---|
--nat-table-color-text |
Base table text color |
--nat-table-color-border |
Shared surface and control border |
--nat-table-color-divider |
Shared row and cell divider |
--nat-table-font-family |
Table font family |
--nat-table-region-background |
Scrollable table region background |
--nat-table-region-border-color |
Scrollable table region border |
--nat-table-region-border-width |
Scrollable table region border width |
--nat-table-radius-region |
Scrollable table region radius |
--nat-table-header-background |
Header background |
--nat-table-header-color |
Header text color |
--nat-table-font-weight-header |
Header text font weight |
--nat-table-header-border-color |
Header divider |
--nat-table-header-border-width |
Header divider width |
--nat-table-row-background |
Default body row background |
--nat-table-row-background-hover |
Hovered row background |
--nat-table-row-background-focus |
Focus-within row background |
--nat-table-pinned-background |
Pinned cell background |
--nat-table-pinned-header-background |
Pinned header cell background (falls back to --nat-table-pinned-background) |
--nat-table-pinned-divider-color |
Pinned edge divider |
--nat-table-pinned-divider-shadow-color |
Shared opt-in shadow color for both pinned-zone boundaries |
--nat-table-pinned-edge-shadow-size |
Shared size of the pinned-zone fade; the library mirrors its direction per zone |
--nat-table-cell-border-color |
Body cell divider |
--nat-table-cell-border-width |
Body cell divider width |
--nat-table-cell-color-positive |
Positive semantic cell tone |
--nat-table-cell-color-negative |
Negative semantic cell tone |
--nat-table-cell-color-warning |
Warning semantic cell tone |
--nat-table-cell-color-neutral |
Neutral semantic cell tone |
--nat-table-empty-state-color |
Empty, loading, and error row text |
--nat-table-focus-ring-color |
Keyboard focus indicator |
--nat-table-focus-ring-width |
Keyboard focus indicator width |
--nat-table-space-cell-y |
Cell block padding |
--nat-table-space-cell-x |
Cell inline padding (shared base) |
--nat-table-space-header-cell-x |
Header cell inline padding (falls back to --nat-table-space-cell-x) |
--nat-table-space-data-cell-x |
Data cell inline padding (falls back to --nat-table-space-cell-x) |
--nat-table-sub-header-background |
Sub-header (group) row background (table and list) |
--nat-table-sub-header-color |
Sub-header (group) row text color (table and list) |
--nat-table-space-sub-header |
Sub-header (group) row padding (table and list) |
--nat-table-font-weight-sub-header |
Sub-header (group) row font weight (table and list) |
Set the border-width tokens to 0 when a design needs to remove the outer table boundary or internal dividers.
List Renderer Tokens (spike)
The nat-list spike renderer lays every item out as a CSS grid whose field areas are named by column id, so consumers can position each column's field freely. These tokens are spike API and may change or be removed with the NatList spike.
| Token | Purpose |
|---|---|
--nat-list-gap |
Gap between list items |
--nat-list-item-areas |
grid-template-areas for one item; area names are column ids (default stacks each visible column) |
--nat-list-item-columns |
grid-template-columns for one item |
--nat-list-item-gap |
Gap between fields inside one item |
--nat-list-item-padding |
Item padding |
--nat-list-item-background |
Item background; transparent by default, so items inherit the page background |
--nat-list-item-background-selected |
Item background while the row is selected (data-selected="true") |
--nat-list-item-border-width |
Item border width; accepts 1-4 value shorthand (e.g. 1px 0 for divider-only items) |
--nat-list-item-border-color |
Item border color; a currentcolor mix by default, so it follows the page text color |
--nat-list-item-radius |
Item corner radius |
--nat-list-field-gap |
Gap between one field's label and value |
--nat-list-field-align |
align-items for one field (defaults to baseline) |
--nat-list-field-flex-direction |
flex-direction for one field (defaults to row) |
--nat-list-field-justify |
justify-content for one field (defaults to flex-start) |
--nat-list-label-font-weight |
Field label weight |
--nat-list-label-font-size |
Field label font size |
--nat-list-label-color |
Field label color (defaults to currentColor) |
--nat-list-space-sub-header |
Sub-header row padding for lists |
--nat-list-sub-header-background |
Sub-header row background for lists |
--nat-list-sub-header-color |
Sub-header row text color for lists |
--nat-list-font-weight-sub-header |
Sub-header row font weight for lists |
--nat-list-sub-header-border |
Sub-header row border style for lists |
--nat-list-sub-header-border-width |
Sub-header row border width for lists |
When overriding --nat-list-item-areas, name every visible column in the template (or hide the rest via column visibility) — a field whose column id is missing from the areas template falls back to implicit grid placement.
The loading, empty, and error items share one base shape, so the tokens below restyle all three at once; each state then has its own accent token for the indicator (and, for the error state, the message color).
| Token | Purpose |
|---|---|
--nat-list-state-padding |
Padding for every state item |
--nat-list-state-gap |
Gap between the state indicator and its message |
--nat-list-state-justify |
justify-content for the state item (e.g. center) |
--nat-list-state-min-height |
Minimum height, useful to stop layout jumping between states |
--nat-list-state-color |
Shared state message color |
--nat-list-state-background |
Shared state background |
--nat-list-state-border-color |
Shared state border color |
--nat-list-state-border-style |
Shared state border style (defaults to dashed) |
--nat-list-state-radius |
Shared state corner radius |
--nat-list-state-indicator-size |
Indicator diameter |
--nat-list-loading-accent |
Loading indicator color (falls back to --nat-table-color-accent) |
--nat-list-empty-accent |
Empty indicator outline color (falls back to --nat-table-color-text-muted) |
--nat-list-error-accent |
Error indicator and message color (falls back to --nat-table-color-danger) |
Each state item also carries a data-state attribute (loading, empty, or error) for consumer styling hooks. The loading indicator animates and honors prefers-reduced-motion: reduce.
UI Control Tokens
ng-advanced-table/components controls consume the same theme. Common groups include:
| Group | Common tokens |
|---|---|
| Surface | --nat-table-card-background, --nat-table-card-border-color, --nat-table-card-shadow, --nat-table-radius-card, --nat-table-space-card, --nat-table-space-card-list (padding when a list renderer is projected; defaults to 0) |
| Controls | --nat-table-color-text-muted, --nat-table-font-size-label, --nat-table-space-control-block-gap |
| Chips | --nat-table-chip-background, --nat-table-chip-background-active, --nat-table-chip-border-color, --nat-table-radius-chip |
| Pager | --nat-table-pager-background, --nat-table-pager-border-color, --nat-table-pager-color, --nat-table-pager-min-height |
| Header actions | --nat-table-sort-icon-color-active, --nat-table-sort-icon-color-idle, --nat-table-pin-color-pinned |
| Motion | --nat-table-transition-fast, --nat-table-transition-medium, --nat-table-disabled-opacity |
| Stacking | --nat-table-z-index-sticky-header, --nat-table-z-index-pinned-cell, --nat-table-z-index-drag-preview |
Reach for these direct tokens when a table control needs a local exception.
Scroll Control Tokens
NatTableScrollControl keeps its native range input and reads inherited tokens from the wrapper around the control and table. The component does not expose private selectors as theme API. The stock buttons draw as 36 × 36 px squares with a 24 px arrow and no inline padding, while an invisible pseudo-element extends each button's pointer target to --nat-table-scroll-button-target-size (44 px, the WCAG 2.5.5 AAA size), so the focus ring hugs the compact box without shrinking the tap area.
| Token | Purpose |
|---|---|
--nat-table-scroll-control-gap |
Gap between the previous button, range group, and next button |
--nat-table-scroll-button-min-height |
Existing fallback for both button axes when the logical sizing tokens are unset |
--nat-table-scroll-button-min-inline-size |
Minimum inline size of each button |
--nat-table-scroll-button-min-block-size |
Minimum block size of each button |
--nat-table-scroll-button-target-size |
Pointer target each button axis is extended to (never smaller than the visual box) |
--nat-table-scroll-button-padding-x |
Button inline padding |
--nat-table-scroll-button-color |
Button and arrow color |
--nat-table-scroll-button-background |
Button background |
--nat-table-scroll-button-background-hover |
Enabled button background on hover |
--nat-table-scroll-button-border-color |
Button border color |
--nat-table-scroll-button-shadow-hover |
Enabled button shadow on hover |
--nat-table-scroll-button-disabled-opacity |
Disabled button opacity |
--nat-table-scroll-icon-size |
Arrow icon inline and block size |
--nat-table-scroll-range-gap |
Gap between the position copy and range input |
--nat-table-font-size-scroll-position |
Position-copy font size |
--nat-table-scroll-position-min-inline-size |
Minimum inline size of the position-copy column |
--nat-table-scroll-position-color |
Position-copy color |
--nat-table-scroll-range-min-inline-size |
Minimum inline size of the native range input |
--nat-table-scroll-range-accent |
Existing native accent and fallback for both range color tokens |
--nat-table-scroll-range-track-block-size |
WebKit and Firefox track thickness |
--nat-table-scroll-range-track-color |
Uniform WebKit and Firefox track color; falls back to --nat-table-scroll-range-accent |
--nat-table-scroll-range-track-border |
WebKit and Firefox track border |
--nat-table-scroll-range-track-radius |
WebKit and Firefox track corner radius |
--nat-table-scroll-range-thumb-inline-size |
WebKit and Firefox thumb inline size |
--nat-table-scroll-range-thumb-block-size |
WebKit and Firefox thumb block size |
--nat-table-scroll-range-thumb-color |
WebKit and Firefox thumb color; falls back to --nat-table-scroll-range-accent |
--nat-table-scroll-range-thumb-border |
WebKit and Firefox thumb border |
--nat-table-scroll-range-thumb-radius |
WebKit and Firefox thumb corner radius |
--nat-table-scroll-range-disabled-opacity |
Disabled range opacity |
--nat-table-radius-chip |
Button corner radius shared with other controls |
--nat-table-hover-lift |
Enabled button hover transform |
--nat-table-transition-medium |
Button color, background, border, shadow, and transform transition |
--nat-table-focus-ring-color |
Keyboard focus-ring color for buttons and range |
--nat-table-focus-ring-width |
Keyboard focus-ring width for buttons and range |
--nat-table-focus-ring-offset |
Keyboard focus-ring offset for buttons and range |
Scope product-specific overrides on a wrapper. Every value below crosses Angular's component boundary through normal custom-property inheritance.
.orders-scroll-theme {
--nat-table-scroll-control-gap: 0.75rem;
--nat-table-scroll-button-min-inline-size: 2.75rem;
--nat-table-scroll-button-min-block-size: 2.75rem;
--nat-table-scroll-button-padding-x: 0.75rem;
--nat-table-scroll-button-color: #12372f;
--nat-table-scroll-button-background: #d8f3e8;
--nat-table-scroll-button-background-hover: #bce7d9;
--nat-table-scroll-button-border-color: #4f8f7c;
--nat-table-scroll-icon-size: 1.2rem;
--nat-table-font-size-scroll-position: 0.8rem;
--nat-table-scroll-position-min-inline-size: 6ch;
--nat-table-scroll-position-color: #345c51;
--nat-table-scroll-range-min-inline-size: 10rem;
--nat-table-scroll-range-track-block-size: 0.5rem;
--nat-table-scroll-range-track-color: #9bcbbb;
--nat-table-scroll-range-track-border: 1px solid #4f8f7c;
--nat-table-scroll-range-track-radius: 0;
--nat-table-scroll-range-thumb-inline-size: 1.35rem;
--nat-table-scroll-range-thumb-block-size: 1.35rem;
--nat-table-scroll-range-thumb-color: #0f766e;
--nat-table-scroll-range-thumb-border: 2px solid #ffffff;
--nat-table-scroll-range-thumb-radius: 0.25rem;
--nat-table-focus-ring-color: #0f766e;
}
The track is intentionally uniform rather than a JavaScript-maintained progress fill. In forced-colors mode, track, thumb, and focus styling switch to system colors so the native keyboard control remains visible.
Render-metrics widgets intentionally do not expose their own component-specific tokens. They inherit the shared semantic palette (--nat-table-color-*) so they remain readable in light and dark themes, while their compact KPI/chip styling stays internal.
Opt-in Stock Theme
ng-advanced-table core is headless by default: with no theme applied, the table and companion controls render with conservative system-color fallbacks and inherit the page's colors. Neither the core table nor NatTableSurface ships the stock look as a built-in default.
To get the polished stock look, import the opt-in stylesheet once, for example in your app's global styles or main.ts:
import 'ng-advanced-table/components/theme.css';
The stock theme is light/dark responsive: its palette uses light-dark() and the theme sets color-scheme: light dark on :root, so it follows the operating-system preference out of the box. To pin or toggle the mode, set color-scheme (and optionally a [data-theme] attribute) on a wrapper. The opt-in theme is intentionally outside the Safari 16.5 baseline for core table behavior; Safari 16.5 consumers can theme through their own --nat-table-* tokens instead of importing theme.css.
Token precedence is unchanged: a --nat-table-* token set on any ancestor wrapper (or on the surface element itself) still wins over the opt-in theme, and derived stock values (borders, dividers, mixed colors) recompute from your overridden palette tokens. If you inspect computed styles you may see internal --sys-nat-table-* bridge variables — they are implementation detail; never set them, set the matching --nat-table-* token instead.
Product UI should scope tokens on a wrapper or NatTableSurface ancestor so all companion controls inherit the same theme, whether or not the opt-in stylesheet is imported.
The tables below list the main stock values and resolved core defaults. Use them as a reference if you want to replicate the stock look, override individual tokens on top of it, or build your own theme from scratch without importing theme.css at all.
Palette And Core
The palette is light/dark responsive via light-dark(<light>, <dark>).
| Token | Stock value or resolved default |
|---|---|
--nat-table-font-family |
'Inter', -apple-system, blinkmacsystemfont, 'Segoe UI', roboto, helvetica, arial, sans-serif |
--nat-table-color-text |
light-dark(#0f1419, #e6eaef) |
--nat-table-color-text-muted |
light-dark(#5b6672, #9aa4b1) |
--nat-table-color-accent |
light-dark(#1f6feb, #4f8bff) |
--nat-table-color-success |
light-dark(#127a3b, #3dd68c) |
--nat-table-color-warning |
light-dark(#8f5f00, #e5b452) |
--nat-table-color-danger |
light-dark(#b42318, #f15b5b) |
--nat-table-color-surface |
light-dark(#fff, #14171c) |
--nat-table-color-surface-elevated |
light-dark(#fff, #14171c) |
--nat-table-color-surface-sticky |
light-dark(#f4f5f7, #1a1e24) |
--nat-table-color-border |
light-dark(#e4e7eb, #262b33) |
--nat-table-color-divider |
light-dark(#e4e7eb, #262b33) |
--nat-table-region-background |
var(--nat-table-color-surface) |
--nat-table-header-background |
var(--nat-table-color-surface-sticky) |
--nat-table-header-color |
var(--nat-table-color-text-muted) |
--nat-table-cell-border-color |
var(--nat-table-color-divider) |
--nat-table-cell-color-positive |
var(--nat-table-color-success) |
--nat-table-cell-color-negative |
var(--nat-table-color-danger) |
--nat-table-cell-color-warning |
var(--nat-table-color-warning) |
--nat-table-cell-color-neutral |
var(--nat-table-color-text-muted) |
--nat-table-empty-state-color |
var(--nat-table-color-text-muted) |
--nat-table-loading-state-color |
var(--nat-table-empty-state-color) |
--nat-table-error-state-color |
var(--nat-table-cell-color-negative) |
--nat-table-focus-ring-color |
var(--nat-table-color-accent) |
Controls
| Token | Stock value or resolved default |
|---|---|
--nat-table-radius-card |
12px |
--nat-table-radius-region |
8px |
--nat-table-radius-input |
6px |
--nat-table-radius-chip |
6px |
--nat-table-space-card |
0 |
--nat-table-space-card-compact |
0 |
--nat-table-space-control-block-gap |
12px |
--nat-table-space-chip-row-gap |
10px |
--nat-table-chip-background |
var(--nat-table-color-surface) |
--nat-table-chip-background-active |
color-mix(in srgb, var(--nat-table-color-accent) 12%, var(--nat-table-color-surface)) |
--nat-table-chip-border-color |
var(--nat-table-color-border) |
--nat-table-pager-background |
var(--nat-table-color-surface) |
--nat-table-pager-border-color |
var(--nat-table-color-border) |
Layout And Stacking
| Token | Stock value or resolved default |
|---|---|
--nat-table-region-overflow-x |
auto |
--nat-table-region-overflow-y |
auto |
--nat-table-region-overscroll-behavior |
none |
--nat-table-region-overscroll-behavior-x |
none |
--nat-table-region-overscroll-behavior-y |
auto |
--nat-table-max-height |
inherit |
--nat-table-min-height |
auto |
--nat-table-state-min-height |
var(--nat-table-min-height, 0) |
--nat-table-height |
inherit |
--nat-table-sticky-top |
0 |
--nat-table-z-index-sticky-header |
4 |
--nat-table-z-index-pinned-cell |
5 |
--nat-table-z-index-pinned-header |
6 |
--nat-table-z-index-focus-cell |
7 (focused pinned cells only) |
--nat-table-z-index-resize-handle |
8 |
--nat-table-z-index-resize-guide |
9 |
--nat-table-z-index-drag-preview |
12 |
Core-Only Tables
Pinned body and header cells always paint above unpinned cells, including when an unpinned cell has keyboard focus beneath a pin zone. The focus-cell layer is reserved for a focused pinned cell so its inset indicator remains visible without overtaking resize handles, resize guides, or drag previews. Pinned focus and hover tokens are composited as overlays over --nat-table-pinned-background; translucent consumer colors therefore keep an opaque pinned base instead of exposing scrolled content.
The core table is unstyled by default whether or not you use NatTableSurface — with or without the surface, it renders with system-color fallbacks unless you import the opt-in theme or provide tokens yourself. For a polished core-only table, import ng-advanced-table/components/theme.css or provide the core tokens yourself.
<section class="plain-table">
<nat-table [data]="rows()" [columns]="columns" accessibleName="Orders" />
</section>
.plain-table {
--nat-table-color-text: #111827;
--nat-table-region-background: #ffffff;
--nat-table-region-border-color: #e5e7eb;
--nat-table-header-background: #f9fafb;
--nat-table-header-color: #4b5563;
--nat-table-cell-border-color: #e5e7eb;
--nat-table-row-background-hover: #f3f4f6;
--nat-table-focus-ring-color: #2563eb;
}
Semantic Cell Tones
Use meta.cellTone for semantic coloring and keep the meaning available in text or context.
{
accessorKey: 'changePercent',
header: 'Chg %',
meta: {
label: 'Change percent',
align: 'end',
cellTone: (context) => {
const value = context.getValue<number>();
if (value > 0) return 'positive';
if (value < 0) return 'negative';
return 'neutral';
},
},
cell: (context) => `${context.getValue<number>().toFixed(2)}%`,
}
Then theme the tone tokens.
.orders-table-theme {
--nat-table-cell-color-positive: #166534;
--nat-table-cell-color-negative: #b91c1c;
--nat-table-cell-color-warning: #a16207;
--nat-table-cell-color-neutral: #475569;
}
Do not encode business meaning only through color. Include signs, labels, icons with text alternatives, or nearby text that makes the state clear.
Theming Checklist
- Put tokens on a wrapper, feature shell, or app theme root.
- Prefer
--nat-table-*tokens for new themes. - Keep table, companion controls, and render metrics under the same theme scope.
- Use
color-schemefor light and dark scopes. - Verify focus-visible states after changing focus, border, header, chip, pager, or semantic colors.
- Keep text, controls, focus indicators, pinned dividers, and semantic tones at WCAG AA contrast.
- Do not target private component classes, generated DOM structure, Angular internals, or
::ng-deep.
Theme example
A scoped consumer theme with a visibly different table treatment and matching token CSS.
<nat-table-surface [enableSorting]="true" [initialState]="initialState" class="ledger-surface">
<nat-table [columns]="columns" [data]="rows" accessibleName="Themed orders table" />
<nat-table-scroll-control />
</nat-table-surface>
<nat-table-surface [initialState]="initialState" class="ledger-surface ledger-list-surface">
<nat-list [columns]="columns" [data]="rows" accessibleName="Themed orders list" />
</nat-table-surface>import { NatList, NatTable } from 'ng-advanced-table';
import { NatTableScrollControl, NatTableSurface, withNatTableHeaderActions } from 'ng-advanced-table/components';
readonly rows = generateMockOrderRows(5);
readonly initialState = {
sorting: [{ id: 'total', desc: true }],
} satisfies Partial<NatTableUserState>;
readonly columns = withNatTableHeaderActions(baseColumns, {
enableColumnPinActions: false,
sortIndicator: ({ sortState }) => (sortState === 'asc' ? '↑' : sortState === 'desc' ? '↓' : '↕'),
});.ledger-surface {
--nat-table-color-text: #26312f;
--nat-table-color-text-muted: #667570;
--nat-table-color-accent: #0f766e;
--nat-table-color-success: #0f766e;
--nat-table-color-warning: #9a5b13;
--nat-table-card-background: #edf3f1;
--nat-table-card-border-color: #cbd8d4;
--nat-table-card-shadow: 0 18px 42px rgb(31 49 45 / 12%);
--nat-table-space-card: 18px;
--nat-table-radius-card: 6px;
--nat-table-font-family: 'Aptos', 'Segoe UI', system-ui, sans-serif;
--nat-table-font-size-header: 0.82rem;
--nat-table-letter-spacing-header: 0;
--nat-table-text-transform-header: none;
--nat-table-line-height-cell: 1.5;
--nat-table-font-weight-row-header: 700;
--nat-table-region-background: #fbfcfb;
--nat-table-region-border-color: #cbd8d4;
--nat-table-region-border-width: 1px;
--nat-table-header-background: #26312f;
--nat-table-header-color: #f8fbfa;
--nat-table-header-border-color: #26312f;
--nat-table-row-background: #fbfcfb;
--nat-table-row-background-hover: #eef6f3;
--nat-table-row-background-focus: #e4efec;
--nat-table-cell-border-color: #dde7e3;
--nat-table-cell-color-positive: #0f766e;
--nat-table-cell-color-warning: #9a5b13;
--nat-table-cell-color-neutral: #667570;
--nat-table-focus-ring-color: #0f766e;
--nat-table-sort-icon-color-active: #f8fbfa;
--nat-table-sort-icon-color-idle: rgb(248 251 250 / 68%);
--nat-table-sort-icon-color-hover: #f8fbfa;
--nat-table-sort-button-color-sorted: #f8fbfa;
--nat-table-space-header-actions-gap: 8px;
--nat-table-sort-icon-min-width: 1rem;
--nat-table-space-cell-y: 15px;
--nat-table-space-cell-x: 18px;
--nat-table-radius-region: 4px;
--nat-table-hover-lift: none;
--nat-table-focus-ring-width: 3px;
--nat-table-scroll-control-gap: 12px;
--nat-table-scroll-button-min-inline-size: 44px;
--nat-table-scroll-button-min-block-size: 44px;
--nat-table-scroll-button-padding-x: 12px;
--nat-table-scroll-button-color: #f8fbfa;
--nat-table-scroll-button-background: #0f766e;
--nat-table-scroll-button-background-hover: #115e59;
--nat-table-scroll-button-border-color: #0f766e;
--nat-table-scroll-button-disabled-opacity: 0.62;
--nat-table-scroll-icon-size: 1.2rem;
--nat-table-scroll-range-gap: 12px;
--nat-table-font-size-scroll-position: 0.78rem;
--nat-table-scroll-position-color: #46675e;
--nat-table-scroll-range-min-inline-size: 9rem;
--nat-table-scroll-range-track-block-size: 8px;
--nat-table-scroll-range-track-color: #acd8cb;
--nat-table-scroll-range-track-border: 1px solid #669b8c;
--nat-table-scroll-range-track-radius: 2px;
--nat-table-scroll-range-thumb-inline-size: 22px;
--nat-table-scroll-range-thumb-block-size: 22px;
--nat-table-scroll-range-thumb-color: #0f766e;
--nat-table-scroll-range-thumb-border: 3px solid #fbfcfb;
--nat-table-scroll-range-thumb-radius: 4px;
--nat-table-scroll-range-disabled-opacity: 0.62;
display: block;
color-scheme: light;
}
/* The list renderer follows the same ledger palette; the --nat-list-*
tokens lay each item out as named field areas (area names are column ids). */
.ledger-list-surface {
--nat-list-gap: 10px;
--nat-list-item-areas: 'id total' 'customer status';
--nat-list-item-columns: 1fr auto;
--nat-list-item-gap: 6px;
--nat-list-item-padding: 14px 16px;
--nat-list-item-background: #fbfcfb;
--nat-list-item-border-color: #cbd8d4;
--nat-list-item-radius: 6px;
}
[data-theme='dark'] .ledger-surface {
--nat-table-color-text: #dfe8e5;
--nat-table-color-text-muted: #9fb1ab;
--nat-table-color-accent: #5eead4;
--nat-table-color-success: #5eead4;
--nat-table-color-warning: #f8c572;
--nat-table-card-background: #111c1a;
--nat-table-card-border-color: #30413d;
--nat-table-card-shadow: 0 18px 44px rgb(3 10 9 / 46%);
--nat-table-region-background: #15211f;
--nat-table-region-border-color: #30413d;
--nat-table-header-background: #dce8e4;
--nat-table-header-color: #17211f;
--nat-table-header-border-color: #dce8e4;
--nat-table-row-background: #15211f;
--nat-table-row-background-hover: #1d2d2a;
--nat-table-row-background-focus: #243632;
--nat-table-cell-border-color: #253632;
--nat-table-cell-color-positive: #5eead4;
--nat-table-cell-color-warning: #f8c572;
--nat-table-cell-color-neutral: #c5d3cf;
--nat-table-focus-ring-color: #5eead4;
--nat-table-sort-icon-color-active: #17211f;
--nat-table-sort-icon-color-idle: rgb(23 33 31 / 62%);
--nat-table-sort-icon-color-hover: #17211f;
--nat-table-sort-button-color-sorted: #17211f;
--nat-table-scroll-button-color: #17211f;
--nat-table-scroll-button-background: #5eead4;
--nat-table-scroll-button-background-hover: #99f6e4;
--nat-table-scroll-button-border-color: #5eead4;
--nat-table-scroll-position-color: #c5d3cf;
--nat-table-scroll-range-track-color: #3d5f57;
--nat-table-scroll-range-track-border: 1px solid #6c8b83;
--nat-table-scroll-range-thumb-color: #5eead4;
--nat-table-scroll-range-thumb-border: 3px solid #15211f;
color-scheme: dark;
}
/* Custom properties are not force-adjusted, so in forced-colors (Windows High
Contrast) mode this palette would keep its values while the browser forces
backgrounds to the system colours — the light header text would end up
near-white on white. Hand the colour tokens back to the system keywords so
the forced palette governs; the demo is about token plumbing, not the
specific colours. Consumers theming the table should do the same. */
@media (forced-colors: active) {
.ledger-surface,
[data-theme='dark'] .ledger-surface {
--nat-table-color-text: CanvasText;
--nat-table-color-text-muted: CanvasText;
--nat-table-color-accent: LinkText;
--nat-table-color-success: CanvasText;
--nat-table-color-warning: CanvasText;
--nat-table-card-background: Canvas;
--nat-table-card-border-color: CanvasText;
--nat-table-card-shadow: none;
--nat-table-region-background: Canvas;
--nat-table-region-border-color: CanvasText;
--nat-table-header-background: Canvas;
--nat-table-header-color: CanvasText;
--nat-table-header-border-color: CanvasText;
--nat-table-row-background: Canvas;
--nat-table-row-background-hover: Canvas;
--nat-table-row-background-focus: Canvas;
--nat-table-cell-border-color: CanvasText;
--nat-table-cell-color-positive: CanvasText;
--nat-table-cell-color-warning: CanvasText;
--nat-table-cell-color-neutral: CanvasText;
--nat-table-focus-ring-color: Highlight;
--nat-table-sort-icon-color-active: CanvasText;
--nat-table-sort-icon-color-idle: CanvasText;
--nat-table-sort-icon-color-hover: CanvasText;
--nat-table-sort-button-color-sorted: CanvasText;
--nat-table-scroll-button-color: ButtonText;
--nat-table-scroll-button-background: ButtonFace;
--nat-table-scroll-button-background-hover: ButtonFace;
--nat-table-scroll-button-border-color: ButtonText;
--nat-table-scroll-position-color: CanvasText;
}
.ledger-list-surface {
--nat-list-item-background: Canvas;
--nat-list-item-border-color: CanvasText;
}
}
[data-theme='dark'] .ledger-list-surface {
--nat-list-item-background: #15211f;
--nat-list-item-border-color: #30413d;
}