Documentation
¶
Overview ¶
Package ui holds the drawing primitives of the seamark console: the theme, the glyphs and the tones, the boxes, the modals and the overlay, the text helpers, the scroll, pager and list state, the line input (input.go), the multi-line text area (textarea.go), the movement keys and the n/a key helpers. The screens of internal/tui draw with them. input.go says why the console adopts no bubbles widget.
What belongs here ¶
A declaration belongs to ui only when it renders or tracks a position without seamark vocabulary. The rule applies to its name, its parameters, its fields and its doc. Seamark vocabulary is, for example, effect, phase, region, proposal, pin, lesson, run, integration, client, setup, policy, brand and workspace. A declaration that names such a concept stays in internal/tui, usually in its widgets.go. So the next author can decide a move from the name alone.
Imports ¶
ui imports the standard library and third-party packages freely, for example Lip Gloss, Bubbles key, x/ansi, termenv, and Bubble Tea for key messages. Of the seamark packages, it imports only internal/redact and internal/render, because the sanitizers need them. It never imports internal/tui or internal/tui/services, so a primitive cannot reach a screen, the console state or an engine. TestUIStaysBelowTheConsole checks this.
Exports ¶
ui exports what internal/tui uses and nothing more; a name that only tests use stays unexported. The state types keep their fields exported, as the Bubbles widgets do, so a screen reads a position without an accessor.
Index ¶
- Constants
- Variables
- func BoxInner(w int) int
- func BoxRows(h int) int
- func BoxTitle(t *Theme, title string, focused bool) string
- func ClipWithEllipsis(lines []string, n, w int, ellipsis string) []string
- func Diag(s string) string
- func DisplayPath(p string) string
- func DropBlankLines(lines []string, n int) []string
- func ErrText(err error) string
- func Fit(s string, w, h int) string
- func HJoin(gap int, blocks ...string) string
- func IsBlank(line string) bool
- func IsUnavailable(b key.Binding) bool
- func JoinBlocks(blocks ...string) string
- func JoinLineBlocks(gap int, blocks ...[]string) []string
- func ListAll(bindings []key.Binding) []key.Binding
- func Listed(b key.Binding) bool
- func ModalBodyWidth(minW, w int) int
- func MultiLine(s string) string
- func OneLine(s string) string
- func PadLeft(s string, w int) string
- func PadRight(s string, w int) string
- func Spread(left, right string, w int) string
- func Truncate(s string, w int, ellipsis string) string
- func TruncateLeft(s string, w int, ellipsis string) string
- func Unavailable(b key.Binding) key.Binding
- func Width(s string) int
- func WithHelp(b key.Binding, k, desc string) key.Binding
- func Wrap(s string, w int) string
- type BoxOpts
- type ColCell
- type Glyphs
- type LineInput
- func (in *LineInput) Holds(s string) bool
- func (in *LineInput) Key(msg tea.KeyMsg)
- func (in *LineInput) MaxRunes() int
- func (in *LineInput) Notice() string
- func (in *LineInput) ReadOnly() bool
- func (in *LineInput) Set(s string)
- func (in *LineInput) Value() string
- func (in *LineInput) View(t *Theme) string
- type ListState
- type ModalOpts
- type NavKeys
- type ScrollState
- type TextArea
- type TextPager
- type Theme
- func (t *Theme) ASCIIFrame(s string) string
- func (t *Theme) Action(k, label string, primary bool) string
- func (t *Theme) Badge(tone Tone, label string) string
- func (t *Theme) Bar(n, total, w int, tone Tone) string
- func (t *Theme) Box(o BoxOpts) string
- func (t *Theme) Card(w, h int, title, right string, lines []string) string
- func (t *Theme) Cols(cells ...ColCell) string
- func (t *Theme) Columns(vals []int, h int, tone Tone) []string
- func (t *Theme) Empty(tone Tone, title, body, next string, w, h int) string
- func (t *Theme) Highlight(row string, w, bg int) string
- func (t *Theme) Hints(bindings []key.Binding) string
- func (t *Theme) KeyHints(bindings []key.Binding) string
- func (t *Theme) KeyLabel(k string) string
- func (t *Theme) Modal(o ModalOpts, sc *ScrollState, w, h int) string
- func (t *Theme) MutedLines(lines []string) []string
- func (t *Theme) Overlay(base, block string, w, h int) string
- func (t *Theme) PositionNote(first, last, total int) string
- func (t *Theme) RangeNote(from, to, n int) string
- func (t *Theme) ScrollBox(o BoxOpts, body, tail []string, sc *ScrollState, keep [2]int, follow bool) string
- func (t *Theme) ScrollNote(offset, window, n, w int) string
- func (t *Theme) ShortHints(bindings []key.Binding) string
- func (t *Theme) SpinnerFrame(tick int) string
- func (t *Theme) StickyBox(o BoxOpts, head, body, tail []string, sc *ScrollState, keep [2]int, ...) string
- func (t *Theme) ToneGlyph(tone Tone) string
- func (t *Theme) ToneStyle(tone Tone) lipgloss.Style
- type Tone
Constants ¶
const ( BgSel = iota BgWarn BgAdd BgDel )
Row backgrounds of the 1a design. The selection spans the full inner width of a pane; diff rows and the stale banner use tinted rows.
const ( WideWidth = 100 MinWidth = 60 MinHeight = 20 )
Layout thresholds. A terminal at least WideWidth cells wide shows a list and its detail side by side; a narrower one shows one pane at a time. Below MinWidth by MinHeight the shell asks for more space. MinHeight is 20, because at 16 rows the confirmation dialogs lost their safety notes and the empty states lost their next action.
const DialogMinBox = 12
DialogMinBox is the narrowest modal box, so the text inside keeps a usable width even in a narrow area.
const (
ModalMinW = 80
)
Modal geometry: 80 cells at the 120-column design size, wider on a wide terminal so long lines fold less.
UnavailableWord marks the keys that the current target cannot use. It is ASCII and it is a word, so the marker reads without color, under NO_COLOR and with the ASCII glyph set.
Variables ¶
Up: key.NewBinding(key.WithKeys("up", "k"), key.WithHelp("↑/k", "up")), Down: key.NewBinding(key.WithKeys("down", "j"), key.WithHelp("↓/j", "down")), PageUp: key.NewBinding(key.WithKeys("pgup", "ctrl+u"), key.WithHelp("pgup", "page up")), PageDown: key.NewBinding(key.WithKeys("pgdown", "ctrl+d"), key.WithHelp("pgdn", "page down")), Top: key.NewBinding(key.WithKeys("home", "g"), key.WithHelp("home", "first")), Bottom: key.NewBinding(key.WithKeys("end", "G"), key.WithHelp("end", "last")), Enter: key.NewBinding(key.WithKeys("enter"), key.WithHelp("enter", "open")), Back: key.NewBinding(key.WithKeys("esc"), key.WithHelp("esc", "back")), Toggle: key.NewBinding(key.WithKeys(" "), key.WithHelp("space", "select")), Next: key.NewBinding(key.WithKeys("tab"), key.WithHelp("tab", "next pane")), Prev: key.NewBinding(key.WithKeys("shift+tab"), key.WithHelp("shift+tab", "previous pane")), Left: key.NewBinding(key.WithKeys("left", "h"), key.WithHelp("←/h", "left")), Right: key.NewBinding(key.WithKeys("right", "l"), key.WithHelp("→/l", "right")), }
Nav holds the movement and activation bindings of every screen. ScrollState, TextPager and ListState read them, so a key moves a text and a list alike.
Functions ¶
func BoxInner ¶
BoxInner returns the content width of a box of outer width w: the two border cells and one cell of padding on each side.
func BoxTitle ¶
BoxTitle styles a box title: the focused pane in the title style, the other panes muted, as in the 1a design. The caller sanitizes the title, because most titles are fixed words.
func ClipWithEllipsis ¶
ClipWithEllipsis keeps the first n plain lines. When lines are cut, the last kept line ends with the ellipsis, so the cut is visible.
func Diag ¶
Diag makes a diagnostic safe: it redacts secrets first, because reader errors and native settings can quote tokens.
func DisplayPath ¶
DisplayPath shortens an absolute path for the header: the home directory becomes "~".
func DropBlankLines ¶
DropBlankLines removes up to n blank lines, the last ones first. The blank lines near the top stay, because they separate the lead text that the reader sees first.
func Fit ¶
Fit clips or pads rendered text to exactly w cells by h lines. The shell needs exact sizes so a pane never pushes the footer away.
func HJoin ¶
HJoin places rendered blocks side by side with gap cells between them. Blocks of different heights are padded at the bottom.
func IsUnavailable ¶
IsUnavailable reports an entry that unavailable made. A binding that a screen only disables stays hidden, so no other screen changes.
func JoinBlocks ¶
JoinBlocks joins non-empty blocks with a blank line between them.
func JoinLineBlocks ¶
JoinLineBlocks joins the non-empty line blocks with gap blank lines between them.
func ListAll ¶
ListAll returns bindings with each disabled binding that has a key label as an unavailable entry. The help of a screen uses it to name every key of the screen, also the keys that do not work now.
func Listed ¶
Listed reports a binding that the hint rows and the help show: an enabled binding or an unavailable entry, each with a key label.
func ModalBodyWidth ¶
ModalBodyWidth returns the width of the body lines of a modal in a w-wide area. A caller wraps the body to this width, so the box shows each line whole.
func MultiLine ¶
MultiLine makes untrusted multi-line text safe and keeps its line breaks. Tabs become spaces because they break width arithmetic.
func OneLine ¶
OneLine makes untrusted text safe for a single terminal line. Repository content, stored text and file names can hold escape sequences; the sanitizer keeps them inert.
func TruncateLeft ¶
TruncateLeft shortens s from the left, which keeps the most specific part of a path visible.
func Unavailable ¶
Unavailable returns b as an entry that the hint rows and the help list as not available now: muted, after the word n/a. The copy is disabled, so every Enabled check reads it as not offered. A screen uses it for a key that the user must find even when the current target cannot use it (a user decision of 2026-10-04). The screen still handles the key press itself, with its package binding, and explains the refusal.
func WithHelp ¶
WithHelp returns a copy of b with a different help text, so a screen can describe what a shared key does in its context.
Types ¶
type BoxOpts ¶
type BoxOpts struct {
// W and H are the outer size in cells, borders included.
W, H int
// Title is the styled label at the left of the top border.
Title string
// Right is the styled label at the right of the top border, for
// example a count or a state.
Right string
// Foot is the styled label at the right of the bottom border, for
// example a scroll position.
Foot string
// Focus draws the border in the accent color. Only the pane that
// receives the movement keys has focus.
Focus bool
// Lines are the styled content lines. Each line is clipped to the
// inner width with an ellipsis; lines past the inner height are
// dropped, so callers scroll before they render.
Lines []string
// Fill paints the modal surface under the whole box.
Fill bool
}
BoxOpts describes one bordered pane of the 1a layout. The title, the right label and the footer sit inside the border lines, so a pane spends no content line on its own heading.
type Glyphs ¶
type Glyphs struct {
HeaderLeft, HeaderMid, HeaderRight string
Cursor, Check, Uncheck, Locked, Kept, Bullet, Arrow, Sep, Ellipsis string
Dash, OK, Warn, Fail, Info, Unknown, Unsupported string
Dot, Hollow string
RadioOn, RadioOff string
RuleLight, RuleHeavy, Vertical string
CornerTL, CornerTR, CornerBL string
CornerBR string
BarFull, BarEmpty string
Spark []string
Add, Del string
Spinner []string
}
Glyphs is one glyph set. The Unicode set uses only the single-width symbols of the 1a design, so width arithmetic stays exact. The ASCII set exists for fonts without these symbols. In each set, Sep differs from Vertical, because without color the glyph is the only signal between them.
type LineInput ¶
type LineInput struct {
// Placeholder is the faint hint of an empty input. "" keeps the
// path hint.
Placeholder string
// Limit bounds the value in runes. 0 keeps lineInputLimit.
Limit int
// Accept filters typed runes, for example digits only for a day
// count. nil accepts every rune that the sanitizer keeps.
Accept func(rune) bool
// RefuseMultiline refuses a whole input that holds a line break, for
// example a paste of two lines, and Notice says why. Without it, the
// line breaks go away and the lines join, which a filter accepts.
RefuseMultiline bool
// RefuseOverLimit refuses a whole input that would pass Limit, and
// Notice says why. Without it, the runes past the limit go away
// silently. With it, a value longer than the limit from Set is read
// only (ReadOnly), because an edit could only shorten it by a cut.
RefuseOverLimit bool
// contains filtered or unexported fields
}
LineInput is a minimal single-line text input. The filter bars, the editors and the forms of the console use it. A filter or a count needs only typing, deletion and cursor movement. The optional fields let each form set its own hint, bound and runes. Their zero values keep the path filter behaviour, because the path filter was the first user.
func (*LineInput) Holds ¶
Holds reports whether the input can show and edit s exactly: the sanitizer and the accept filter keep every rune. A form opens a value that fails it as read-only, because an edit would change runes that the user never touched.
func (*LineInput) Key ¶
Key applies one key press. The sanitizer, the accept filter and the length bound drop runes, unless an opt-in field refuses the whole input instead. A read-only value takes only the movement keys.
func (*LineInput) MaxRunes ¶
MaxRunes returns the length bound of the value in runes: Limit, or lineInputLimit when Limit is 0. A form names this bound when it locks a stored value, so the form never copies the number.
func (*LineInput) Notice ¶
Notice returns why the last key changed less than the user typed, or "". A form shows it under the input, because a refused paste must be visible. A field without an opt-in always returns "".
func (*LineInput) ReadOnly ¶
ReadOnly reports a value that is longer than the limit while RefuseOverLimit is set. Only Set can make such a value, for example with a text from a file. Key then moves the cursor but changes no rune.
type ListState ¶
ListState is the cursor and scroll offset of one plain list. Screens keep one per list, so resize and refresh never reset the position.
func (*ListState) Clamp ¶
Clamp keeps the cursor inside n rows and the cursor row inside a window of h rows. It records a positive h as the window of the page keys. A key handler passes 0, because it does not know the height, and the recorded window then stays.
type ModalOpts ¶
type ModalOpts struct {
Title, Right string
Body []string
// Actions are the keys under the rule at the bottom. The row stays
// visible while the body scrolls.
Actions []key.Binding
// Tail is the summary of a confirmation, for example "Removes 2
// lines from one file". It stays under the rule, above the
// actions, and never scrolls, so the minimum layout still shows what
// y confirms. The caller wraps each line to ModalBodyWidth; the box
// clips a longer line. A summary taller than the area keeps its first
// lines, so the actions and the border stay (capTail). Nil keeps the
// layout without a summary.
Tail []string
// MinW is the narrowest modal on a wide terminal; 0 selects
// ModalMinW. A small terminal still gets a narrower modal.
MinW int
// Follow asks the modal to show the body lines Keep[0] to Keep[1],
// for example the cursor row of a form. Only the modal knows the
// height of its window, so a key handler sets Follow and the next
// render scrolls. A negative Keep[0] keeps the position.
Follow bool
Keep [2]int
}
ModalOpts is the content of one modal: the border labels, the body that scrolls, and the actions that the bottom row names.
type NavKeys ¶
type NavKeys struct {
}
NavKeys are the shared movement and activation bindings. Screens use these values so every list moves the same way.
type ScrollState ¶
ScrollState is the vertical position of one scrollable text. The view records the page size and the last offset, because the key handler cannot know how tall the rendered text is. The modals and most panes share this type, so their texts scroll with the same keys.
func (*ScrollState) Fit ¶
func (sc *ScrollState) Fit(n, h int) (from, to int)
Fit records the bounds of a text of n lines in a window of h lines and returns the visible range [from, to). It clamps the offset, because a resize or a refresh can make the text shorter. Every box that scrolls calls it once per render, so all boxes keep one rule.
func (*ScrollState) Key ¶
func (sc *ScrollState) Key(msg tea.KeyMsg) bool
Key applies a movement key and reports whether the key was one.
func (*ScrollState) Reveal ¶
func (sc *ScrollState) Reveal(top, bottom, h int)
Reveal moves the offset so that the lines top to bottom show in a window of h lines. A negative top means no line to keep, so nothing moves. When the range is taller than the window, the top line wins, because it holds the heading of the cursor group. The caller runs fit next, which brings the offset back inside the bounds.
func (*ScrollState) Scrolls ¶
func (sc *ScrollState) Scrolls() bool
Scrolls reports text that is taller than its window.
type TextArea ¶
type TextArea struct {
// Placeholder is the faint hint of an empty area. "" shows only the
// cursor.
Placeholder string
// contains filtered or unexported fields
}
TextArea is a multi-line text input with soft wrap. enter inserts a line break, so a form leaves the area with another key, for example esc. The arrows, home and end, ctrl+a and ctrl+e, pgup and pgdown move the cursor. The zero value is an empty area.
func (*TextArea) Holds ¶
Holds reports whether the area can show and edit s exactly: it keeps every rune of s.
func (*TextArea) Key ¶
Key applies one key press. A paste arrives as one key with every rune. A terminal without bracketed paste sends a line break as enter or ctrl+j, and a tab as tab. So these keys insert their rune.
func (*TextArea) Notice ¶
Notice returns why the last input lost runes, or "". A form shows it under the area, because a dropped rune must be visible.
func (*TextArea) SetValue ¶
SetValue replaces the text and puts the cursor at its end. A rune that the area cannot hold goes away, and Notice then says how many went away. A form checks a stored text with Holds first, because it must not change a text that the user did not edit.
func (*TextArea) View ¶
View renders at most h rows of w cells. It scrolls the rows so that the cursor row shows, and it draws the cursor with the glyphs of LineInput (cursorView). A tab shows as spaces (MultiLine).
w must be at least 5 cells. A row always holds its first cluster, and a tab takes 4 cells plus 1 for the cursor. So a narrower view can hold a row wider than w. A form gives the area a far wider box.
type TextPager ¶
type TextPager struct {
// contains filtered or unexported fields
}
TextPager scrolls one long text that a selection picks, for example the detail of a list row or the diff of a planned write. A new id starts at the top, because a new selection is a new text. The same id keeps the offset, so a refresh keeps the position.
The pager replaces a bubbles/viewport and keeps three of its rules, so every frame stays the same:
- An empty text is one empty line, and the window has at least one row.
- A line wider than the box loses its end without an ellipsis.
- The offset moves back only when it passes the last line. After the box grows, the text can end above the bottom row. A down key then keeps the offset, and an up key moves to the last full page.
The scroll state is a named field and not an embedded one. A caller then cannot reach ScrollState.Key, which does not know the third rule.
func (*TextPager) Key ¶
Key applies a movement key and reports whether the key was one. A down key keeps an offset past the bottom, which is the third rule of the type comment.
type Theme ¶
type Theme struct {
ASCII bool
Glyphs Glyphs
Header lipgloss.Style // the product name and the outer marks
HeaderMark lipgloss.Style // the channel mark between the wedges
Subtitle lipgloss.Style
TabActive lipgloss.Style
TabIdle lipgloss.Style
TabNum lipgloss.Style
Rule lipgloss.Style // unfocused borders, rules, dimmed backdrop
RuleOn lipgloss.Style // focused borders, the active tab rule
Title lipgloss.Style // item titles
Heading lipgloss.Style // upper-case section labels
Body lipgloss.Style
Muted lipgloss.Style // secondary text and labels
Faint lipgloss.Style // tertiary text, column headers, hints
Accent lipgloss.Style
Key lipgloss.Style // key names in hints
Code lipgloss.Style // selectable commands and paths
Marked lipgloss.Style // multi-selected rows
Success lipgloss.Style
Attention lipgloss.Style
Failure lipgloss.Style
Unknown lipgloss.Style
Info lipgloss.Style
Button lipgloss.Style // the label of a primary next action
Ghost lipgloss.Style // the label of a secondary next action
}
Theme holds the glyphs and styles of one session. Screens take every style from here so the console keeps one visual vocabulary.
func NewTheme ¶
NewTheme builds the session theme. lipgloss downgrades the colors to the terminal profile and drops them under NO_COLOR, so the glyphs and labels carry every state on their own.
func (*Theme) ASCIIFrame ¶
ASCIIFrame replaces the known Unicode symbols in a rendered frame when the session uses the ASCII glyph set. It is a safety net for literals that do not come from Glyphs, because a font without these symbols shows a replacement box. Escape sequences are ASCII, so the swap never changes a style.
func (*Theme) Action ¶
Action renders one next action with its key, for example "enter Apply". primary=true gives it the prominent style.
func (*Theme) Badge ¶
Badge renders a glyph and a text label in the tone color, for example "✓ current". The label keeps the meaning when color is off.
func (*Theme) Bar ¶
Bar renders a horizontal bar of w cells: the filled part in the tone color and the rest in the line color. The count beside it carries the value, so the bar is a visual aid only.
func (*Theme) Card ¶
Card renders a summary card: a short box whose title is a dim upper-case label and whose right label carries the state.
func (*Theme) Cols ¶
Cols lays out cells in fixed-width columns. Each cell is clipped with an ellipsis and padded, so a table never wraps a cell.
func (*Theme) Columns ¶
Columns renders a column chart of h rows. Each value takes two cells with a one-cell gap. The top cell of a column uses an eighth-block glyph, so small differences stay visible at a low height.
func (*Theme) Empty ¶
Empty renders a centered empty or error state: a title, an explanation, and the next valid action.
The title and the next action are the most important lines, so they stay visible when the block is taller than h. The body gives up its lines first, and its last kept line ends with an ellipsis. The next action is clipped only when it does not fit next to the title.
func (*Theme) Highlight ¶
Highlight paints a background under a rendered row and pads it to w cells. The row keeps its own foreground styles: every reset inside it sets the background again, so the fill never breaks at a styled word.
func (*Theme) Hints ¶
Hints renders key bindings as "key action" pairs for the footer.
Consecutive unavailable entries (see Unavailable) form one faint group that starts with the word n/a, for example "n/a: w write, v view". The word carries the state without color. One word for the group costs fewer cells than one word for each key.
func (*Theme) KeyHints ¶
KeyHints renders every hint by its key alone, for example "space n i d - n/a: w t v". A footer uses it as the last step before it cuts an n/a entry, so every key stays in view; the help names the action of each key.
func (*Theme) Modal ¶
func (t *Theme) Modal(o ModalOpts, sc *ScrollState, w, h int) string
Modal renders the modal of the 1a design. It draws a filled box with an accent border, a body that scrolls in sc, and the actions under a rule. It records the scroll bounds in sc, because a key handler cannot know the rendered height. The shell dims the frame and centers the block.
func (*Theme) MutedLines ¶
MutedLines renders plain body lines in the muted style.
func (*Theme) Overlay ¶
Overlay places a rendered block on a dimmed copy of base, centered in w by h cells. The base keeps its text around the block, so the user still sees where the modal came from.
func (*Theme) PositionNote ¶
PositionNote returns the plain "a–b of n" position of a scrolled window. first and last are the 1-based visible rows, and total is the row count. Callers add the style and the words around it. The ASCII glyph set gets a plain hyphen, because a view that renders outside the shell skips the frame-wide ASCII swap.
func (*Theme) RangeNote ¶
RangeNote renders the faint "3–12 of 40" position of a scrolled window. from is the 0-based first row and to the end of the window, as the list offsets give them.
func (*Theme) ScrollBox ¶
func (t *Theme) ScrollBox(o BoxOpts, body, tail []string, sc *ScrollState, keep [2]int, follow bool) string
ScrollBox renders body lines in a box that scrolls in sc, with the tail lines always visible under the body. When follow is set, the window moves so that the lines keep[0] to keep[1] show, for example the cursor group and its detail lines. A box that scrolls shows its position in the bottom border.
func (*Theme) ScrollNote ¶
ScrollNote renders the "a–b of n" position of a scrolling window, right-aligned, so hidden rows are never a surprise.
func (*Theme) ShortHints ¶
ShortHints renders the hints as Hints does, but each n/a group shows only its keys, for example "n/a: w t v". A footer that cannot hold every hint uses it, so the unavailable keys stay in view at a cost of two cells for each key.
func (*Theme) SpinnerFrame ¶
SpinnerFrame returns the activity glyph for a tick count. The count comes from state.tick, the one injectable tick of the shell, so the console does not use bubbles/spinner (input.go gives the reasons).
func (*Theme) StickyBox ¶
func (t *Theme) StickyBox(o BoxOpts, head, body, tail []string, sc *ScrollState, keep [2]int, follow bool) string
StickyBox is ScrollBox with head lines that stay above the body, for example the headline of a long operation. Only the body scrolls, and keep counts body lines. Several screens share it, so every scrolling box keeps the same rules.
type Tone ¶
type Tone int
Tone is the semantic state of a value. Every tone has a glyph and a text label as well as a color, because color alone must never carry meaning (NO_COLOR, monochrome terminals, color vision).
const ( // ToneNeutral is plain information. ToneNeutral Tone = iota // ToneSuccess is a current or healthy state. ToneSuccess // ToneAttention is an actionable problem, a pending decision, or a // stale state. ToneAttention // ToneFailure is a broken state or a failed operation. ToneFailure // ToneUnknown is missing data. It is never shown as success. ToneUnknown // ToneAccent marks the primary action or the active destination. ToneAccent // ToneUnsupported marks a capability that the console does not provide. ToneUnsupported )