Tessera Theme System
Scope
This document defines the V1 theming/styling contract for Tessera without DI and without engine leakage.
Goals:
- one consistent styling model across built-in controls
- semantic tokens instead of hardcoded colors in control code
- global defaults plus granular override points
- first-class support for built-in palettes and custom palettes
Out of scope for V1:
- inline image rendering in controls (target: V1.1)
Theme Tokens
Theme values should be semantic, not control-specific:
Text.Primary,Text.Secondary,Text.Muted,Text.InverseSurface.Base,Surface.Panel,Surface.OverlayBorder.Default,Border.Strong,Border.Focused,Border.ErrorState.Success,State.Warning,State.Error,State.InfoAccent.Primary,Accent.SecondarySelection.Background,Selection.ForegroundFocus.Ring,Focus.Title,Focus.Border,Focus.Marker
All tokens map to TesseraStyle values and are consumable by controls without raw ANSI strings in app code.
Focus.Marker is a first-class token and should drive focus-marker rendering for controls that expose marker hooks (FocusMarker/ShowFocusMarker), rather than hardcoded marker styling.
Consumer Hook Matrix (Quick Lookup)
Use these naming patterns on the no-DI public path (TesseraApplication.RunAsync(new App()) or TesseraApplication.CreateBuilder().UseApp<TApp>()...):
| Family | Focus | Selected | Hovered | Border |
|---|---|---|---|---|
Inputs/query (TextInput, TextArea, SearchBox) | FocusMarker, ShowFocusMarker, FocusedTitleStyle | control-specific Selected* hooks | control-specific Hovered* hooks | BorderStyleText, FocusedBorderStyleText |
Navigation/list (ListView<T>, TreeView, Choice, ComboBox) | title focus hooks + marker hooks | SelectedIndex/SelectedItem + Selected*Style | Hovered*Style | BorderStyleText, FocusedBorderStyleText |
Data/forms (Table, DataGrid, TreeTable, Form, FieldSet, DataForm<TModel>, ValidationSummary) | focused title/marker hooks | Selected*Style and row/cell markers | Hovered*Style | BorderStyleText, FocusedBorderStyleText |
Extended family-by-family matrix lives in public-api-inventory.
Typography Emphasis Intent
Tessera supports lightweight typography intent through TesseraFontWeight and TesseraStyle.WithFontWeight(...).
This maps to ANSI SGR emphasis flags only (Normal, Bold, Dim).
It does not control terminal font engines, real font families, font sizes, or ligature behavior.
Experimental terminal font request is exposed separately through ScreenOptions.FontSpec:
runtime.Screen = new ScreenOptions
{
FontSpec = "Iosevka Term 14",
};FontSpec behavior in Tessera V1:
- null/empty: no sequence emitted
- non-empty: renderer emits OSC 50 when value changes
- sanitization: strips
BEL,ESC,\, and control chars - reset: no forced font restore sequence
Cross-terminal support and terminal-specific caveats:
docs/terminal-font-capability-matrix.md.
ANSI Style Foundations
Low-level ANSI style composition lives in Tessera.Styles:
AnsiColorIndexed(0..255)Rgb(r, g, b)
TesseraStyleWithBoldWithUnderlineWithForegroundWithBackgroundWithItalicWithDimWithInverseWithFontWeight(...)Merge(...)ToEscapeSequence()Render(string text)
Use TesseraStyle as the primitive value type behind theme tokens and per-control overrides. Public docs should treat raw ANSI styling as the foundation layer, and theme tokens as the preferred application-facing layer.
Public API Names (V1 Foundations)
Theme primitives use the following public types:
TesseraThemeTesseraThemeTextTokensTesseraThemeSurfaceTokensTesseraThemeBorderTokensTesseraThemeStateTokensTesseraThemeAccentTokensTesseraThemeSelectionTokensTesseraThemeFocusTokensTesseraThemes.Catppuccin(CatppuccinVariant)TesseraThemes.RosePine(RosePineVariant)TesseraThemeOverridesTesseraThemeVisualStateTesseraThemeControlExtensions.ApplyTheme(...)TesseraRuntimeOptions.ThemeScreenOptions.FontSpec(experimental best-effort terminal font request)TesseraFontWeightTesseraStyle.WithFontWeight(TesseraFontWeight)
Theme Cookbook
Select Catppuccin
using Tessera;
using Tessera.Styles;
var app = TesseraApplication.CreateBuilder()
.UseApp<MyApp>()
.ConfigureRuntime(static runtime =>
{
runtime.Theme = TesseraThemes.Catppuccin(CatppuccinVariant.Mocha);
})
.Build();Select Rosé Pine
using Tessera;
using Tessera.Styles;
var app = TesseraApplication.CreateBuilder()
.UseApp<MyApp>()
.ConfigureRuntime(static runtime =>
{
runtime.Theme = TesseraThemes.RosePine(RosePineVariant.Main);
})
.Build();Set a Custom Theme
using Tessera;
using Tessera.Styles;
var baseTheme = TesseraThemes.Catppuccin(CatppuccinVariant.Macchiato);
var customTheme = new TesseraTheme
{
Text = baseTheme.Text,
Surface = baseTheme.Surface,
Border = new TesseraThemeBorderTokens
{
Default = baseTheme.Border.Default,
Strong = baseTheme.Border.Strong,
Focused = TesseraStyle.Empty.WithBold().WithForeground(AnsiColor.Rgb(255, 184, 108)),
Error = baseTheme.Border.Error,
},
State = baseTheme.State,
Accent = baseTheme.Accent,
Selection = baseTheme.Selection,
Focus = baseTheme.Focus,
};
var app = TesseraApplication.CreateBuilder()
.UseApp<MyApp>()
.ConfigureRuntime(runtime => runtime.Theme = customTheme)
.Build();Per-Control Overrides
using Tessera.Controls;
using Tessera.Styles;
var button = new Button
{
LabelStyle = TesseraStyle.Empty.WithForeground(AnsiColor.BrightWhite),
FocusedLabelStyle = TesseraStyle.Empty.WithBold().WithForeground(AnsiColor.BrightWhite),
SurfaceStyle = TesseraStyle.Empty.WithBackground(AnsiColor.Rgb(36, 24, 30)),
FocusedSurfaceStyle = TesseraStyle.Empty.WithBackground(AnsiColor.Rgb(54, 36, 44)),
};
`Button` treats label styles as text-only semantics.
Use `LabelStyle` / `FocusedLabelStyle` / `PressedLabelStyle` for foreground and emphasis.
Use `SurfaceStyle` / `FocusedSurfaceStyle` / `PressedSurfaceStyle` for button-body fill.
Background-like label facets are ignored so the button stays a single flat body.
Buttons now default to plain label chrome plus built-in horizontal breathing room.
Avoid layering a second chip-like background behind the label, because it breaks the intended box-model read and makes padding visually disappear.
Default button focus should come primarily from label emphasis; body fill may shift slightly for focused/pressed states, but the control should remain one coherent rectangle.
var list = new ListView<string>()
{
DefaultRowStyle = TesseraStyle.Empty.WithForeground(AnsiColor.BrightWhite),
HoveredRowStyle = TesseraStyle.Empty.WithUnderline().WithForeground(AnsiColor.BrightCyan),
SelectedRowStyle = TesseraStyle.Empty.WithBold().WithForeground(AnsiColor.BrightGreen),
};
var input = new TextInput
{
ValueTextStyle = TesseraStyle.Empty.WithForeground(AnsiColor.BrightWhite),
PlaceholderTextStyle = TesseraStyle.Empty.WithDim().WithForeground(AnsiColor.BrightBlack),
FocusedTitleStyle = TesseraStyle.Empty.WithBold().WithForeground(AnsiColor.BrightYellow),
};Overlay Glyph APIs (MenuBar, ContextMenu, CommandPalette)
using Tessera.Controls;
var menuBar = new MenuBar
{
Border = BorderStyle.SingleLine,
Glyphs = new MenuBarGlyphSet("[", "]", " ", " ", "{", "}", "<", ">"),
};
var contextMenu = new ContextMenu
{
Border = BorderStyle.Rounded,
ShowFocusMarker = true,
Glyphs = new ContextMenuGlyphSet("·", ">", "▸", " "),
};
var commandPalette = new CommandPalette
{
Border = BorderStyle.Rounded,
ShowFocusMarker = true,
Glyphs = new CommandPaletteGlyphSet("❯", " ", ">", "▸", " "),
};Border Override APIs (High-Use Controls)
using Tessera.Controls;
using Tessera.Styles;
var input = new TextInput
{
BorderStyleText = TesseraStyle.Empty.WithForeground(AnsiColor.BrightBlack),
FocusedBorderStyleText = TesseraStyle.Empty.WithBold().WithForeground(AnsiColor.BrightCyan),
};
var choice = new Choice
{
BorderStyleText = TesseraStyle.Empty.WithForeground(AnsiColor.BrightBlack),
FocusedBorderStyleText = TesseraStyle.Empty.WithBold().WithForeground(AnsiColor.BrightGreen),
};
var grid = new DataGrid
{
BorderStyleText = TesseraStyle.Empty.WithForeground(AnsiColor.BrightBlack),
FocusedBorderStyleText = TesseraStyle.Empty.WithBold().WithForeground(AnsiColor.BrightYellow),
};Visual Polish Patterns (Choice/ComboBox/TreeView)
Use the same three-layer pattern for polished defaults and app-specific overrides:
- border hook override (
BorderStyleText,FocusedBorderStyleText) - typed glyph set override (
DropdownGlyphSet,TreeViewGlyphSet) - text-state override (
TitleStyle,FocusedTitleStyle, row/item styles)
using Tessera.Controls;
using Tessera.Styles;
var choice = new Choice
{
BorderStyleText = TesseraStyle.Empty.WithForeground(AnsiColor.BrightBlack),
FocusedBorderStyleText = TesseraStyle.Empty.WithBold().WithForeground(AnsiColor.BrightGreen),
Glyphs = new DropdownGlyphSet("▾", "▴", ">", "✓"),
TitleStyle = TesseraStyle.Empty.WithForeground(AnsiColor.BrightWhite),
FocusedTitleStyle = TesseraStyle.Empty.WithBold().WithForeground(AnsiColor.BrightCyan),
};
var comboBox = new ComboBox
{
BorderStyleText = TesseraStyle.Empty.WithForeground(AnsiColor.BrightBlack),
FocusedBorderStyleText = TesseraStyle.Empty.WithBold().WithForeground(AnsiColor.BrightYellow),
Glyphs = new DropdownGlyphSet("▼", "▲", "•", "✓"),
};
var treeView = new TreeView
{
BorderStyleText = TesseraStyle.Empty.WithForeground(AnsiColor.BrightBlack),
FocusedBorderStyleText = TesseraStyle.Empty.WithBold().WithForeground(AnsiColor.BrightMagenta),
Glyphs = new TreeViewGlyphSet("▼", "▶", "•"),
TitleStyle = TesseraStyle.Empty.WithForeground(AnsiColor.BrightWhite),
FocusedTitleStyle = TesseraStyle.Empty.WithBold().WithForeground(AnsiColor.BrightMagenta),
};Wave 1 App Shell + Forms Theme Hooks
TesseraThemeControlExtensions.FormsAndShell.cs includes explicit mappings for:
FormFieldSetDataForm<TModel>WizardSplitViewInspectorPanel
These controls map BorderStyleText and FocusedBorderStyleText to semantic border/focus tokens by default.
using Tessera.Controls;
using Tessera.Styles;
var theme = TesseraThemes.Catppuccin(CatppuccinVariant.Frappe);
var form = new Form().ApplyThemeDefaults(theme);
form.RequiredMarkerStyle = TesseraStyle.Empty.WithBold().WithForeground(AnsiColor.BrightRed);
var dataForm = new DataForm<object>().ApplyThemeDefaults(theme);
dataForm.ErrorStyle = TesseraStyle.Empty.WithBold().WithForeground(AnsiColor.BrightRed);
var wizard = new Wizard().ApplyThemeDefaults(theme);
wizard.ActiveStepStyle = TesseraStyle.Empty.WithBold().WithForeground(AnsiColor.BrightCyan);
var split = new SplitView().ApplyThemeDefaults(theme);
split.FocusedDividerStyle = TesseraStyle.Empty.WithBold().WithForeground(AnsiColor.BrightYellow);Wave 2 Data/Planning/Query Theme Hooks
TesseraThemeControlExtensions includes explicit mappings for:
VirtualizedListView<T>GroupedListView<TGroup,TItem>PivotTableQueryBuilderKanbanBoardTagInputCalendarMonthViewSchedulerTimelineRichTextView
Bordered controls in this set (VirtualizedListView<T>, GroupedListView<TGroup,TItem>, PivotTable, QueryBuilder, KanbanBoard, TagInput, RichTextView) map BorderStyleText and FocusedBorderStyleText to semantic border/focus tokens by default.
TagInput also maps CaretStyle to theme.Focus.Ring by default, while placeholder tint remains controllable through PlaceholderTextStyle.
using Tessera.Controls;
using Tessera.Styles;
var theme = TesseraThemes.Catppuccin(CatppuccinVariant.Mocha);
var kanban = new KanbanBoard().ApplyThemeDefaults(theme);
kanban.BorderStyleText = TesseraStyle.Empty.WithForeground(AnsiColor.BrightBlack);
kanban.FocusedBorderStyleText = TesseraStyle.Empty.WithBold().WithForeground(AnsiColor.BrightYellow);
var scheduler = new SchedulerTimeline().ApplyThemeDefaults(theme);
scheduler.ConflictRowStyle = TesseraStyle.Empty.WithBold().WithForeground(AnsiColor.BrightRed);
var query = new QueryBuilder().ApplyThemeDefaults(theme);
query.ErrorRuleStyle = TesseraStyle.Empty.WithBold().WithForeground(AnsiColor.BrightRed);
var richText = new RichTextView().ApplyThemeDefaults(theme);
richText.InlineCodeStyle = TesseraStyle.Empty.WithBackground(AnsiColor.BrightBlack).WithForeground(AnsiColor.BrightWhite);Wave 3 Dev/Ops Theme Hooks
TesseraThemeControlExtensions includes explicit mappings for:
JsonTreeViewTraceViewerCommandOutputLogTailPanelTaskRunnerPanelActivityFeedNotificationInboxKeyBindingHelpDialog
Bordered controls in this set (JsonTreeView, TraceViewer, CommandOutput, LogTailPanel, TaskRunnerPanel, ActivityFeed) map BorderStyleText and FocusedBorderStyleText to semantic border/focus tokens by default.
using Tessera.Controls;
using Tessera.Styles;
var theme = TesseraThemes.RosePine(RosePineVariant.Main);
var logs = new LogTailPanel().ApplyThemeDefaults(theme);
logs.BorderStyleText = TesseraStyle.Empty.WithForeground(AnsiColor.BrightBlack);
logs.FocusedBorderStyleText = TesseraStyle.Empty.WithBold().WithForeground(AnsiColor.BrightYellow);
var trace = new TraceViewer().ApplyThemeDefaults(theme);
trace.WarningRowStyle = TesseraStyle.Empty.WithBold().WithForeground(AnsiColor.BrightYellow);
var tasks = new TaskRunnerPanel().ApplyThemeDefaults(theme);
tasks.FailedStatusStyle = TesseraStyle.Empty.WithBold().WithForeground(AnsiColor.BrightRed);
var inbox = new NotificationInbox().ApplyThemeDefaults(theme);
inbox.PinnedItemStyle = TesseraStyle.Empty.WithBold().WithForeground(AnsiColor.BrightCyan);
var help = new KeyBindingHelpDialog().ApplyThemeDefaults(theme);
help.KeysStyle = TesseraStyle.Empty.WithBold().WithForeground(AnsiColor.BrightWhite);Wave 4 Workspace + Visual Data Theme Hooks (Batch A + B)
TesseraThemeControlExtensions.Workspace.cs includes explicit mappings for:
DockWorkspacePaneTabsPaletteEditorHeatmapTreeMapChartTerminalPanelProcessListView
Bordered controls in this set (DockWorkspace, PaneTabs, Heatmap, TreeMapChart, ProcessListView) map BorderStyleText and FocusedBorderStyleText to semantic border/focus tokens by default.
using Tessera.Controls;
using Tessera.Styles;
var theme = TesseraThemes.Catppuccin(CatppuccinVariant.Macchiato);
var workspace = new DockWorkspace().ApplyThemeDefaults(theme);
workspace.FocusedPaneBorderStyleText = TesseraStyle.Empty.WithBold().WithForeground(AnsiColor.BrightYellow);
var tabs = new PaneTabs().ApplyThemeDefaults(theme);
tabs.HoveredTabStyle = TesseraStyle.Empty.WithUnderline().WithForeground(AnsiColor.BrightCyan);
var heatmap = new Heatmap().ApplyThemeDefaults(theme);
heatmap.PeakCellStyle = TesseraStyle.Empty.WithBold().WithForeground(AnsiColor.BrightGreen);
var processList = new ProcessListView().ApplyThemeDefaults(theme);
processList.HeaderStyle = TesseraStyle.Empty.WithBold().WithForeground(AnsiColor.BrightWhite);
var terminal = new TerminalPanel().ApplyThemeDefaults(theme);
terminal.StandardErrorStyle = TesseraStyle.Empty.WithBold().WithForeground(AnsiColor.BrightRed);Dropdown and Tree Glyph Sets
using Tessera.Controls;
var combo = new ComboBox
{
Glyphs = new DropdownGlyphSet("v", "^", ">", "+"),
};
var tree = new TreeView
{
Glyphs = new TreeViewGlyphSet("▼", "▶", "•"),
};Search Results Glyph Set
using Tessera.Controls;
var results = new SearchResultsView
{
Glyphs = new SearchResultsGlyphSet("·", "▸", "▶", "~", "."),
ShowRankMarker = true,
};Data Widget Marker and Separator APIs
using Tessera.Controls;
var dataGrid = new DataGrid
{
ColumnSeparatorText = " │ ",
SortAscendingMarker = " ↑",
SortDescendingMarker = " ↓",
};
var treeTable = new TreeTable("Name", "Value")
{
ColumnSeparatorText = " │ ",
SelectedRowMarker = ">",
UnselectedRowMarker = " ",
ExpandedBranchMarker = "▼",
CollapsedBranchMarker = "▶",
LeafMarker = "•",
};Palette Model
V1 ships with:
- Catppuccin variants (
Latte,Frappe,Macchiato,Mocha) - Rosé Pine variants (
Main,Moon,Dawn) - custom user palette from strongly typed theme objects
Palette selection is runtime-configurable and does not require app architecture patterns beyond TesseraApp + TesseraRuntimeOptions.
Override Hierarchy
Style resolution order (lowest to highest precedence):
- framework default theme
- selected palette
- global app theme overrides
- control-type theme overrides (for example all
Button) - control instance overrides
- state overrides (
Focused,Hovered,Selected,Disabled,Error,Active)
This hierarchy allows global consistency with explicit local escape hatches.
Visual State Policy
Default policy for all controls:
- focus is visualized by themeable border/title style (not only
"*"markers) - selected and hovered states are visually distinct in monochrome-safe and color-capable terminals
- error/warning/success states are token-driven and accessible by contrast
- disabled/read-only states are clearly lower emphasis, still readable
Implemented Extension Layout
TesseraThemeControlExtensions is split into domain partial files:
TesseraThemeControlExtensions.Basic.csTesseraThemeControlExtensions.InputValue.csTesseraThemeControlExtensions.Navigation.csTesseraThemeControlExtensions.NavigationOverlay.csTesseraThemeControlExtensions.NavigationPrimitives.csTesseraThemeControlExtensions.DataAndFlow.csTesseraThemeControlExtensions.ExplorerAndFeedback.csTesseraThemeControlExtensions.RenderingTextUtilities.csTesseraThemeControlExtensions.ModalAndCharts.csTesseraThemeControlExtensions.Plotting.csTesseraThemeControlExtensions.DevOpsAndWorkflows.csTesseraThemeControlExtensions.Workspace.csTesseraThemeControlExtensions.FormsAndShell.cs
Mapped controls expose:
ApplyTheme(TesseraTheme theme)ApplyThemeDefaults(TesseraTheme theme)- plotting mappings:
Sparkline,TelemetryChart,AreaPlot,ScatterPlot,Histogram,LinePlot,PlotPanel - workspace mappings:
DockWorkspace,PaneTabs,PaletteEditor,Heatmap,TreeMapChart,TerminalPanel,ProcessListView - app-shell/forms mappings:
Form,FieldSet,DataForm<TModel>,Wizard,SplitView,InspectorPanel - overloads taking
TesseraThemeOverrides,baseTheme, andTesseraThemeVisualState
Input/value mapping coverage includes:
TextInput,TextArea,Toggle,Slider,Spinner,ProgressBar,NumberInput,DatePicker,TimePickerTextInputmaps value/placeholder/focused-title styles; title marker remains configurable viaFocusMarker+ShowFocusMarkerTextInputmapsBorderStyleText->theme.Border.DefaultandFocusedBorderStyleText->theme.Border.Focused.Merge(theme.Focus.Border)Toggle,Slider,Spinner, andProgressBarmapBorderStyleText->theme.Border.DefaultandFocusedBorderStyleText->theme.Border.Focused.Merge(theme.Focus.Border)TextArea,NumberInput,DatePicker, andTimePickermapBorderStyleText->theme.Border.DefaultandFocusedBorderStyleText->theme.Border.Focused.Merge(theme.Focus.Border)
Basic mapping coverage includes:
Label,Button,ListView<T>,StatusBar,TextInput,Table,TabsButtonmapsSurfaceStyle->theme.Surface.Panel,FocusedSurfaceStyle->theme.Surface.Panel, andPressedSurfaceStyle->theme.Selection.BackgroundButtonlabel styles are text-only; body/background comes from button surface stylesTablemapsBorderStyleText->theme.Border.DefaultandFocusedBorderStyleText->theme.Border.Focused.Merge(theme.Focus.Border)
Navigation mapping coverage includes:
Breadcrumb,Paginator,Toolbar,CommandBar,SearchBox,SearchResultsViewSearchBoxmaps title/value/placeholder/match/navigation styles plus border text hooksSearchResultsViewmaps title, row-state, and border text hooks; row markers are customizable throughSearchResultsGlyphSet
Navigation/overlay mapping coverage includes:
Choice,ComboBox,TreeView,MenuBar,ContextMenu,CommandPalette,Notifications,SearchBoxChoice/ComboBoxmapBorderStyleText->theme.Border.DefaultChoice/ComboBoxmapFocusedBorderStyleText->theme.Border.Focused.Merge(theme.Focus.Border)Choice/ComboBoxexposeGlyphsviaDropdownGlyphSetfor closed/open/highlight/selected markersTreeViewmaps border text hooks and title focus marker; branch/leaf markers are configurable throughTreeViewGlyphSetMenuBar,ContextMenu, andCommandPalettemapBorderStyleText+FocusedBorderStyleTextto border/focus tokensMenuBar,ContextMenu, andCommandPaletteexpose typed glyph configuration (MenuBarGlyphSet,ContextMenuGlyphSet,CommandPaletteGlyphSet)NotificationsmapsBorderStyleText+FocusedBorderStyleTextto border/focus tokensContextMenupreserves focused title markers in bordered title rendering width calculationsSearchBoxmaps title/value/placeholder/match/navigation styles plus border text hooks; title marker is configurable throughFocusMarker+ShowFocusMarker
Navigation primitive mapping coverage includes:
Accordion,MultiSelect,RadioGroup
Rendering text utility mapping coverage includes:
Badge,LogView,MarkdownView,MiniLogLogViewandMarkdownViewmapBorderStyleText+FocusedBorderStyleTextto border/focus tokens
Modal/chart summary mapping coverage includes:
Dialog,Modal,BarChart,LineChart,Gauge,StatsCardDialogandModalmap border text hooks to semantic border/focus tokens
Data/flow mapping coverage includes:
DataGrid,TreeTable,KeyValueList,Timeline,StepperDataGridmaps border text hooks and exposesColumnSeparatorTextplus sort marker text APIsTreeTablemaps border text hooks and exposesColumnSeparatorText, row marker text APIs, and branch/leaf marker text APIsKeyValueListandTimelinemap border text hooks to semantic border/focus tokens
Explorer/feedback mapping coverage includes:
DiffView,PropertyGrid,FileExplorer,FuzzyFinder,ToastCenterDiffView,PropertyGrid,FileExplorer,FuzzyFinder, andToastCentermapBorderStyleText+FocusedBorderStyleTextto border/focus tokens
Dev/ops workflow mapping coverage includes:
JsonTreeView,CommandOutput,LogTailPanel,ActivityFeed,NotificationInbox,KeyBindingHelpDialog- bordered controls in this set map
BorderStyleText+FocusedBorderStyleTextto border/focus tokens
Workspace/visual-data mapping coverage includes:
DockWorkspace,PaneTabs,PaletteEditor,Heatmap,TreeMapChart,TerminalPanel,ProcessListView- bordered controls in this set map
BorderStyleText+FocusedBorderStyleTextto border/focus tokens
App-shell/forms mapping coverage includes:
Form,FieldSet,DataForm<TModel>,Wizard,SplitView,InspectorPanel- bordered controls in this set map
BorderStyleText+FocusedBorderStyleTextto border/focus tokens
Bordered control parity enforcement:
- new bordered controls must expose
BorderStyleTextandFocusedBorderStyleText - new bordered controls must map those hooks to
theme.Border.Defaultandtheme.Border.Focused.Merge(theme.Focus.Border) - test enforcement is maintained through
ThemeOverridesTests.*token-mapping suites,VisualParityTestsedge-case coverage, andBorderedControlParityPolicyTests.cs - bordered-control parity rollout is complete for current shipped controls; policy remains forward-only for newly added controls
V1 Rollout
Phase 1 (baseline controls):
Label,StatusBar,Button,TextInput,ListView<T>,Table,Tabs,Breadcrumb,Paginator,Toolbar,CommandBar,SearchBox,Dialog,ContextMenu,CommandPalette
Phase 2 (data and advanced controls):
TreeView,DataGrid,TreeTable,KeyValueList,Timeline,Stepper,MenuBar,Notifications,DiffView,PropertyGrid,FileExplorer,FuzzyFinder,ToastCenter,Toggle,Slider,Spinner,Accordion,MultiSelect,RadioGroup,Badge,LogView,MarkdownView,MiniLog,Dialog,Modal,BarChart,LineChart,Gauge,StatsCard
Acceptance criteria:
- top controls expose style/theme override points with consistent naming
- focus, hover, selection, disabled, and error styles are configurable
- Catppuccin + Rosé Pine + custom palette can be applied without control-level rewiring
- docs and examples demonstrate global theme selection and per-control override
- starter theming docs stay focused on primary
Tesseraauthoring namespaces
V1.1 Note
Image rendering is planned for V1.1 with capability-based backends and graceful fallback modes.