Skip to content
Isotone InterfaceDesign system of Stilus, Gesso and Albumen
Theme
Highlight
Density

Isotone Interface

Isotone Interface is the desktop UI of the Isotone Graphics Suite: Stilus (vector), Gesso (raster) and Albumen (darkroom and photo manager), built in WPF for Windows 11. It is deliberately familiar to Photoshop users and grows out of Bezier, the Stilus prototype: its 2px corners, hairline dividers, glowing checked tools, rich tooltips, scrubbable number boxes and dense status bar all carry over.

Principles

  1. Content first. The image or artwork is the brightest, most colorful thing on screen. Chrome is neutral grey and recedes; color in the chrome means state, identity or status, never decoration.
  2. Photoshop-familiar. Same window anatomy (menu bar in the title bar, options bar, tool rail on the left, document tabs, docked panels on the right, status bar), same shortcuts, same brightness themes, same blue highlight, same compact density. A Photoshop user should find every tool where their hands expect it.
  3. Suite-consistent. Stilus, Gesso and Albumen share every token, control and layout rule. The only visible difference between them is the app accent in the title-bar mark, the splash, and the one primary button of a view.
  4. Dense, not cramped. 24px controls and 12px text by default, on a 4px grid, with a Comfortable density for larger or touch-adjacent screens.
  5. Every state drawn. Hover, pressed, checked, disabled and keyboard focus are designed for every control; nothing falls back to stock WPF.

Theme model

Four brightness themes

Preferences > Interface > Color theme offers four brightness themes, as Photoshop does. One token set carries all four values; Dark is the default and the first theme in tokens.json.

Themeframesurface-panelsurface-raisedsurface-fieldcanvas-surroundtext-primary
Dark (default)#282828#323232#3A3A3A#262626#1E1E1E#E3E3E3
Darkest#151515#1E1E1E#262626#121212#101010#DCDCDC
Medium Gray#454545#535353#4C4C4C#3E3E3E#3B3B3B#F5F5F5
Light#C4C4C4#D6D6D6#EBEBEB#F7F7F7#A3A3A3#1A1A1A

Layering keeps Bezier's crust, mantle and surface order, reorganized around Photoshop's anchors:

  • frame (Bezier crust): title bar with the menu bar, document tab strip, status bar and the gaps between docked panels.
  • surface-panel (mantle): panels, tool rail, options bar, the selected document tab.
  • surface-tabstrip: panel tab strips, collapsed icon strips, the hint bar.
  • surface-raised: anything that floats: menus, dropdowns, tooltips, dialogs, toasts. Always with border-popup and a shadow. In Medium Gray it is slightly darker than the panel, which keeps text and links above 4.5:1.
  • surface-field: an inset well for text and number fields (near white in Light).
  • surface-control, -hover, -pressed: button faces.
  • canvas-surround: the pasteboard, distinct from both frame and surface-panel in every theme so the document edge reads.
  • divider for 1px hairlines between sections; divider-strong for toolbar, menu and status separators; border-control for the edge that identifies a field or checkbox (3:1 on panels).

State color (Highlight) versus app accent

Two kinds of color appear in chrome, and they never swap roles.

State is the Highlight color, the same in every app: selection, keyboard focus, checked checkboxes and radios, the active tool, the highlighted menu item, slider fills, selected rows, drop targets, links. Tokens: state (solid fill that carries state-on text), state-hover, state-pressed, state-on, state-subtle (selected rows), state-tint (translucent checked-tool fill), state-line (marks that need 3:1: active tool border, slider fill, underline of the selected tab), state-text (links), and focus-ring (an alias of state-line).

App accent is identity only: Stilus cyan accent-stilus, Gesso orange accent-gesso, Albumen green accent-albumen (lighter values in the three dark themes, darker in Light). It appears on the title-bar app mark, the splash and its launch progress, and the single primary button of a view, with its label in accent-<app>-on. It never marks selection, focus or a checked state.

Examples:

  • The selected layer in Gesso is state-subtle; the dialog's OK button in the same window is accent-gesso.
  • The active Brush tool shows state-tint, a 1px state-line border and glow-state, in all three apps.
  • The highlighted item in a menu is state with state-on text; the menu bar's app mark beside it is accent-<app>.
  • Albumen's Import button is accent-albumen; the photos it selects in the grid are outlined in state-line.

Highlight color option

Preferences > Interface > Highlight color offers three values. Every state* token, and focus-ring, handle-stroke and glow-state with them, follows the choice.

OptionValuesWhy
Blue (default)the state* tokens (#1473E6 family, tuned per theme)Neutral on photographs and illustrations (few images are dominated by this blue); no clash with warning amber; the safest choice beside error red for color-blind users; clean in the Light theme; matches Photoshop, so it reads as "selected" without learning.
Isotone orangethe state-orange* tokens (Bezier's #FF6B35, darker in Light)Isotone's Bezier heritage. The dark themes set near-black text on it (state-orange-on).
Windows accent colorderived from UISettings Accent and AccentLight1-3 / AccentDark1-3, contrast-adjusted per themeMatches the rest of the user's Windows. Falls back to Blue when unavailable.

The Highlight card documents the Windows accent mapping and the WPF swap. Two cautions come with the orange option:

  • Gesso's identity orange sits close to Isotone orange. accent-gesso #F5923E and state-orange #FF6B35 differ by only 1.1 to 1.2:1 in lightness, so they cannot be told apart by lightness. Roles keep them apart: with the orange option, Gesso's primary button keeps the identity orange while selected rows use state-orange-subtle (a brown tint at least 3:1 away from the button in every theme) and focus uses state-orange-line. Blue stays Gesso's recommended Highlight.
  • Warning amber against Isotone orange. status-warning (amber, #F2C14E in Dark) is 1.6 to 1.9:1 lighter than state-orange in the dark themes and differs in hue in Light (1.25:1). Warnings always carry the alert icon and a word, so they never depend on that difference.

Status colors

status-error, status-warning, status-success, status-info, each with a -subtle fill for info bars and toast wells. They mean status only, never decoration, and always travel with an icon (error, alert, success, info) and a word. On a subtle fill the text is text-primary. Error and success are not separable by lightness alone (1.0 to 1.3:1), which is why the icon and word are mandatory. status-info is independent of the Highlight color.

Canvas colors

checker-light/checker-dark, guide, guide-smart, ants-light/ants-dark, handle-fill, artboard are the same in all themes: they sit on artwork, not chrome. handle-stroke follows the Highlight color.

Typography

Segoe UI Variable, falling back to Segoe UI and system-ui: the Windows 11 system face, so nothing ships or loads. Segoe UI Variable Display for the splash only. Mono: Cascadia Mono, then Consolas.

StyleSize / lineWeightUse
caption11 / 14400status bar, number box values, tooltip descriptions, helper lines
body12 / 16400menus, labels, rows, buttons, options bar
body-strong12 / 16600tooltip titles, the selected document tab, lead words in info bars, primary buttons
section-header11 / 14, +0.04em, capitals600panel section headers (Bezier's ALL CAPS SemiBold, in text-secondary)
title14 / 20400flyout and empty-state headings
dialog-title14 / 20600dialog titles
display46 / 56, -0.5px600splash app name only (the Suite card)
mono11 / 14400status bar coordinates, pixel readouts
mono-body12 / 16400hex values, logs

Comfortable density swaps caption, body and body-strong for caption-comfortable (12/16), body-comfortable (13/18) and body-strong-comfortable; titles stay. The type scale ships in WPF as FontSize resources named type-caption, type-body-compact, type-body-comfortable, type-title.

Text rules: sentence case for buttons, labels and messages ("Save a copy"); title case for menu items and dialog titles, following Photoshop ("Image Size", "Convert to Smart Object"); an ellipsis on commands that open a dialog. Use "you" sparingly and never "we". No exclamation marks, no emoji. Numbers use the user's culture and tabular figures in readouts; units follow values with a space in prose ("1.9 GB") and without in fields (the unit sits in its own column).

Spacing and density

A 4px grid: space-hair 2, space-1 4, space-1-5 6, space-2 8, space-3 12, space-4 16, space-6 24. Bezier's paddings stay exact: toolbars 8,4; options and status bars 12,4; hint bar 12,6; panel header 12,10; panel body 12,8; fields 8,6; tooltips 10,6.

Two densities, chosen in Preferences > Interface > UI density. Compact is the default.

Size token pairCompactComfortable
control-h-* (buttons, fields, combos)2430
control-h-dialog2830
menu-row-h-*2430
optionsbar-h-*3240
doctab-h-*2832
tool-button-* / toolrail-w-*32 / 4040 / 48
panel-tab-h-*2632
row-h-*2228
layer-row-h-*3644
statusbar-h-*2226
check-size-*1416
swatch-*1620
body text1213
icons in toolbars1620

Fixed in both: titlebar-h 32, caption-button-w 46, infobar-h 28, section-header-h 28, ruler-w 18, panel-w-default 280 (260 to 300).

Radii

Small and nearly square, from Bezier. radius-sm 2px for everything docked in the chrome (buttons, fields, checkboxes, tools, tabs, row highlights, tooltips, swatches); radius-md 4px for popups (menus, dropdowns, flyouts); radius-lg 6px for dialogs and toasts; radius-round for radio buttons, toggle switches, slider thumbs and status dots. Nothing else is rounded.

Borders and elevation

Docked chrome is flat: regions are separated by 1px divider hairlines, never by shadows or gaps wider than 1px. Shadows are only for things that float:

  • shadow-tooltip for tooltips (Bezier: blur 8, depth 2, 30%).
  • shadow-popup for menus, dropdowns and flyouts.
  • shadow-dialog for dialogs, toasts and floating panels.
  • glow-state is not elevation: it is the soft zero-depth glow of a checked tool.

Shadows are darker and tighter in the dark themes and lighter in Light. Every floating surface also has a 1px border-popup.

Motion

Bezier's timings with one curve, ease-out (cubic out):

  • duration-fast 100ms: hover and press colors, checkbox and toggle transitions, scroll bar widening, thumb scale.
  • duration-standard 200ms: menus and flyouts fading in, section expand and collapse, toasts sliding in 20px, the splash fading out when the main window is ready.
  • duration-slow 400ms: dialogs popping in from scale 0.95. The splash's travelling border glow keeps Bezier's own timing: one lap per 6 s, fading in over 300ms and out over 500ms.
  • tooltip-delay 400ms before a tooltip opens.

When Windows "Animation effects" is off (SystemParameters.ClientAreaAnimation false, or UISettings.AnimationsEnabled false), every duration is 0 and marching ants, spinners and indeterminate bars stop. Nothing in the chrome moves on its own otherwise.

Iconography

One family: Lucide geometry (ISC), in the shared icon catalog as path data. 24 viewBox, icon-stroke 1.5px at icon-sm 16px (menus, panels, options bar, rows, buttons) and icon-md 20px (tool rail), round caps and joins, strokes only. Icons are icon at rest, text-primary when hovered or active, state-on on a state fill, text-disabled when disabled. FluentIcons.Wpf, which Bezier mixed in, leaves the suite; the caption buttons draw minus, maximize, restore and x from the same catalog at stroke 1. Emoji are never icons.

This UI icon catalog (Lucide-style strokes) is separate from the app icons. The app icons of Stilus, Gesso and Albumen are Direction C, the suite tile: a shared graphite tile, the spectrum band along its foot and the app's accent glyph. They are drawn from their own SVG files, never from the catalog, and they appear in the taskbar, Start menu, installer, file associations, About dialog and the title-bar app mark (the hand-tuned -16 file); the splash is the Suite card, which carries the master icon at 136 px (see the Splash component guide). Sizes, construction, colors and rules are in the App icons section, and the files are in the App icons asset group.

Accessibility

Contrast

Every text token is checked (WCAG 2.x) against every ground its usage note names, in all four themes: 352 pairs, all passing. Text needs 4.5:1; borders that identify a control, focus rings, icons and state marks need 3:1. A selection of the results:

PairDarkDarkestMediumLight
text-primary on surface-panel10.012.27.112.0
text-primary on frame11.513.38.810.0
text-secondary on surface-panel5.96.85.57.2
text-secondary on surface-raised5.26.26.18.8
text-placeholder on surface-field4.54.65.45.0
state-on on state4.54.55.44.5
state-text on surface-panel5.36.04.94.8
state-line (= focus-ring) on surface-panel5.05.14.64.0
state-line on surface-raised4.54.65.24.8
border-control on surface-panel3.53.43.03.7
state-orange-on on state-orange6.56.57.15.7
state-orange-line on surface-panel5.05.94.63.9
accent-gesso-on on accent-gesso7.97.97.95.3
status-error on surface-panel5.16.14.74.7

text-disabled sits near 2.3 to 2.6:1 on purpose (WCAG exempts inactive controls). The state fill itself is a surface, not a mark: in Medium Gray it is only 1.4:1 against the panel, so every checked control also draws a state-line border.

Focus and keyboard

One focus ring (focus-ring, 2px, 1px outside; inset on rows), shown for keyboard focus only. F6 cycles the regions (tool rail, options bar, document, dock); Tab moves inside a region; every dialog is fully keyboard operable with Enter and Escape doing what their buttons say; menus have access keys; tool shortcuts never fire while a text field has focus. Every icon-only control has a tooltip naming the command and shortcut and an AutomationProperties.Name.

Windows high contrast

When SystemParameters.HighContrast is true, Isotone.UI loads Themes/HighContrast.xaml, which maps tokens to system colors instead of the four themes:

TokensSystemColors
frame, surface-*, canvas-surroundWindowBrush
text-primary, text-secondary, icon, border-control, divider*WindowTextBrush
text-disabledGrayTextBrush
state, state-subtle, state-tintHighlightBrush
state-onHighlightTextBrush
state-line, focus-ringHighlightBrush (drawn 2px)
state-textHotTrackBrush
buttonsControlBrush / ControlTextBrush

Accent and status fills are dropped in high contrast; status keeps its icon and word. The canvas keeps its own colors because it shows the user's content.

Scaling

Every size token is in device-independent pixels. The UI is checked at 100, 150 and 200 percent: 1px hairlines use SnapsToDevicePixels and UseLayoutRounding so they stay one device pixel, icons are vector paths, the checkerboard and handles size by display scale, not zoom, and the Comfortable density is the recommended pairing for small high-DPI laptops.

WPF implementation

Isotone.UI carries the system as resources:

Isotone.UI/
  Themes/
    (all generated from docs/design/tokens.json by scripts/generate-theme.py; never hand-edited)
    Tokens.xaml            sizes, spacing, radii, durations, font families (single values)
    Dark.xaml              color and shadow tokens, Dark values (default)
    Darkest.xaml
    MediumGray.xaml
    Light.xaml
    HighContrast.xaml      token keys mapped to SystemColors
    Highlight.Blue.xaml    Highlight overlay: Blue (default, maps state keys to the blue set)
    Highlight.Orange.xaml  Highlight overlay: Isotone orange (maps state keys to state-orange)
    Density.Compact.xaml   neutral size keys pointed at the -compact values (default)
    Density.Comfortable.xaml neutral size keys pointed at the -comfortable values
    Controls/*.xaml        one dictionary per control family (Button.xaml, Menu.xaml, NumberBox.xaml...)
  Icons/icons.json         the icon catalog
  • Brush keys are token names: <SolidColorBrush x:Key="surface-panel" Color="#323232"/>. Size tokens are sys:Double (control-h-compact), radii are CornerRadius (radius-sm), spacing is Thickness or sys:Double, durations are Duration (duration-fast), ease-out is a CubicEase with EasingMode="EaseOut".
  • Always DynamicResource for colors, so a theme or Highlight change restyles open windows without a restart. StaticResource is fine for sizes.
  • ThemeService swaps the brightness dictionary in Application.Resources.MergedDictionaries (index 1); HighlightService swaps the Highlight overlay after it (Highlight.Blue.xaml, Highlight.Orange.xaml, or a dictionary built at runtime from the Windows accent); DensityService swaps Density.Compact.xaml or Density.Comfortable.xaml, which point the neutral keys (control-h, row-h, menu-row-h...) at the -compact or -comfortable values.
  • Each app sets Isotone.App.Accent, AccentHover and AccentOn to its accent-<app> brushes once at startup.
  • Implicit styles cover every stock control a surface uses (Button, ToggleButton, RepeatButton, CheckBox, RadioButton, TextBox, PasswordBox, ComboBox, ListBox, ListView, TreeView, TabControl, Menu, ContextMenu, ToolTip, ScrollBar, ScrollViewer, Slider, ProgressBar, StatusBar, Expander, GridSplitter); FocusVisualStyle is {x:Null} everywhere and templates draw the Isotone focus ring.
  • AvalonDock gets an Isotone theme built from the same keys. No WPF-UI or other control framework.
  • A surface never hardcodes a color, size or spacing that a token names; tokens.json in this system is the source for the XAML dictionaries.

What changed from Bezier

Bezier (Stilus prototype)Isotone Interface
One pure-grey dark palette, inline in MainWindowView.xamlFour brightness themes from one token set, in Isotone.UI dictionaries
Accent broken: grey #808080 with #FF6B35 orange leftoversBlue Highlight color by default, Isotone orange (#FF6B35, tuned) and Windows accent as options; per-app identity accents kept separate
Title bar doubled: OS chrome plus a fake bar with emoji caption buttonsOne custom title bar through WindowChrome: app mark, menu bar inside it, 46 x 32 caption buttons with a red close
Two icon families (FluentIcons.Wpf and Lucide-style, stroke 2)One Lucide catalog, stroke 1.5 at 16 and 20px
Stock Menu, ContextMenu, ScrollBar, TextBox, ComboBox, Slider, TabControl, ListBox, TreeViewEvery control styled, with hover, pressed, disabled and focus states
No disabled or keyboard focus visualsOne focus ring spec; disabled states everywhere
Sizes and radii drifting (28 to 34px buttons, mixed radii)Size tokens with Compact and Comfortable pairs; radii 2, 4, 6
Error toast as an orange fillNeutral toast with a status icon and word; info bars in four severities
Kept2px radius, 1px hairlines, checked-tool tint + border + glow, rich tooltip with shortcut and 400ms delay, CompactNumberBox scrub label, context toolbar and hint bar, dense status bar with separators and mono coordinates, caps section headers, 100/200/400ms cubic-out motion

Colors

Four interface brightness themes, Photoshop style: Dark is the default, then Darkest, Medium Gray and Light. One token set; every token carries all four values. state* tokens are the Highlight color (Blue by default); accent-* tokens are app identity only.

TokenDarkDarkestMedium GrayLightUsage
frame#282828#151515#454545#c4c4c4Window frame: title bar with the menu bar, document tab strip, status bar, and the gaps between docked panels. Darker than panels in the three dark themes, darker than panels in Light too so panels read as sheets on it.
surface-panel#323232#1e1e1e#535353#d6d6d6Dock panels, the tool rail, the options bar, the active document tab. The ground most text and controls sit on.
surface-tabstrip#2b2b2b#191919#4a4a4a#cdcdcdPanel tab strips and collapsed icon strips; section expander headers inside a panel.
surface-raised#3a3a3a#262626#4c4c4c#ebebebFloating surfaces: menus, context menus, dropdown lists, tooltips, dialogs, toasts, flyouts. Always paired with border-popup and a shadow token.
surface-field#262626#121212#3e3e3e#f7f7f7Fill of text boxes, number boxes, editable combo boxes, the hex field: an inset well, darker than the panel in dark themes, near white in Light.
surface-control#454545#2e2e2e#646464#e4e4e4Button, split button, closed combo box and caption-free control faces at rest.
surface-control-hover#505050#383838#6c6c6c#f0f0f0Control faces under the pointer; caption buttons (minimize, maximize) on hover; tool rail buttons on hover.
surface-control-pressed#2a2a2a#171717#474747#c4c4c4Control faces while pressed; toggle buttons that are on but not a tool.
surface-hover#3d3d3d#282828#5c5c5c#c9c9c9Row and tab hover on panels: list, tree and layer rows, panel tabs, document tabs, menu bar titles.
canvas-surround#1e1e1e#101010#3b3b3b#a3a3a3The pasteboard around the document. Distinct from frame and panels so the edge of the image or artboard reads; never used for chrome.
ruler-surface#2b2b2b#181818#4a4a4a#cbcbcbRuler strips along the canvas top and left edges.
scrim#00000099#000000a6#0000008c#00000059Dims the window behind a modal dialog.
divider#3e3e3e#2a2a2a#626262#bcbcbcHairline 1px dividers between panel sections, rows and bars. Decorative: separation is carried by layout too, so no contrast floor.
divider-strong#4a4a4a#363636#6e6e6e#a9a9a9Separators in toolbars, the options bar, menus and the status bar (1px lines); panel group borders against the frame.
border-control#858585#707070#a3a3a3#6b6b6bThe 1px border that identifies a field, checkbox, radio, closed combo box or button against surface-panel and surface-raised (at least 3:1 on both).
border-control-hover#9a9a9a#8a8a8a#bdbdbd#595959Field and checkbox borders under the pointer.
border-popup#555555#3c3c3c#6f6f6f#9e9e9e1px edge of menus, dropdowns, tooltips, dialogs and toasts; the shadow does the lifting.
scroll-thumb#5e5e5e#4a4a4a#7c7c7c#9a9a9aOverlay scroll bar thumb at rest (thin).
scroll-thumb-hover#8a8a8a#747474#a6a6a6#6e6e6eScroll bar thumb when the bar is hovered, widened or dragged.
text-primary#e3e3e3#dcdcdc#f5f5f5#1a1a1aPrimary text and icons on frame, surface-panel, surface-tabstrip, surface-raised, surface-field, every surface-control state, surface-hover, state-subtle, state-orange-subtle, selection-inactive and the status *-subtle fills.
text-secondary#b0b0b0#a6a6a6#dadada#3f3f3fLabels, captions, section headers, units, shortcut text, status bar text and default icon strokes, on frame, surface-panel, surface-tabstrip, surface-raised, surface-field, surface-hover, ruler-surface and state-subtle.
text-disabled#6f6f6f#595959#8c8c8c#8e8e8eDisabled labels, icons and values on any surface. Exempt from contrast minimums (WCAG 1.4.3 inactive components); kept about 2:1 so it still reads as present.
text-placeholder#8c8c8c#7e7e7e#b8b8b8#6b6b6bPlaceholder text in empty fields, on surface-field (at least 4.5:1).
icon#b0b0b0= text-secondary#a6a6a6= text-secondary#dadada= text-secondary#3f3f3f= text-secondaryDefault icon stroke in menus, panels, the options bar and the tool rail (alias of text-secondary). Active or hovered icons switch to text-primary.
state#1473e6#1473e6#1267d0#1473e6Solid state fill carrying state-on text: highlighted menu and list item, checked checkbox, selected radio dot ring fill, toggle switch on, the selected item of a dropdown, selected document tab indicator. Highlight color Blue (default). Preferences > Interface > Highlight color swaps every state token for its state-orange twin (Isotone orange) or for values derived from the Windows accent; see README, Theme model.
state-hover#0d66d0#0d66d0#0f5fc0#0d66d0state fill under the pointer or with keyboard highlight moving across it.
state-pressed#0a57b4#0a57b4#0b52a8#0a57b4state fill while pressed.
state-on#ffffff#ffffff#ffffff#ffffffText, check marks and icons on state, state-hover and state-pressed (at least 4.5:1).
state-subtle#25415f#1d3553#3a5f8c#bdd5f3Selected rows in lists, trees and the Layers panel while their panel has focus; text-primary reads on it.
state-tint#1473e633#1473e640#1473e640#1473e62eTranslucent fill of a checked tool, checked toggle button and the drag target band (the Bezier signature), always with a 1px state-line border.
state-line#56a5ff#3d8ff0#9fcdff#0f63c9State marks that must reach 3:1 on panels, raised surfaces and fields: active tool border, slider fill, drop insertion line, selected tab underline, the active ruler marker. Highlight color Blue (default). Preferences > Interface > Highlight color swaps every state token for its state-orange twin (Isotone orange) or for values derived from the Windows accent; see README, Theme model.
state-text#5aabff#4d9dfa#a9d3ff#0a57b4Links and state-colored text on surface-panel, surface-raised and surface-field (at least 4.5:1).
focus-ring#56a5ff= state-line#3d8ff0= state-line#9fcdff= state-line#0f63c9= state-lineKeyboard focus ring: 2px solid, 1px outside the control (inset on rows). Follows the Highlight color because it aliases state-line. At least 3:1 on every surface it lands on.
selection-inactive#464646#303030#666666#b4b4b4Selected rows while their panel does not have keyboard focus; text-primary reads on it.
state-orange#ff6b35#ff6b35#ff7a47#b83d0bOrange twin of state. Isotone orange Highlight option (Bezier #FF6B35 heritage); used only when Preferences > Interface > Highlight color is Isotone orange, in place of the matching state token.
state-orange-hover#ff824f#ff824f#ff8f60#a33508Orange twin of state-hover. Isotone orange Highlight option (Bezier #FF6B35 heritage); used only when Preferences > Interface > Highlight color is Isotone orange, in place of the matching state token.
state-orange-pressed#e85a24#e85a24#f06a36#8e2e06Orange twin of state-pressed. Isotone orange Highlight option (Bezier #FF6B35 heritage); used only when Preferences > Interface > Highlight color is Isotone orange, in place of the matching state token.
state-orange-on#141414#141414#141414#ffffffText and glyphs on state-orange fills: near black in the dark themes, white in Light (at least 4.5:1). Isotone orange Highlight option (Bezier #FF6B35 heritage); used only when Preferences > Interface > Highlight color is Isotone orange, in place of the matching state token.
state-orange-subtle#5a3525#44261a#7a4a36#f4cdb9Orange twin of state-subtle (selected rows). Isotone orange Highlight option (Bezier #FF6B35 heritage); used only when Preferences > Interface > Highlight color is Isotone orange, in place of the matching state token.
state-orange-tint#ff6b3529#ff6b3533#ff6b3538#b83d0b24Orange twin of state-tint (checked tool fill). Isotone orange Highlight option (Bezier #FF6B35 heritage); used only when Preferences > Interface > Highlight color is Isotone orange, in place of the matching state token.
state-orange-line#ff7a47#ff6b35#ffb899#b83d0bOrange twin of state-line and focus-ring. Isotone orange Highlight option (Bezier #FF6B35 heritage); used only when Preferences > Interface > Highlight color is Isotone orange, in place of the matching state token.
state-orange-text#ff8a5c#ff7a47#ffc2a8#a33508Orange twin of state-text. Isotone orange Highlight option (Bezier #FF6B35 heritage); used only when Preferences > Interface > Highlight color is Isotone orange, in place of the matching state token.
accent-stilus#29c5e6#29c5e6#29c5e6#00758cStilus cyan (the pen nib). Identity only: logo mark, title-bar app mark, splash, launch progress and the single primary button of a view. Never selection, focus or checked state.
accent-stilus-hover#52d2ed#52d2ed#52d2ed#00687cStilus primary button under the pointer.
accent-stilus-on#0f1416#0f1416#0f1416#ffffffLabel and icon on an accent-stilus fill.
accent-gesso#f5923e#f5923e#f5923e#b04f00Gesso orange (the paintbrush). Identity only: logo mark, title-bar app mark, splash, launch progress and the single primary button of a view. Never selection, focus or checked state. Sits near state-orange in hue: when the orange Highlight option is on, Gesso still keeps identity and state in separate roles.
accent-gesso-hover#f7a660#f7a660#f7a660#9a4500Gesso primary button under the pointer.
accent-gesso-on#1a1410#1a1410#1a1410#ffffffLabel and icon on an accent-gesso fill.
accent-albumen#4cc47a#4cc47a#4cc47a#1b7a3dAlbumen green (the aperture). Identity only: logo mark, title-bar app mark, splash, launch progress and the single primary button of a view. Never selection, focus or checked state.
accent-albumen-hover#6ed092#6ed092#6ed092#166a34Albumen primary button under the pointer.
accent-albumen-on#0f1612#0f1612#0f1612#ffffffLabel and icon on an accent-albumen fill.
status-error#ff7b72#ff6e64#ffbab4#ad2418Error text and icons (with an icon and a word, never color alone) on surface-panel, surface-raised, surface-field and status-error-subtle; out-of-range field borders.
status-error-subtle#4a2826#3a1d1b#6d4441#f7d8d5Error info bar and toast icon well; text-primary reads on it.
status-warning#f2c14e#f0b93a#ffdb8a#7a5000Warning text and icons (amber, lighter and yellower than state-orange so the two never read as one) on surface-panel, surface-raised and status-warning-subtle.
status-warning-subtle#463c22#352c15#6a5c3a#f6e7c0Warning info bar fill; text-primary reads on it.
status-success#5fd08a#52c67e#a6e8bd#166628Success text and icons (with a check icon and a word) on surface-panel, surface-raised and status-success-subtle.
status-success-subtle#233f2e#16301f#40624d#d3eedbSuccess info bar fill; text-primary reads on it.
status-info#6cb4ff#5aa8ff#b0d6ff#0a57b4Informational text and icons on surface-panel, surface-raised and status-info-subtle. Independent of the Highlight color.
status-info-subtle#233a54#172a40#3f5a78#d6e6f8Info bar and hint bar fill; text-primary reads on it.
caption-close-hover#c42b1c#c42b1c#c42b1c#c42b1cClose caption button on hover (Windows 11 red), every theme.
caption-close-pressed#b22a1b#b22a1b#b22a1b#b22a1bClose caption button while pressed.
caption-close-on#ffffff#ffffff#ffffff#ffffffThe close glyph on caption-close-hover and caption-close-pressed.
checker-light#ffffff#ffffff#ffffff#ffffffLight squares of the transparency checkerboard (16px tiles at 100% zoom); the same in every theme so transparency reads the same.
checker-dark#cccccc#cccccc#cccccc#ccccccDark squares of the transparency checkerboard.
guide#00c8ff#00c8ff#00c8ff#00c8ffRuler guides drawn over the artwork, 1px, same in every theme.
guide-smart#ff3ddc#ff3ddc#ff3ddc#ff3ddcSmart guides and snapping hints (magenta), 1px.
ants-light#ffffff#ffffff#ffffff#ffffffLight dashes of the marching-ants selection outline.
ants-dark#000000#000000#000000#000000Dark dashes of the marching-ants selection outline (4px dashes, alternating with ants-light).
handle-fill#ffffff#ffffff#ffffff#ffffffTransform and bounding-box handle fill (7px squares).
handle-stroke#1473e6= state#1473e6= state#1267d0= state#1473e6= stateTransform handle and bounding-box stroke; follows the Highlight color.
artboard#ffffff#ffffff#ffffff#ffffffDefault artboard and new-document background in Stilus.

Type

FamilyStack
--font-sans"Segoe UI Variable Text", "Segoe UI Variable", "Segoe UI", system-ui, sans-serif
--font-display"Segoe UI Variable Display", "Segoe UI Variable", "Segoe UI", system-ui, sans-serif
--font-mono"Cascadia Mono", Consolas, ui-monospace, monospace

Interface (Compact)

The default density. Windows system faces: nothing to load. Segoe UI Variable picks its Small optical size under 14px on its own.

caption11px / 14px, 400
W 1920 px H 1080 px
Captions, status bar text, number box values, tooltip descriptions, shortcut text in tooltips.
body12px / 16px, 400
Layer 1 copy
Menu items, field labels, list and layer rows, buttons, options bar.
body-strong12px / 16px, 600
Brightness/Contrast
Tooltip titles, active document tab name, the key word in an info bar message.
section-header11px / 14px, 600, 0.04em
APPEARANCE
Panel section headers and panel tab labels in the Bezier style: set in capitals (WPF: Typography.Capitals="AllCapitals" or upper-cased text), text-secondary.
title14px / 20px, 400
Untitled-1 @ 66.7% (RGB/8)
Flyout and empty-state headings; the Home screen list headings.
dialog-title14px / 20px, 600
Image Size
Dialog titles.

Interface (Comfortable)

The Comfortable density swaps caption and body for these; titles stay.

caption-comfortable12px / 16px, 400
W 1920 px H 1080 px
caption in Comfortable density.
body-comfortable13px / 18px, 400
Layer 1 copy
body in Comfortable density.
body-strong-comfortable13px / 18px, 600
Brightness/Contrast
body-strong in Comfortable density.

Display

display46px / 56px, 600, -0.5px
Gesso
The app name on the Suite card splash only (docs/design/components/Splash/README.md).

Mono

mono11px / 14px, 400
X 1204.5 Y 388.0
Cursor coordinates in the status bar, hex values, pixel readouts in the Info panel.
mono-body12px / 16px, 400
#1473E6
Hex field value, script and log views.

Spacing

4px grid. Compact paddings come from the Bezier source (toolbar 8,4; options and status bars 12,4; panel header 12,10; panel body 12,8; field 8,6 horizontal 6 in number boxes; tooltip 10,6).

TokenValueSampleUsage
space-hair2pxBetween adjacent tool rail buttons; checkbox-to-glyph inset; icon nudges.
space-14pxIcon-to-label gap; vertical padding of bars; gap between options bar controls in a group.
space-1-56pxHorizontal padding inside number boxes and tooltips (vertical); field vertical padding.
space-28pxField and row horizontal padding; toolbar padding; gap between buttons; property row spacing.
space-312pxPanel body and panel header horizontal padding; options bar and status bar padding; status bar separator margins.
space-416pxDialog padding (sides); toast padding; gap between dialog groups.
space-624pxDialog top and bottom padding; gap between dialog sections.

Radius

Small and square-ish, from Bezier: 2px on everything that sits in the chrome, 4px on anything that pops up, 6px on dialogs and toasts.

TokenValueSampleUsage
radius-sm2pxButtons, fields, checkboxes, tool buttons, tabs, list row highlights, swatches, tooltips.
radius-md4pxMenus, context menus, dropdown lists, flyouts, popovers.
radius-lg6pxDialogs and toasts.
radius-round9999pxRadio buttons, toggle switch track and thumb, the slider thumb, status dots.

Shadows

Shadows only on floating surfaces: tooltips, menus and dropdowns, dialogs and toasts. Docked chrome is flat and separated by hairlines. Glows mark a checked tool.

shadow-tooltip
  • Dark 0 2px 8px #0000004d
  • Darkest 0 2px 8px #00000066
  • Medium Gray 0 2px 8px #00000040
  • Light 0 2px 8px #00000029

Tooltips (Bezier: blur 8, depth 2, opacity 0.3).

shadow-popup
  • Dark 0 4px 16px #00000073
  • Darkest 0 4px 16px #0000008c
  • Medium Gray 0 4px 16px #00000059
  • Light 0 4px 14px #00000038

Menus, context menus, dropdown lists, flyouts.

shadow-dialog
  • Dark 0 12px 40px #00000099
  • Darkest 0 12px 40px #000000b3
  • Medium Gray 0 12px 40px #00000073
  • Light 0 12px 32px #00000047

Dialogs and toasts (Bezier toast: blur 20).

glow-state
  • Dark 0 0 8px #1473e680
  • Darkest 0 0 8px #1473e699
  • Medium Gray 0 0 8px #1473e673
  • Light 0 0 6px #1473e659

Soft zero-depth glow of a checked tool (Bezier: blur 8, opacity 0.5); widen to blur 10, opacity 0.6 on hover. Follows the Highlight color.

glow-state-orange
  • Dark 0 0 8px #ff6b3580
  • Darkest 0 0 8px #ff6b3599
  • Medium Gray 0 0 8px #ff6b3573
  • Light 0 0 6px #b83d0b59

glow-state when Highlight color is Isotone orange.

Sizes

Single values; density pairs are named -compact and -comfortable. Compact is the default (Photoshop density).

TokenValueSampleUsage
control-h-compact24pxButtons, fields, number boxes, combo boxes in toolbars, the options bar and panels (Compact).
control-h-comfortable30pxThe same controls in Comfortable density.
control-h-dialog28pxButtons and fields inside dialogs (Compact); Comfortable uses control-h-comfortable.
titlebar-h32pxTitle bar with the menu bar and caption buttons, both densities.
caption-button-w46pxMinimize, maximize and close caption buttons (46 x 32, Windows 11).
menu-row-h-compact24pxMenu and context menu rows (Compact).
menu-row-h-comfortable30pxMenu rows (Comfortable).
menu-w-min200pxMinimum menu width; shortcut column right aligned.
optionsbar-h-compact32pxOptions bar (context toolbar) height (Compact).
optionsbar-h-comfortable40pxOptions bar height (Comfortable).
infobar-h28pxInfo or hint bar under the options bar.
doctab-h-compact28pxDocument tab strip (Compact).
doctab-h-comfortable32pxDocument tab strip (Comfortable).
doctab-w-max240pxMaximum document tab width; names truncate with an ellipsis in the middle.
tool-button-compact32pxTool rail button, square (Compact).
tool-button-comfortable40pxTool rail button (Comfortable).
toolrail-w-compact40pxTool rail width, one column (Compact).
toolrail-w-comfortable48pxTool rail width (Comfortable).
panel-w-min260pxRight dock minimum width.
panel-w-default280pxRight dock default width.
panel-w-max300pxRight dock default maximum when not resized by the user.
panel-tab-h-compact26pxPanel tab strip (Compact).
panel-tab-h-comfortable32pxPanel tab strip (Comfortable).
panel-iconstrip-w36pxCollapsed panel icon strip width.
section-header-h28pxCollapsible section header inside a panel.
row-h-compact22pxList, tree and property rows (Compact).
row-h-comfortable28pxList, tree and property rows (Comfortable).
layer-row-h-compact36pxLayers panel row (Compact) with a 28px thumbnail.
layer-row-h-comfortable44pxLayers panel row (Comfortable) with a 36px thumbnail.
statusbar-h-compact22pxStatus bar (Compact).
statusbar-h-comfortable26pxStatus bar (Comfortable).
ruler-w18pxRuler thickness, top and left.
icon-sm16pxIcons in menus, panels, the options bar, list rows and buttons.
icon-md20pxIcons on the tool rail and in the Comfortable options bar.
icon-stroke1.5pxIcon stroke width at 16 and 20px (round caps and joins).
check-size-compact14pxCheckbox and radio box (Compact).
check-size-comfortable16pxCheckbox and radio box (Comfortable).
toggle-w32pxToggle switch track width (track 16px tall).
slider-track-h2pxSlider track thickness.
slider-thumb10pxSlider thumb diameter (12px Comfortable).
scrollbar-w-rest4pxOverlay scroll bar thumb width at rest.
scrollbar-w-hover10pxScroll bar width while hovered or dragged (arrows appear).
swatch-compact16pxSwatch grid cell (Compact), 2px gap.
swatch-comfortable20pxSwatch grid cell (Comfortable).
color-chip24pxForeground and background color chips on the tool rail (offset by 10px).
focus-ring-w2pxFocus ring stroke.
handle-size7pxTransform handle square.
checker-tile8pxCheckerboard square at 100% (a 16px repeat of two tiles).
type-caption11pxcaption size, for templates that set size alone.
type-body-compact12pxbody size (Compact).
type-body-comfortable13pxbody size (Comfortable).
type-title14pxtitle and dialog-title size.

Motion

Bezier AnimationHelper timings with a cubic ease out. Every animation is skipped (0ms) when Windows "Animation effects" is off (SystemParameters.ClientAreaAnimation false) or prefers-reduced-motion is set. Hover or focus a sample to play it.

TokenValueSampleUsage
duration-fast100msHover and press color changes, checkbox and toggle transitions, scroll bar widening.
duration-standard200msMenus and flyouts fading in, panel collapse and expand, toasts sliding in 20px.
duration-slow400msDialogs popping in from scale 0.95, splash transitions.
tooltip-delay400msHover time before a rich tooltip opens; 0ms while moving between tools once one is open.
ease-outcubic-bezier(0.33, 1, 0.68, 1)The one easing curve (WPF CubicEase EasingMode=EaseOut).

Shell layout

Every Isotone document window has the same anatomy, top to bottom and left to right. A feature adds to it; it never invents a second one. Sizes are Compact, with Comfortable in parentheses.

┌───────────────────────────────────────────────────────────────────────────────────────┐
│ [■] File Edit Image Layer Select Filter View Window Help               ─   □   ✕    │ title bar 32, frame
├───────────────────────────────────────────────────────────────────────────────────────┤
│ [brush ▾] │ Size 24 px  Hard 80 % │ Mode Normal ▾  Opacity 100 %  Flow 65 %  [≈]     │ options bar 32 (40), surface-panel
├───────────────────────────────────────────────────────────────────────────────────────┤
│ (i) Brush: Click to paint. Shift-click paints a straight line.                         │ hint bar 28, surface-tabstrip (optional)
├────┬──────────────────────────────────────────────────────────────┬───────────────────┤
│    │ Harbor at dusk.psd @ 66.7% (RGB/8) * │ Untitled-1 @ 100%  │ │ Properties│Adjust  │ doc tabs 28 (32) frame │ panel tabs 26
│ ▣  ├──────────────────────────────────────────────────────────────┤  APPEARANCE        │
│ ▢  │ ruler 18                                                     │  TRANSFORM         │
│ ◌  │   ┌───────────────────────────────┐                          ├───────────────────┤
│ ✂  │   │                               │                          │ Layers│Channels    │
│ ── │   │          document             │     canvas-surround      │  Normal ▾  100 %   │
│ ✎  │   │                               │                          │  ◉ ▦ Title         │
│ ⌫  │   └───────────────────────────────┘                          │  ◉ ▦ Retouch       │
│ …  │                                                              │  ◉ ▦ Background [L]│
│ ■□ │                                                              │                   │
├────┴──────────────────────────────────────────────────────────────┴───────────────────┤
│ ● Ready │ 2 objects selected │ RGB │ Snap on          X 1204.5 Y 388.0 │ 66.7% │ GPU  │ status bar 22 (26), frame
└───────────────────────────────────────────────────────────────────────────────────────┘
  tool rail 40 (48)                                                    right dock 280 (260 to 300)

(The diagram uses text glyphs as placeholders; the product draws catalog icons.)

Regions

RegionSizeTokensNotes
Title bartitlebar-h 32frameApp mark (40px zone), menu bar, drag area, caption buttons caption-button-w 46. See Window chrome.
Options baroptionsbar-h-compact 32 (40)surface-panel, divider belowActive tool's settings. See Options bar.
Hint barinfobar-h 28surface-tabstripOptional (View > Show Hints). Info bars for status stack here too.
Tool railtoolrail-w-compact 40 (48)surface-panel, divider rightOne column of 32px (40px) tools, groups separated, color chips at the bottom. Can float or switch to two columns (Photoshop's double arrow) when the window is shorter than the rail.
Document tabsdoctab-h-compact 28 (32)frameOne per document; selected tab is surface-panel with a 2px state-line top edge.
Rulersruler-w 18ruler-surfaceToggle with Ctrl+R.
Canvasthe restcanvas-surroundThe only region with saturated color: the user's content.
Right dockpanel-w-default 280 (panel-w-min 260 to panel-w-max 300, user resizable)panels surface-panel on frame with 1px gapsPanel groups stacked vertically, each with a tab strip; collapsible to a panel-iconstrip-w 36px icon strip.
Status barstatusbar-h-compact 22 (26)frame, divider aboveSee Status bar.

Minimum window size 1024 x 640; default 1400 x 900 (Bezier's), restored per app from settings.

Per app

Stilus (vector)

  • Menus: File, Edit, Object, Path, Type, Select, View, Window, Help.
  • Tool rail: Selection, Direct Selection, Pen (group: Pen, Add Anchor, Delete Anchor, Convert), Type, Rectangle (group: shapes), Line, Pencil, Eyedropper, Artboard, Hand, Zoom; fill and stroke chips replace foreground/background.
  • Options bar: with nothing selected, the document W/H and units; with a selection, X, Y, W, H, rotation, and the object's fill and stroke (Bezier's context toolbar).
  • Dock: Properties (Appearance, Transform), Layers (object tree), Artboards, Swatches, History.
  • Canvas: white artboard pages on canvas-surround; smart guides in guide-smart.

Gesso (raster)

  • Menus: File, Edit, Image, Layer, Select, Filter, View, Window, Help.
  • Tool rail in Photoshop's order: Move, Marquee, Lasso, Quick Selection / Magic Wand, Crop, Eyedropper | Healing, Brush, Clone Stamp, History Brush, Eraser, Gradient / Paint Bucket, Blur, Dodge | Pen, Type, Path Selection, Shape | Hand, Zoom | color chips, Quick Mask.
  • Dock (Photoshop's default arrangement): Color / Swatches, Properties / Adjustments, Layers / Channels / Paths, History.
  • Canvas: transparency shows the checkerboard at checker-tile 8px.

The previous Gesso layout (Layers on the left, Properties on the right) moves to this single right dock.

Albumen (darkroom and photo manager)

  • Two workspaces switched by tabs in the title bar area after the menus: Library and Develop (Lightroom Classic's modules), each keeping the same regions.
  • Library: left dock (folders and collections, a List and tree) instead of the tool rail; grid of thumbnails in the canvas region on canvas-surround; right dock with Metadata and Keywords; a filmstrip 96px tall above the status bar on frame.
  • Develop: tool rail with Crop, Spot Removal, Red Eye, Masking, Before/After; right dock with the Histogram and the develop panels as sections (Basic, Tone Curve, HSL, Detail, Lens, Effects) using Sliders paired with NumberBoxes.
  • Selected thumbnails use a 2px state-line outline and state-subtle cell fill; the Import button is Albumen's primary (accent-albumen).

Splash and Home

  • Home (no document open): the canvas region shows New and Open (New is the primary button), recent documents as a list with 96px thumbnails, and nothing else.
  • Splash: the Suite card (operator decision 2026-09-27), built in XAML so the version, status and progress are live; <app>-splash.svg is its reference design and a marketing image, never shown by the app. The full spec is the Splash component guide (components/Splash/README.md); the table below is its summary.

Splash spec

AspectSpec
Size640 x 360 DIPs, radius 8, centred on the monitor that holds the cursor; no title bar, not in the taskbar
Cardvertical gradient #303136 to #1A1B1E, a 1px inner highlight of white at 8 percent; the same in every brightness theme
Layout gridicon column x 56 to 192 centred on y 160; text column from x 230 to x 610; text positions are baselines
Iconthe Direction C master at 136 x 136, x 56, y 92, over a radial halo of accent-<app> at 20 percent (centre 128, 160, radius 150)
App nameSegoe UI Variable Display 46px semibold, letter spacing -0.5px, #F4F4F5, x 228, baseline 148
Role16px regular #B7B8BD, baseline 178 ("Vector editor", "Raster and photo editor", "Digital darkroom and photo manager")
Suite and version13px regular #8C8D93, baseline 212: "Isotone Graphics Suite · Version 0.1.0", the dot in #6C6D73
StatusSegoe UI Variable Text 12px #A3A4AA, baseline 272, live from startup ("Loading tools…", "Loading brushes…", "Opening the catalog…")
Progress340 x 3 track #3A3B41 at x 230, y 284, radius 1.5; fill accent-<app>, determinate, advanced by the startup steps
Copyright11px #6E6F75, right-aligned at x 610, baseline 312: "© 2026 Rizonetech (Pty) Ltd · Free and open source (GPL-3.0)"
Bandthe spectrum as a gentle wave along the bottom edge (the seven app icon stops), with a 1.5px white crest at 35 percent
GlowBezier's BorderGlowAnimator in accent-<app>: a 1.5px highlight travelling around the edge, one lap per 6 s while loading, fading in over 300ms and out over 500ms; none when Windows animation effects are off
Timingshown from process start until the main window is ready, then fades out over duration-standard 200ms; no minimum display time and no artificial delay; closes at once when animations are off

App icons

Stilus

stilus.svg master, shown at 96
stilus-16.svg
stilus-24.svg
stilus-32.svg
Stilus Vector editor Isotone Graphics Suite · Version 0.1.0 Loading tools… © 2026 Rizonetech (Pty) Ltd · Free and open source (GPL-3.0)
stilus-splash.svg Suite card splash, reference design

Gesso

gesso.svg master, shown at 96
gesso-16.svg
gesso-24.svg
gesso-32.svg
Gesso Raster and photo editor Isotone Graphics Suite · Version 0.1.0 Loading brushes… © 2026 Rizonetech (Pty) Ltd · Free and open source (GPL-3.0)
gesso-splash.svg Suite card splash, reference design

Albumen

albumen.svg master, shown at 96
albumen-16.svg
albumen-24.svg
albumen-32.svg
Albumen Digital darkroom and photo manager Isotone Graphics Suite · Version 0.1.0 Opening the catalog… © 2026 Rizonetech (Pty) Ltd · Free and open source (GPL-3.0)
albumen-splash.svg Suite card splash, reference design

Source files: resources/icons/<app>/. The small files are hand-tuned; they are shown at their native size on the page ground.

Stilus, Gesso and Albumen share one app icon system: Direction C, the suite tile, chosen on 2026-09-27. The splash is the Suite card (operator decision 2026-09-27), a 640 x 360 graphite card that carries the master icon; its spec is the Splash component guide. Direction A, the neon art, is retired and no longer in the repository.

The app icons are separate from the UI icon catalog: catalog icons are Lucide-style strokes that draw commands and tools in the chrome, while app icons are full-color files that identify an app to Windows and to the person using it.

Family concept

Every icon is built from three layers, and each layer has one job.

  • Graphite tile. The same dark rounded square for every app, so the three read as one suite in a taskbar or a Start menu folder.
  • Spectrum band. A wave of the seven suite colors along the foot of the tile: the Isotone signature, identical in every app.
  • Accent glyph. The app's own mark in its accent color: a pen nib on an anchor path for Stilus (accent-stilus cyan), a paintbrush with scattered pixels for Gesso (accent-gesso orange), an aperture inside viewfinder corners for Albumen (accent-albumen green).

The glyph is the only thing that changes between apps; the tile and band never do.

Construction (master, 256 viewBox)

PartGeometry
Canvas256 x 256 viewBox, 8 px transparent margin on every side
Tilerect x 8, y 8, 240 x 240 (8 to 248), rx 48, vertical gradient #34353B to #1E1F23
Inner highlightrect x 9, y 9, 238 x 238, rx 47, white stroke 2 at 9 percent opacity (reads as a 1 px inner edge)
Spectrum bandpath M0 226C64 214 120 238 176 226S236 212 256 216V256H0Z, clipped to the tile, horizontal gradient from x 8 to 248
Band crestthe same curve as a stroke, white 2 px at 35 percent opacity
Glyph safe boxabout x 36 to 220, y 28 to 204, centred at (128, 116), above the band

The glyph is centred at (128, 116), not at the tile centre, so it sits optically in the middle of the graphite area above the band.

Optical balancing makes the three glyphs look the same size although their shapes differ: relative to the original drawings, the Stilus line glyph is scaled up 25 percent (group scale 1.125), Gesso 10 percent (0.990) and Albumen 8 percent (0.972). Stilus gets the most because a thin line drawing reads smallest.

Each master keeps its gradient and clip ids prefixed with the app (stilus-c-bg, gesso-c-spec...) so several icons can be inlined in one document without collisions.

Size ladder: which file at which size

Rendered sizeFileNotes
16 and 20 px<app>-16.svg16 grid, tile fills the canvas, rx 3
24 and 30 px<app>-24.svg24 grid, tile x/y 1 to 23, rx 4
32 to 40 px<app>-32.svg32 grid, tile x/y 1 to 31, rx 6
48 px and up<app>.svg (the master)48, 64, 96, 128, 256

Sizes in between are rendered from the next smaller file's grid only when it is an exact multiple (20 from 16 at 125 percent, 30 from 24, 40 from 32); never scale a small variant up past its range.

The small variants (16, 24, 32)

At taskbar and title-bar sizes an icon is recognized by its silhouette, so the small variants carry the app's main object alone, enlarged to fill the space above the band (operator decision, 2026-09-27: less detail at 32, 24 and 16).

  • Stilus: the pen nib alone (no Bezier curve, handle, or anchor nodes). The breather hole stays at 24 and 32; at 16 the nib is solid with only the slit.
  • Gesso: the paintbrush alone (no pixel squares). The light ferrule band stays at every size, since it is what makes the shape read as a brush.
  • Albumen: the six-blade aperture alone (no viewfinder corners); at 16 the blade separators are heavier so the blades stay distinct.
  • The glyph is scaled to fill a box inset from the tile (1.5 px at 16, 2.6 px at 24, 3.2 px at 32) and centered above the band.
  • The tile keeps the master's graphite gradient with a smaller corner radius (3, 4, 6), and the spectrum band is a straight bar 2, 2.5, and 3.5 px tall, clipped to the tile corners; the inner highlight and the band crest are dropped.
  • The variants are generated from the masters' glyph shapes by scripts/generate-small-icons.py, so a change to a master glyph carries through; regenerate them after editing a master.
  • Accent colors stay the same hex values as the master, so an icon reads as the same app at every size.

Colors

RoleValues
Tile (master)vertical gradient #34353B (top) to #1E1F23 (bottom)
Tile (16 to 32)flat #2B2C31
Spectrum bandstops at 0, 0.17, 0.33, 0.5, 0.67, 0.83 and 1: #FF4D6D, #FF9A3C, #FFD84A, #4CC47A, #29C5E6, #5B7CFF, #B45CFF
Stilus glyphaccent-stilus #29C5E6, light facet #8BE6F7, ferrule #1597BA, anchors white (48 px and up)
Gesso glyphaccent-gesso #F5923E, highlight #FFC98F, tuft to #FFE08A, pixels #FFD84A and warm neighbours
Albumen glyphaccent-albumen #4CC47A, light blades #9BE8B6, dark body #1B7A3D and #0B3A1C, viewfinder white

The accents are the dark-theme values of the accent-<app> tokens; the icon keeps them in every theme, because it is an image on its own tile, not chrome.

Where each is used

SurfaceSizeFile
Title-bar app mark16 px (20 px at 125 percent and up)<app>-16.svg
Taskbar24 px at 100 percent, 30 to 48 px when scaled-24, -32, master by the ladder
Start menu, pinned and all apps24 to 48 px by scaleby the ladder
Installer (Inno Setup wizard and uninstall entry)from the .icoall sizes
File associations (Explorer)16 to 256 px from the .icoall sizes
About dialog128 pxmaster
Splash (the Suite card)136 pxmaster, on the card built in XAML to the Splash component guide
Marketing and store artanythe master, or <app>-splash.svg (the Suite card reference design, 640 x 360)

The title bar is the only place in the chrome where the app icon appears; everywhere else the chrome stays neutral and the app is identified by its accent on the one primary button.

The suite icon and wordmark

The Isotone Graphics Suite has its own icon and wordmark (operator decision 2026-09-28: icon direction A, "Three Lights", and wordmark 2, with the dot of the i as the three primaries). Both are generated by scripts/build-suite-mark.py; edit the script, never the SVGs.

  • Icon (resources/icons/isotone/isotone.svg, with isotone-16.svg, -24.svg, -32.svg from scripts/generate-small-icons.py): the same graphite tile and spectrum band as the app icons, with the three app accents as overlapping lights of radius 45 whose centres sit 25 from (128, 114): Stilus cyan above, Gesso orange lower left, Albumen green lower right. Each overlap is filled with the screen mix of its colors, precomputed, so no renderer needs a blend mode; the centre, where all three meet, is near white. It identifies the suite (the suite installer, the README, the design page), never an app.
  • Wordmark (resources/brand/isotone-wordmark-on-dark.svg, -on-light.svg): "isotone" in lowercase Sora SemiBold with the dotless i, its dot a single circle filled with the three app colors blended in color-wheel order (orange, green, cyan, lower left to upper right, so no step of the blend turns grey), placed where the operator approved it (radius 6.56, 10 right of the stem centre, 41 above the baseline, at a 58 font size), over "GRAPHICS SUITE" in Sora Medium tracked 4.5. The letters are outlines, so the files never depend on an installed font; the font itself is in resources/brand/fonts/ (SIL Open Font License 1.1).
  • The wordmark stands alone: it is never locked up with the suite icon (operator decision 2026-09-28). The icon has its own places (the suite installer, the design page, social images), and each is used on its own.
  • Do not put the suite icon on an app's window, taskbar entry, or file association, and do not recolor the three lights: their order and colors are the three apps.

The Suite card splash

The splash shows the master icon at 136 px on a graphite card (640 x 360, radius 8, the same family of greys as the tile), over a soft halo of the app accent, beside the app name, its role, the suite and version line, a live status line and the launch progress in the accent, with the spectrum band as a gentle wave along the card's bottom edge (the same seven stops as the icons). The card is identical in the three apps apart from the icon, the accent and the words. <app>-splash.svg is its reference design and a marketing image; the app draws the card in XAML so the version, status and progress are live. The full spec (layout grid, colors, text styles, progress, band, glow and timing) is the Splash component guide, summarized in the Shell layout's Splash and Home.

Do and do not

  • Do use the file the ladder names for the rendered size.
  • Do keep clear space around the icon of at least one eighth of its size (the 8 px margin of the master) on every side.
  • Do place the icon as is on any theme's frame or surface-panel: the graphite tile carries its own contrast.
  • Do not recolor a glyph, tint it with the Highlight color, or swap one app's accent for another's.
  • Do not draw the master below 48 px: its band crest and highlight turn to mush; use the small variants.
  • Do not add text, a version number or a badge to the tile.
  • Do not drop or reorder the spectrum band, or change its colors per app.
  • Do not use a catalog icon (pen-tool, brush, aperture) as a stand-in for an app icon.
  • Do not use the Suite card splash as an app icon, or ship its SVG or a PNG of it as the in-app splash: the app builds the card in XAML so its text is live.

Export

PNG sizes and each app's multi-resolution .ico (16, 20, 24, 30, 32, 40, 48, 64, 128 and 256) are generated from these SVGs by the icon export script, each size taken from the file the ladder names.

Never hand-edit an exported PNG or .ico: change the SVG and export again.

The export also renders each <app>-splash.svg at 640 x 360, 960 x 540 and 1280 x 720 (1x, 1.5x and 2x) for marketing only; the apps never load them.

Source files: resources/icons/<app>/<app>.svg (master), <app>-16.svg, <app>-24.svg, <app>-32.svg and <app>-splash.svg (the Suite card reference design), the same fifteen files as the App icons asset group.

Components

Each card is the live preview from docs/design/components/<Comp>/preview.html with its guidelines. The Theme, Highlight and Density switches above apply to every preview.

Foundations

App icon

Direction C suite tile: masters, size ladder on frame and panel, do and don't

The app icons of Stilus, Gesso and Albumen: Direction C, the suite tile, a shared graphite tile with the spectrum band along its foot and the app's accent glyph, in a 256 master and hand-tuned 16, 24 and 32 variants.

The full guide (construction, colors, pixel-grid rules, export) is the App icons section of the brand book; the files are the App icons asset group.

Which file

Rendered sizeFile
16 and 20 px<app>-16.svg
24 and 30 px<app>-24.svg
32 to 40 px<app>-32.svg
48 px and up<app>.svg
Splash (the Suite card)the master at 136 px, on the card built in XAML (see Splash); <app>-splash.svg is the card's reference design and a marketing image, not an icon

Rules

  • The title-bar app mark is <app>-16.svg at 16 px (20 px at 125 percent and up), drawn as is in the 40 px app mark zone.
  • The About dialog shows the master at 128 px; taskbar, Start menu, installer and file associations take sizes from the generated .ico.
  • Never recolor the glyph, never draw the master below 48 px, never add text, never drop the band, keep clear space of one eighth of the icon size.
  • The icon keeps its own colors in every brightness theme and in high contrast; it is an image, not chrome.
  • A catalog icon (pen-tool, brush, aperture) never stands in for an app icon.

WPF

  • Window.Icon and the title-bar mark take the app's .ico generated from these SVGs; the mark picks the frame the ladder names for the current DPI (16 at 100 percent, 20 at 125 percent, 24 at 150 percent), never a scaled master.
  • AutomationProperties.Name on the title-bar mark is the app name ("Gesso").

Focus ring

One keyboard focus ring: 2px focus-ring, 1px outside; inset on rows

Shows all three Highlight options side by side, so the Highlight switch leaves it as is.

One keyboard focus indicator for the whole suite: a 2px solid focus-ring stroke. It only appears for keyboard focus, never for mouse clicks.

Spec

WhereRing
Buttons, tool buttons, caption buttons, swatches, checkbox and radio boxes, toggle tracks, slider thumbsfocus-ring-w 2px, 1px outside the element, following its radius
Text boxes, number boxes, editable combo boxesthe 1px border turns focus-ring plus a 1px inner focus-ring line, so the field does not grow
Rows (lists, trees, layers, menu items), tabs, document tabs, menu titles2px inset, drawn over the selection fill

focus-ring aliases state-line, so it follows the Highlight color. Contrast: at least 3:1 against frame, surface-panel, surface-tabstrip, surface-raised, surface-field, surface-control, surface-control-hover and ruler-surface, and against state-subtle for focused selected rows, in all four themes (checked by script, see README).

Rules

  • Never remove focus visuals; never show them on mouse focus.
  • Focus moves predictably: F6 cycles the main regions (tool rail, options bar, document, dock, status toasts); Tab moves within a region.
  • Windows high contrast: the ring uses SystemColors.HighlightBrush.

WPF

Set FocusVisualStyle="{x:Null}" in every Isotone style and draw the ring in the template (Border PART_FocusRing, Margin="-3", BorderThickness="2", CornerRadius = element radius + 2), shown by a trigger on IsKeyboardFocused (IsKeyboardFocusWithin for composite controls) combined with the attached Isotone.Focus.IsKeyboardInitiated, which tracks the last input device through InputManager.Current.PreNotifyInput.

Highlight color

Highlight color options: Blue (default), Isotone orange, Windows accent

Shows all three Highlight options side by side, so the Highlight switch leaves it as is.

The state color (selection, focus, checked controls, active tool, highlighted menu item, slider fill, selected rows, links) is a user choice in Preferences > Interface > Highlight color. Blue is the default.

Options

OptionSourceNotes
Blue (default)the state* tokensPhotoshop-like; neutral on photographs, never confused with warning amber or error red
Isotone orangethe state-orange* tokens (Bezier #FF6B35)the dark themes put near-black text on orange (state-orange-on); Light uses a darker orange with white
Windows accent colorUISettings.GetColorValue Accent, AccentLight1-3, AccentDark1-3contrast-adjusted per theme; the preview uses the Windows default #0078D4 as the example

Each option supplies the whole set: state, state-hover, state-pressed, state-on, state-subtle, state-tint, state-line, state-text, plus focus-ring, handle-stroke and glow-state, which follow.

Windows accent mapping

TokenDark, DarkestMedium GrayLight
stateAccent (AccentDark1 if state-on would fall under 4.5:1)AccentDark1AccentDark1
state-hover / state-pressedAccentDark1 / AccentDark2AccentDark2 / AccentDark3AccentDark2 / AccentDark3
state-line, focus-ringAccentLight2 (Light1 in Darkest)AccentLight3AccentDark1
state-textAccentLight2AccentLight3AccentDark2
state-subtleAccent blended 30% over surface-panel35%25% over white
state-tintAccent at 20% alpha25%18%

After mapping, each value is checked against the same pairs as the blue set (4.5:1 text, 3:1 marks); a value that misses is stepped in OKLCH lightness (lighter in dark themes, darker in Light) until it passes. state-on is white or #141414, whichever contrasts more with state.

WPF

The four brightness dictionaries hold the blue values. A fifth merged dictionary, the Highlight overlay, is swapped at runtime by HighlightService: Highlight.Blue.xaml for Blue, Highlight.Orange.xaml (each state key mapped to its state-orange brush) for Isotone orange, and for Windows accent a dictionary of brushes computed from Windows.UI.ViewManagement.UISettings (WinRT projection, available with the net11.0-windows10.0.26100.0 target). The service subscribes to UISettings.ColorValuesChanged (raised on a worker thread: marshal to the dispatcher) and rebuilds the dictionary live. If the call throws or returns no accent, it falls back to Blue and logs a Warning. SystemParameters.WindowGlassColor is not used: it reports the glass color, not the accent. Every consumer uses DynamicResource, so swapping the dictionary restyles open windows without a restart.

Icons

The one icon family: Lucide geometry, 16 and 20px, stroke 1.5

The suite draws every icon from one family: Lucide geometry (ISC license, compatible with GPL-3.0), stored as path data in the shared icon catalog. The survey found FluentIcons.Wpf mixed with Lucide-style paths; FluentIcons.Wpf leaves the suite.

Rules

  • Grid: 24 viewBox, stroke icon-stroke 1.5px at both 16 and 20px, round caps and joins, no fills (a filled shape is drawn as a closed stroke).
  • Sizes: icon-sm 16px in menus, panels, the options bar, list rows and buttons; icon-md 20px on the tool rail and in Comfortable toolbars; 12 to 14px only for chevrons and inline glyphs, with stroke 2 so they hold weight.
  • Color: icon (= text-secondary) at rest, text-primary on hover or when active, state-on on a state fill, text-disabled when disabled, a status color only next to status text. Icons never take the app accent except inside the app mark.
  • Every icon-only control has a tooltip and an AutomationProperties.Name; decorative icons are hidden from UIA.
  • New icons: take Lucide's if one exists; otherwise draw one on the same grid (2px padding, 1.5 stroke) and add it to the catalog with a name and a note.
  • Tool icons match the tool, not the command (Photoshop's names for Photoshop tools).
  • The app marks (pen nib, paintbrush, aperture) are the apps' own icon files, not catalog icons.

Catalog (preview names)

The preview renders every icon the system currently documents. Names are the catalog keys: pointer (Move tool), marquee, lasso, wand, crop, pipette, brush, pencil, eraser, stamp, bucket, pen-tool, type, square, circle, hand, zoom-in, zoom-out, plus panel, file, edit, status and window glyphs.

WPF

Isotone.UI.Icons: an IconCatalog singleton loaded from icons.json (name to path data, source-generated JSON context), an Isotone.Icon control (Path with Stretch="Uniform" inside a 24-unit Viewbox, StrokeThickness scaled so 1.5 at 24 stays 1.5 device-independent pixels at 16 and 20, StrokeStartLineCap/EndLineCap/LineJoin round), and a markup extension {ph:Icon brush}. Foreground drives the stroke through TemplateBinding.

Actions

Button

Default, primary, subtle, icon, split and toggle, in every state

Command buttons: default, primary (the app accent, once per view), subtle, icon-only, split and toggle.

Anatomy and sizes

VariantSizeTokens
Defaultcontrol-h-compact 24px (dialogs control-h-dialog 28px, Comfortable 30px), min 64px wide (80px in dialogs), 12px side padding, radius-smsurface-control, 1px divider-strong, label body text-primary
Primaryas default, body-strong labelaccent-<app> fill and border, label accent-<app>-on, hover accent-<app>-hover
Subtleas default, no fill or borderhover surface-hover
Iconsquare, 16px iconicon, hover icon text-primary
Splitmain part plus a 20px arrow part divided by 1pxarrow opens a Menu of related commands
Toggleusually icon-only, subtleon: state-tint fill, 1px state-line border

Rules

  • One primary button per view: the dialog's commit button, the Home screen's New, Albumen's Import. It is the only place chrome shows the app accent beside the title-bar mark.
  • Labels are verbs in title case in menus and sentence case on buttons: "Save a copy", "Export". OK and Cancel stay short.
  • Icon-only buttons always have a tooltip naming the command and shortcut and an AutomationProperties.Name.
  • Destructive commands are default buttons with a verb that says what goes ("Delete 12 photos"), never red fills.

States

Rest, hover (surface-control-hover), pressed (surface-control-pressed), focus (2px focus-ring 1px outside), disabled (surface-control fill, divider border, text-disabled label; primary loses its accent). Toggle adds on and on+hover.

Keyboard

Tab to focus; Enter and Space activate. In dialogs the primary button is IsDefault (Enter) and Cancel is IsCancel (Escape). A split button's arrow opens with Alt+Down.

WPF

Styles Isotone.Button (implicit), Isotone.PrimaryButton, Isotone.SubtleButton, Isotone.IconButton, Isotone.SplitButton (a Control with PART_Main and PART_Drop + ContextMenu), and ToggleButton style Isotone.ToggleIconButton. Template: Border PART_Chrome with CornerRadius="{StaticResource radius-sm}", ContentPresenter; states via VisualStateManager CommonStates and FocusStates (a separate Border PART_FocusRing 1px outside, visible on IsKeyboardFocused, never on mouse focus). FocusVisualStyle="{x:Null}" so the default dotted rectangle never shows. The primary style binds its brushes to Isotone.App.Accent, set once per app.

Inputs

Checkbox

Unchecked, checked, indeterminate across states; the three Highlight options

Shows all three Highlight options side by side, so the Highlight switch leaves it as is.

A two- or three-state option. The box fills with the Highlight color when checked.

Anatomy

PartSizeTokens
Boxcheck-size-compact 14px (Comfortable 16px), radius-smsurface-field, 1px border-control
Glyph12px check or minus, stroke 2.5state-on
Label8px after the box, bodytext-primary

States

RestHoverPressedDisabledFocus
Uncheckedsurface-field + border-controlborder border-control-hoverfill surface-control-pressedno fill, text-disabled border and labelfocus ring 1px outside the box
Checkedstate fill, state-line border, check state-onstate-hoverstate-presseddivider-strong fill, glyph text-disabledring
Indeterminateas checked with a minusstate-hoverstate-pressedas checked disabledring

The state-line border keeps the checked box visible in Medium Gray, where the state fill alone is only 1.4:1 against the panel; the check itself holds 4.5:1 on the fill in every theme.

Highlight color

Checked boxes follow Preferences > Interface > Highlight color: Blue (default), Isotone orange (state-orange with a near-black check in the dark themes), or the Windows accent. The preview shows all three.

Keyboard

Space toggles; indeterminate is reachable only when the checkbox represents a mixed selection (clicking it sets all to checked). The label is part of the hit target.

WPF

CheckBox style Isotone.CheckBox (implicit). Template: Grid with Border PART_Box (CornerRadius 2), Path PART_Check and Rectangle PART_Indeterminate, ContentPresenter with Margin="8,0,0,0". IsThreeState only for mixed selections. Visual states CheckStates (Checked, Unchecked, Indeterminate) plus CommonStates and FocusStates; transitions duration-fast.

Combo box and dropdown

Closed states, open list, editable combo

Choose one value from a list (blend modes, resample methods, fonts). The editable form also accepts typed values.

Anatomy

PartSizeTokens
Closed boxcontrol-h-compact 24px, 8px left padding, 12px chevron with 4px right padding, radius-smsurface-control, 1px border-control, text-primary, chevron icon
Editable boxsurface-field text area plus a 20px drop part divided by 1px divider-strongas TextBox
Listat least the box width, radius-md, 4px vertical padding, max 16 rows then scrollsMenu surface: surface-raised, border-popup, shadow-popup
Itemmenu-row-h-compact 24px, 16px check columntext-primary; selected shows a check

States

  • Closed: rest, hover (surface-control-hover, border-control-hover), open (border focus-ring), focus (ring 1px outside), disabled (no fill, divider-strong border, text-disabled).
  • Items: highlighted state + state-on; selected shows the check (and is highlighted when the list opens); disabled text-disabled; separators group related modes (as Photoshop groups blend modes).

Keyboard

Alt+Down or F4 opens; Up and Down change the value without opening (blend modes preview live, which Photoshop users expect); typing jumps by prefix; Enter picks; Escape closes and reverts. Editable: type, Enter commits.

WPF

ComboBox style Isotone.ComboBox (implicit) with parts PART_EditableTextBox, PART_Popup (AllowsTransparency), ToggleButton for the drop part; ComboBoxItem style shares the MenuItem look. IsEditable switches the template via a trigger. VirtualizingStackPanel for long lists (fonts).

Number box

Bezier CompactNumberBox: drag the label to scrub

Bezier's CompactNumberBox: a numeric field whose label is a scrub handle. Drag left or right on the label to change the value, as in Photoshop's scrubby sliders.

Anatomy

PartSizeTokens
Boxcontrol-h-compact 24px, width set by the host (72 to 120px), radius-smsurface-field, 1px border-control
Scrub zonelabel (X, W, Opacity) or a grip of two 1px lines at 50%, 6px left padding, 3px gaptext-secondary, cursor SizeWE
Valueright aligned, caption, tabular figurestext-primary
Unit3px after the valuetext-secondary
Spinners (optional)14 x 10px each, 1px divider-strong left edge8px chevrons in icon

Scrubbing

  • 1 unit per pixel; Shift x10; Alt x0.1 (values with decimals).
  • The pointer is captured and hidden after 4px of travel and wraps at screen edges, so a long drag never stops.
  • Each drag is one undo step; the document previews live.
  • While scrubbing the label turns state-text and the border border-control-hover.

States

Rest, hover (border-control-hover), scrubbing, focus (focus-ring border plus inner line), disabled (no fill, text-disabled everywhere), out of range (status-error border and line, a helper line naming the range "0 to 100"; the last valid value is kept on commit).

Keyboard

Up and Down step by 1 (Shift 10, Alt 0.1); Page Up and Down by 10; Enter commits; Escape reverts. Math is accepted ("1920/2"), and units convert ("2in" in a px field).

WPF

Isotone.UI.Controls.NumberBox (Control, from Bezier CompactNumberBox) with dependency properties Value, Minimum, Maximum, SmallChange, LargeChange, Decimals, Label, Unit, ShowSpinners, ShowGrip. Template parts: PART_ScrubZone (Cursor="SizeWE", handles PreviewMouseLeftButtonDown and CaptureMouse), PART_TextBox, PART_Up / PART_Down (RepeatButton). Visual states CommonStates, FocusStates, ValidationStates (Valid, OutOfRange), ScrubStates (Idle, Scrubbing).

Radio button

Selected and unselected across states

One choice from a small, visible set (two to five). Use a ComboBox for more.

Anatomy

Box check-size-compact 14px circle (radius-round, Comfortable 16px), surface-field with 1px border-control; selected: state fill, state-line border, 6px state-on dot. Label body 8px after.

States

Rest, hover (border-control-hover), pressed (surface-control-pressed), disabled (text-disabled ring, dot and label; selected disabled fills divider-strong), focus (ring 1px outside the circle). Selected hover and pressed use state-hover and state-pressed.

Keyboard

The group is one tab stop landing on the selected item; arrow keys move and select; Space selects the focused item if none is.

WPF

RadioButton style Isotone.RadioButton: Ellipse PART_Ring, Ellipse PART_Dot; group with GroupName or a shared parent; put the set in a StackPanel with KeyboardNavigation.DirectionalNavigation="Cycle" and TabNavigation="Once". Tool rail buttons are RadioButtons with a different style (see Tool rail).

Slider

Track, fill, thumb and paired number box; gradient sliders

Photoshop-style slider: a thin track with a fill, a round thumb, and a paired NumberBox for exact entry. Gradient sliders show the value's color range (hue, saturation, opacity).

Anatomy

PartSizeTokens
Trackslider-track-h 2px, full width minus the thumbborder-control
Fillfrom the minimum to the thumbstate-line
Thumbslider-thumb 10px circle (12px Comfortable) with a 1px frame halotext-primary
Paired number box72px NumberBox with grip and unitsee NumberBox
Gradient slider10px ramp, radius-sm, 1px border-control inner edge, a 7px triangle thumb under itthe ramp is content (hue, saturation, alpha over the checkerboard); triangle text-primary

States

Rest; hover (thumb scales 1.2 in duration-fast); pressed or dragging (thumb state-line); focus (ring 2px outside the thumb; on gradient sliders the triangle turns focus-ring); disabled (track divider-strong, fill and thumb text-disabled).

Keyboard

Left and Down decrease, Right and Up increase by SmallChange (1); Page keys by LargeChange (10); Home and End jump to the ends. Shift+arrow uses LargeChange. The number box and slider stay in sync; dragging is one undo step.

WPF

Slider style Isotone.Slider: Track PART_Track with RepeatButtons (DecreaseRepeatButton draws the fill, IncreaseRepeatButton the track) and a Thumb template (Ellipse). IsMoveToPointEnabled="True" (click jumps, Photoshop behavior). Gradient slider: Isotone.GradientSlider with a Brush Ramp property and a Polygon thumb. Pair with a NumberBox bound two-way to the same Value.

Swatches and color

Foreground and background chips, swatch grid, color field, hex

Color selection pieces: foreground and background chips, the swatch grid, the color field with hue slider, and the hex field.

Anatomy

PartSizeTokens
FG/BG chipstwo color-chip 24px squares offset 10px, radius-sm1px text-primary edge + 1px frame halo; swap (swap) and default (square) glyphs 12 and 10px in icon
Swatch gridswatch-compact 16px cells (Comfortable 20px), 2px gap, radius-sm1px inner shade line so white and black cells keep an edge
None swatcha cell with a diagonalsurface-field with a status-error stroke
Color field176 x 112px, radius-sm, 1px border-control inner edgea 10px ring: 2px checker-light with a 1px ants-dark outline, visible on any color
Hue strip10px tall under the field, triangle thumbas Gradient slider
Hex field108px TextBox, # prefix in text-secondary, value in mono-bodyas TextBox

States

Swatch: rest, hover (1px text-primary outline 1px outside), selected (2px state-line outline 1px outside), focus (focus ring). Chips: hover shows a tooltip with the hex value; click opens the Color Picker dialog.

Keyboard

The grid is one tab stop; arrows move; Enter sets the foreground color, Alt+Enter the background; Delete removes (with undo). X swaps chips, D resets to black and white. The hex field accepts 3 or 6 digits, with or without #.

WPF

ListBox with a WrapPanel items host and ListBoxItem style Isotone.Swatch; chips are Isotone.ColorChips (Control with Foreground/Background color DPs, PART_Swap, PART_Reset). Color field: Isotone.ColorField rendering the gradient with two LinearGradientBrushes in a Grid; hue: Isotone.GradientSlider. Swatch colors are document content and are not theme resources.

Text box

Single-line text field in every state

Single-line text entry: names, paths, search. Numeric values use NumberBox.

Anatomy

PartSizeTokens
Fieldcontrol-h-compact 24px (dialogs 28px, Comfortable 30px), 8px side padding, radius-smsurface-field, 1px border-control
Textbodytext-primary; placeholder text-placeholder
Leading icon14px (search)icon
Helper or error linecaption, 4px belowtext-secondary; error status-error with the error icon

States

  • Rest; hover: border border-control-hover.
  • Focus: border focus-ring plus a 1px inner focus-ring line (2px total, inside, so fields do not grow). Text selection uses state with state-on text.
  • Disabled: no fill, divider-strong border, text-disabled text.
  • Read-only: no fill, divider-strong border, text-primary text, still focusable and selectable.
  • Error: status-error border and inner line, a message that says what is allowed ("Names can't contain / or \\"), never color alone.
  • Placeholder: shown only while empty; not a label.

Keyboard

Standard edit keys; Enter commits (in the options bar and panels also returns focus to the canvas); Escape reverts to the value at focus; Ctrl+A selects all. Single-letter tool shortcuts never fire while a field has focus.

WPF

TextBox style Isotone.TextBox (implicit): Border PART_Chrome, ScrollViewer PART_ContentHost, TextBlock PART_Placeholder (visible when Text is empty), SelectionBrush="{DynamicResource state}", SelectionTextBrush="{DynamicResource state-on}", CaretBrush="{DynamicResource text-primary}". Errors come from INotifyDataErrorInfo; Validation.ErrorTemplate is replaced by the helper line.

Toggle switch

Immediate on/off settings in Preferences

An on/off setting that applies immediately, used in Preferences and panel menus. Settings that wait for OK are checkboxes.

Anatomy

Track toggle-w 32 x 16px, radius-round, surface-field with 1px border-control; thumb 10px text-secondary, 2px inset. On: track state with state-line border, thumb state-on at the right. Label body 8px after (or before in a settings row with the label left aligned).

States

Off and on, each rest, hover (border border-control-hover, thumb text-primary; on: state-hover), disabled (text-disabled track border and thumb; on fills divider-strong), focus (ring 1px outside the track). The thumb slides in duration-fast with ease-out; no slide when animations are off.

Keyboard

Space toggles. Arrow keys do not.

WPF

ToggleButton style Isotone.ToggleSwitch (no third-party control): Border PART_Track, Ellipse PART_Thumb with a TranslateTransform animated between 0 and 16. AutomationProperties.Name is the label; UIA exposes the Toggle pattern.

Navigation

Scroll bar

Thin overlay scroll bar that widens on hover

A thin overlay scroll bar that stays out of the way and widens on hover, used in panels, lists and dialogs. The canvas uses its own scroll bars with the same look.

Anatomy and states

StateLook
Restscrollbar-w-rest 4px thumb, radius-round, scroll-thumb, 2px from the edge, no track
Hover (pointer within 10px)bar widens to scrollbar-w-hover 10px in duration-fast: track surface-tabstrip, thumb 6px scroll-thumb-hover, 8px arrow glyphs in text-secondary at both ends
Draggingthumb text-secondary
Idlefades to 0 after 1s without scrolling or hover when Windows "Always show scrollbars" is off; always visible when it is on

Minimum thumb length 24px. The bar overlays content; lists reserve 4px right padding so text never sits under the thumb.

Keyboard

Scroll bars are not tab stops; the scrolled control handles arrows, Page Up/Down, Home, End.

WPF

ScrollBar and ScrollViewer styles Isotone.ScrollBar / Isotone.ScrollViewer (implicit): the ScrollViewer template overlays PART_VerticalScrollBar and PART_HorizontalScrollBar in the same Grid cell as ScrollContentPresenter. The bar's template: Track PART_Track with a Thumb (Border with CornerRadius) and RepeatButton arrows collapsed until IsMouseOver. Read UISettings.AutoHideScrollBars for the fade.

Tabs

Panel tab strip and dialog tabs

Two tab styles: the panel tab strip (grouped panels, Photoshop style) and underline tabs for dialogs (Preferences, Export settings).

Panel tabs

panel-tab-h-compact 26px strip on surface-tabstrip; each tab 12px side padding, body, 1px divider right edge. Rest text-secondary; hover surface-hover + text-primary; selected surface-panel joined to the body (covers the strip's bottom line) + text-primary; focus inset ring. Tabs can be dragged to regroup or float (see Panel).

Dialog tabs

A row with 16px gaps over a 1px divider line; labels body, 6px top and 8px bottom padding. Rest text-secondary; hover text-primary; selected body-strong text-primary with a 2px state-line underline; disabled text-disabled (with a tooltip saying why). For more than 7 sections use a list on the left instead.

Keyboard

The tab row is one tab stop; Left and Right move and select (automatic activation); Ctrl+Tab and Ctrl+Shift+Tab switch from inside the content; Home and End jump.

WPF

TabControl styles Isotone.PanelTabControl and Isotone.DialogTabControl; TabItem templates with Border PART_Chrome and, for dialog tabs, Rectangle PART_Underline visible on IsSelected. TabStripPlacement="Top", KeyboardNavigation.TabNavigation="Once" on the header panel.

Data

Layers row

Layers panel: visibility, thumbnail, mask link, lock; blend and opacity

The Layers panel row (Gesso; Stilus uses the same row for objects): visibility eye, thumbnail, optional linked mask, name, trailing badges, over the blend mode and opacity controls.

Anatomy

PartSizeTokens
Rowlayer-row-h-compact 36px (Comfortable 44px), 1px divider belowtext-primary body name
Visibility28px column with a 1px divider right edge, 14px eyeicon; empty column when hidden
Thumbnail28px (Comfortable 36px), 1px divider-strong frame, 8px checkerboardchecker-light, checker-dark
Mask link14px column with a 12px link glyph, then the mask thumbnailicon
Group12px chevron and 16px folder instead of a thumbnail; children indent 24pxicon
Badgesfx in caption, 14px locktext-secondary, icon
Header controlsblend ComboBox (132px) + Opacity NumberBox; Lock toggles (20px subtle toggle buttons) + Fill NumberBoxas those components
Footer22px subtle icon buttons: link, fx, mask, adjustment, new group, new layer, deleteicon

States

  • Hover surface-hover; selected state-subtle; selected while the panel lacks focus selection-inactive; multi-select uses the same fill.
  • Hidden: no eye, thumbnail at 45%, name in text-secondary.
  • Locked: lock badge; a fully locked Background layer sets its name in italics (Photoshop convention).
  • Dragging: 2px state-line insertion line between rows (starting after the visibility column); dropping on a group highlights it with Drop into from List and tree.
  • Keyboard focus: inset focus ring.

Keyboard

Alt+[ and Alt+] move the selection down and up; Ctrl+[ and Ctrl+] move the layer; the eye toggles with a click, Alt+click soloes; F2 or double-click the name renames; Ctrl+G groups; Delete deletes. Clicking the eye never changes the selection.

WPF

ListBox (or TreeView for groups) with ItemTemplate Isotone.LayerRowTemplate: a Grid with columns 28 | Auto | Auto | * | Auto. The thumbnail is an Image over a DrawingBrush checkerboard (TileMode="Tile", Viewport="0,0,8,8" absolute). Thumbnails render off the UI thread at the row's device pixel size. The eye is a ToggleButton with Focusable true and AutomationProperties.Name "Show layer" / "Hide layer".

List and tree

List and tree rows: hover, selected, unfocused, disabled, drop targets

Rows for lists and trees in panels and dialogs: Albumen's folders and collections, Stilus's object tree, History, Presets.

Anatomy

PartSizeTokens
Rowrow-h-compact 22px (Comfortable 28px), 8px left padding plus 16px per levelbody in text-primary
Expand chevron12px box, chevron-right (collapsed) or chevron-down (expanded)icon
Icon14px, 6px gapsicon
Metaright aligned, captiontext-secondary (counts, sizes, "offline")

States

StateLook
Hoversurface-hover
Selected, focused liststate-subtle (text stays text-primary)
Selected, list not focusedselection-inactive
Keyboard focus2px inset focus ring on the focused row (drawn over the selection)
Disabledtext-disabled text, icon and meta
Drop intostate-tint fill + 1px inset state-line
Drop before or after2px state-line bar between rows, inset 4px

Keyboard

Up and Down move; Shift extends; Ctrl+Space toggles; Right expands then moves to the first child; Left collapses then moves to the parent; * expands all below; F2 renames; Delete deletes with undo; typing jumps by prefix.

WPF

ListBox, ListView and TreeView styles Isotone.ListBox, Isotone.TreeView with item containers Isotone.ListRow / Isotone.TreeRow. The tree row template draws full-width highlights (a Grid spanning the row with the indent inside, not WPF's default indented highlight). Triggers use IsSelected plus Selector.IsSelectionActive for the unfocused color. Drag feedback via an Adorner (Isotone.DropIndicatorAdorner). Always VirtualizingPanel.IsVirtualizing="True" and VirtualizationMode="Recycling" for libraries of 50,000 photos.

Shell

Context menu

Right-click menu on a layer

The right-click menu: the same item template as Menu, opened at the pointer and scoped to the thing under it. It names its subject with a group header when the target is not obvious (a layer, a guide, a photo).

Anatomy and sizes

Identical to Menu: surface-raised, 1px border-popup, radius-md, shadow-popup, rows menu-row-h-compact, icons 16px, shortcut in text-secondary, separators divider-strong, group header in section-header.

Rules

  • Order: the most frequent command first, then edits, then destructive commands last and separated. Show a disabled item rather than removing it when users expect to find it there (Rasterize on a pixel layer).
  • Opening a context menu on an unselected row selects that row first; on a selected row it acts on the whole selection.
  • Right-click on the canvas lists commands for the active tool (Photoshop behavior), not a generic list.

States

As Menu: highlighted state with state-on text, disabled text-disabled, checked, radio, submenu.

Keyboard

Shift+F10 or the Menu key opens it at the focused element (top-left of the focused row), with the first enabled item highlighted. Arrows, Enter and Escape as in Menu.

WPF

ContextMenu styled in Menu.xaml, sharing the MenuItem style. HasDropShadow is off; the template draws shadow-popup itself. Set Placement="MousePoint" for pointer opening; ContextMenuService.Placement handles keyboard opening.

Document tabs

Open documents above the canvas

One tab per open document, on the frame strip between the options bar and the canvas.

Anatomy

PartSizeTokens
Stripdoctab-h-compact 28px (Comfortable 32px)frame, 1px divider below
Tab12px left and 4px right padding, max doctab-w-max 240px, 1px divider on the rightlabel body in text-secondary
Close18px square, 12px x glyph, radius-smicon; hover surface-control-hover
Overflowsubtle icon button at the right, chevrons-rightopens a list of all documents

Label format (Photoshop): name.ext @ zoom (mode/depth) plus * when unsaved. Long names truncate in the middle so the extension and zoom stay visible.

States

  • Rest: text-secondary, close hidden.
  • Hover: surface-hover, text-primary, close visible.
  • Selected: surface-panel (joins the canvas area), body-strong text-primary, 2px state-line along the top edge, close visible.
  • Focus: inset focus ring.
  • Dragging: the tab follows the pointer; a 2px state-line insertion bar shows the drop slot; dragging out floats the document.

Keyboard

Ctrl+Tab and Ctrl+Shift+Tab cycle documents; Ctrl+W or Ctrl+F4 closes; with a tab focused, Left and Right move, Delete closes, the Menu key opens Close, Close Others, Reveal in Explorer.

WPF

TabControl over the documents collection (or AvalonDock LayoutDocumentPane with the Isotone theme), TabItem style Isotone.DocumentTab. Template parts: Border PART_Chrome, Rectangle PART_Indicator (visible when IsSelected), TextBlock with a middle-ellipsis converter, Button PART_Close bound to CloseDocumentCommand. Middle-click closes.

Menu bar and menus

Menu bar and drop-down menu, every item state

Drop-down menus from the menu bar inside the title bar. Highlighted items use the Highlight color (state), so the menu reads like Photoshop's.

Anatomy

PartSizeTokens
Menu title24px tall, 8px side padding, radius-smtext-primary; hover surface-hover; open surface-control-hover
Menumin menu-w-min (200px), 4px vertical padding, radius-mdsurface-raised, 1px border-popup, shadow-popup
Item rowmenu-row-h-compact 24px (Comfortable 30px), inset 4px, radius-smlabel text-primary in body
Icon column20px16px icon in icon; also holds the check or radio dot
Shortcutright aligned, 16px gap before ittext-secondary
Submenu arrow16px column, 12px chevron-righticon
Separator1px, 4px above and belowdivider-strong
Group headercaps, section-headertext-secondary

States

  • Rest: as above.
  • Highlighted (pointer or keyboard): fill state, label, shortcut, icon and arrow in state-on.
  • Submenu open (pointer moved into the submenu): surface-hover, so the path stays visible without a second blue bar.
  • Disabled: label, shortcut and icon text-disabled; still highlightable by keyboard with no fill so the reason tooltip can show.
  • Checked (toggle command): check glyph in the icon column; the item's own icon is dropped.
  • Radio (one of a set): 6px dot in the icon column; the set sits between separators, optionally under a group header.

Keyboard

  • Down and Up move the highlight and wrap; Home and End jump; letters jump by access key, then by first letter.
  • Right opens a submenu, Left closes it (or moves to the previous menu title from a top-level menu).
  • Enter or Space runs the item; Escape closes one level; Alt closes all.
  • Shortcut text uses Windows naming: Ctrl, Shift, Alt, then the key (Shift+Ctrl+Z in Photoshop order is acceptable across the suite as long as one order is used everywhere; Isotone uses Shift+Ctrl+key).

WPF

  • Menu and MenuItem restyled in Isotone.UI/Themes/Controls/Menu.xaml. The MenuItem template is a 4-column Grid with SharedSizeGroups (Icon, Label, Gesture, Arrow) and parts PART_Popup and PART_SubmenuPopup (a Popup with AllowsTransparency so the shadow and radius render).
  • Triggers: Role (TopLevelHeader, TopLevelItem, SubmenuHeader, SubmenuItem), IsHighlighted, IsChecked, IsEnabled, IsSubmenuOpen.
  • InputGestureText feeds the shortcut column; commands carry their KeyGesture so the text never drifts.
  • Radio items: IsCheckable plus an attached Isotone.MenuItem.Group, drawing the dot instead of the check.
  • Separator keyed MenuItem.SeparatorStyleKey.

Options bar

Context toolbar per tool, with the hint bar

The context toolbar under the title bar that shows the active tool's settings (Photoshop's options bar, Bezier's context toolbar), with the hint bar beneath it.

Anatomy

PartSizeTokens
Baroptionsbar-h-compact 32px (Comfortable 40px), 12px side padding, 8px gapssurface-panel, 1px divider below
Tool preset buttonsubtle button, 16px tool icon plus 10px chevronopens the tool preset picker
Controls24px NumberBox, ComboBox, Checkbox, subtle toggle buttonsas those components
Labelsbefore a control, bodytext-secondary
Group separator1 x 16px, 4px side marginsdivider-strong
Hint barinfobar-h 28px, lightbulb 14px, caption textsurface-tabstrip, text-secondary, the tool name in body-strong text-primary

Rules

  • Content changes with the tool; order: preset, size and shape, blending (Mode, Opacity, Flow), then toggles. Keep Photoshop's order so muscle memory transfers.
  • In Stilus with a selection the bar shows the selection's X, Y, W and H (Bezier's document W/H when nothing is selected).
  • Controls that do not apply are disabled with a reason tooltip, never hidden, so the bar does not jump.
  • The hint bar is one line naming the tool and its modifier keys; View > Show Hints hides it.
  • Overflow: controls at the right collapse into a trailing ellipsis button menu.

Keyboard

The bar is a toolbar: F6 cycles focus between rail, options bar, canvas and dock; inside, Tab moves between controls; Enter commits a field and returns focus to the canvas; Escape reverts it.

WPF

ToolBar is not used (its overflow chrome fights the design); the bar is a DockPanel with an ItemsControl whose DataTemplateSelector picks the tool's options view. Style key Isotone.OptionsBar; separators Isotone.ToolbarSeparator. The hint bar is Isotone.HintBar bound to the tool's Hint string.

Panel

Dock panel: tab strip, sections, collapsed icon strip

Docked panels in the right dock: a tab strip of grouped panels, a panel menu, collapsible sections, and a collapsed icon-strip form.

Anatomy

PartSizeTokens
Dockpanel-w-default 280px (min panel-w-min 260, default max panel-w-max 300; user resizable)panels surface-panel separated by 1px divider over frame
Tab strippanel-tab-h-compact 26px (Comfortable 32px)surface-tabstrip, 1px divider below
Panel tab12px side padding, bodyinactive text-secondary; selected surface-panel + text-primary joined to the body
Strip tools20px subtle icon buttons: collapse (chevrons-right), panel menu (menu)icon
Section headersection-header-h 28px, 12px chevron, caps section-headertext-secondary, hover text-primary; optional count right aligned
Section body12px sides, 4px top, 12px bottom, 8px row gapproperty rows: 60px label column in text-secondary
Icon strip (collapsed)panel-iconstrip-w 36px, 28px buttonsas tool buttons; the open panel's button is checked

Behavior

  • Section expanded state persists per panel in settings.
  • Collapsing the dock turns each panel group into its icons; clicking one flies the panel out over the canvas (with shadow-popup), clicking elsewhere closes it.
  • Panels float by dragging the tab out; floating panels use surface-raised with shadow-dialog and a 20px caption strip.
  • Nothing inside a panel is louder than the canvas: no fills beyond surface-panel, no accent color.

Keyboard

F6 reaches the dock; Ctrl+Tab inside a panel group moves between tabs; section headers are buttons (Enter or Space toggles, aria-expanded); the panel menu opens with Shift+F10 on the tab.

WPF

AvalonDock (LayoutAnchorablePane) with an Isotone theme dictionary replacing AnchorablePaneTitle and AnchorablePaneTabPanel templates; outside AvalonDock, Isotone.PanelHost (TabControl + ItemsControl). Section: Expander styled Isotone.SectionExpander (Bezier CollapsibleHeader), header template with a rotating 12px chevron (duration-standard, ease-out). Property rows: Grid with ColumnDefinition Width="60" shared by Grid.IsSharedSizeScope.

Splash

Suite card: live status, launch progress and accent border glow; reference renders per app

The Suite card: the window each app shows while it starts (operator decision 2026-09-27). A graphite card with the app icon on a soft accent halo, the app name, its role, the suite and version line, a live status line and launch progress, and the spectrum band as a gentle wave along the bottom edge. It is the same card in Stilus, Gesso and Albumen; only the icon, the accent, the name, the role and the status text differ.

The reference design is resources/icons/<app>/<app>-splash.svg (640 x 360), also used as a marketing image. In the app the card is built in XAML to this spec, never shown as a picture, so the version, the status and the progress are live.

Anatomy

All positions are in DIPs on the 640 x 360 card, origin top left; text positions are baselines, as in the reference SVG.

PartGeometryValues
Card640 x 360, radius 8vertical gradient #303136 (top) to #1A1B1E (bottom)
Inner highlight1px stroke inset 0.5, radius 7.5white at 8 percent
Halocircle centred (128, 160), radius 150, clipped to the cardradial accent-<app> at 20 percent opacity fading to 0
App icon136 x 136 at x 56, y 92the Direction C master <app>.svg (or its generated PNG/<app>_256.png), as is
App namex 228, baseline 148Segoe UI Variable Display 46px semibold (600), letter spacing -0.5px, #F4F4F5
Rolex 230, baseline 17816px regular, #B7B8BD: "Vector editor", "Raster and photo editor", "Digital darkroom and photo manager"
Suite and versionx 230, baseline 21213px regular, #8C8D93: "Isotone Graphics Suite · Version 0.1.0", the middle dot in #6C6D73
Status linex 230, baseline 272Segoe UI Variable Text 12px regular, #A3A4AA, one line, trimmed with an ellipsis
Progress track340 x 3 at x 230, y 284, radius 1.5#3A3B41
Progress fillfrom x 230, same height and radiusaccent-<app>
Copyrightright edge x 610, baseline 31211px regular, #6E6F75: "© 2026 Rizonetech (Pty) Ltd · Free and open source (GPL-3.0)"
Spectrum bandpath M0 340C140 330 250 352 380 341S560 326 640 332V360H0Z, clipped to the cardhorizontal gradient x 0 to 640, the seven suite stops of the app icons
Band crestthe same curve as a stroke, 1.5pxwhite at 35 percent
Border glowa highlight travelling around the card edge, 1.5pxaccent-<app>

Layout grid: a left column for the icon (x 56 to 192, centred on y 160) and a text column from x 230 to the right margin at x 610; the name, role and version block sits above the status and progress block, and the copyright closes the text column above the band.

Colors

  • The accent is accent-<app> (Stilus #29C5E6, Gesso #F5923E, Albumen #4CC47A), the dark-theme value in every theme: the card is always graphite.
  • The card greys (#303136, #1A1B1E, #F4F4F5, #B7B8BD, #8C8D93, #6C6D73, #A3A4AA, #3A3B41, #6E6F75) have no token: they are the splash's own palette, matched to the app icon tile. The card looks the same in every brightness theme, like the app icon.
  • Spectrum stops at 0, 0.167, 0.333, 0.5, 0.667, 0.833 and 1: #FF4D6D, #FF9A3C, #FFD84A, #4CC47A, #29C5E6, #5B7CFF, #B45CFF.
  • High contrast: the card fill is the system Window color, every text and the 1px border the system WindowText color, the progress fill the system Highlight color; the halo, the band crest and the glow are dropped; the icon and the band stay, as images.

Behaviour

  • Show the splash as the first thing the process draws, on its own UI thread, centred on the monitor that holds the cursor.
  • Status and progress are live: each startup step sets the status line ("Loading tools…", "Loading brushes…", "Opening the catalog…") and advances the fill by its share of the steps. The bar is always determinate.
  • The fill width change animates over duration-fast 100ms with ease-out; it jumps when animations are off.
  • The border glow is Bezier's BorderGlowAnimator in accent-<app>: one lap around the card every 6 seconds while loading, fading in over 300ms and out over 500ms when loading ends. When Windows animation effects are off there is no glow at all.
  • Timing: the splash stays until the main window is ready (loaded and rendered once), then fades out over duration-standard 200ms while the main window shows. There is no minimum display time and no artificial delay; with animations off it closes at once.
  • A startup failure closes the splash before the exception window opens.

Rules

  • Never ship the reference SVG, or a PNG of it, as the splash: the text would be frozen.
  • The version is the app's own informational version without the build metadata ("Version 0.1.0", "Version 0.2.0-beta.1").
  • The status line is sentence case, ends with an ellipsis while working, and names what is loading, never a file path or a percentage.
  • No buttons, no links, no close box, no tips carousel.
  • The accent appears only on the halo, the progress fill and the glow; the icon keeps its own colors.

Keyboard

Not focusable and takes no input. Screen readers get the window name ("Stilus is starting"), the status line as a polite live region, and the progress through UIA RangeValue.

WPF

Isotone.UI SplashWindow (WindowStyle="None", AllowsTransparency="True", ShowInTaskbar="False", Topmost="True", ResizeMode="NoResize"), a 640 x 360 Grid clipped to a radius 8 RectangleGeometry, drawn from an AppIdentity (name, role, version, icon, accent). The card greys are named brushes in the window's own resources, not in the theme dictionaries. The icon is an Image of the app's generated PNG/<app>_256.png (or a DrawingImage of the master) at 136 x 136 with RenderOptions.BitmapScalingMode="HighQuality"; the band is a Path with the geometry above and a LinearGradientBrush in absolute units. The progress is a ProgressBar restyled to the 3px track. The glow is BorderGlowAnimator on a 1.5px Rectangle stroke with RadiusX/RadiusY 8. The check is a capture of the running window at 100 percent, compared against the render of <app>-splash.svg at 640 x 360: same positions and colors, apart from the live status text and progress.

Status bar

Dense status strip with separators and mono coordinates

The dense strip along the bottom edge: status on the left, document facts and live readouts on the right (Bezier's status bar).

Anatomy

PartSizeTokens
Barstatusbar-h-compact 22px (Comfortable 26px), 12px side paddingframe, 1px divider on top
Textcaption (Comfortable caption-comfortable)text-secondary
Separator1 x 12px, 12px side marginsdivider-strong
Status dot6px circlestatus-success ready, status-warning working, status-error failed, always next to a word
Coordinatesmonotext-primary
Inline progress96px Progress bar with a percentstate-line

Order, left to right: status word, selection summary, color mode, snapping, artboard or layer; right: cursor X and Y, zoom, element count or document size, memory, GPU or CPU.

Rules

  • Values update live but throttle to 10 per second; coordinates use tabular figures and fixed decimals so the text does not jitter.
  • Items the user clicks (zoom, color mode, snapping) are subtle buttons 18px tall with the same text style, hover surface-hover.
  • No icons except where they are the item (the magnet for Snap).

Keyboard

The bar is not in the tab order; its commands exist in menus. Screen readers get changes through a polite live region on the status word only.

WPF

StatusBar restyled as Isotone.StatusBar with StatusBarItems and Separator keyed StatusBar.SeparatorStyleKey (1 x 12). Coordinates: TextBlock with FontFamily="{DynamicResource font-mono}" and Typography.NumeralAlignment="Tabular". AutomationProperties.LiveSetting="Polite" on the status word.

Tool rail

Tool rail, flyout groups, rich tooltip, every tool state

The single-column tool palette on the left of every document window, with flyout groups and the foreground and background color chips at the bottom.

Anatomy

PartSizeTokens
Railtoolrail-w-compact 40px (Comfortable toolrail-w-comfortable 48px), 4px top and bottomsurface-panel, 1px divider on the right
Tool buttontool-button-compact 32px square (Comfortable 40px), 2px gap, radius-sm20px icon (icon-md) in icon
Group triangle4px, 3px from the bottom-right cornercurrentColor at 80%
Group separator24 x 1px, 4px above and belowdivider-strong
Color chipstwo color-chip squares offset 10px, swap and default glyphs at 12px1px text-primary edge plus 1px frame halo so white and black chips both read

States

StateLook
Resttransparent, icon icon
Hoversurface-hover, icon text-primary
Pressedsurface-control-pressed
Checked (active tool)state-tint fill, 1px state-line border, glow-state shadow (Bezier signature); widen the glow to blur 10 at 60% on hover
Disabledicon text-disabled (for example Crop on a locked document)
Focusfocus ring, 1px outside

Flyout groups

  • A grouped tool shows the triangle. Press and hold (300ms), right-click, or Alt+click cycles; the flyout is a Menu listing the group with shortcut letters and a 4px square marking the tool shown on the rail.
  • Choosing a tool from the flyout replaces the rail button's icon and checks it.
  • Shift+letter cycles the tools of a group (Photoshop default).

Rich tooltip

After tooltip-delay (400ms) the Tooltip component opens right of the button: tool name, shortcut chip, one-line description. Moving to a neighboring tool while a tooltip is open switches it with no delay.

Keyboard

  • The rail is one tab stop (KeyboardNavigation.DirectionalNavigation="Cycle"); Up and Down move, Enter or Space selects, Shift+F10 opens the flyout.
  • Single-letter shortcuts work anywhere the canvas has focus and never when a text field has focus.

WPF

  • ItemsControl of RadioButtons with GroupName="Tools" styled Isotone.ToolButton (from Bezier's ActiveToolButton). Template parts: Border PART_Chrome (fill, border, DropShadowEffect with ShadowDepth 0 for the glow), Path PART_Icon, Path PART_GroupTriangle (visible when Isotone.Tool.HasGroup).
  • Visual states: CommonStates (Normal, MouseOver, Pressed, Disabled), CheckStates (Checked, Unchecked), FocusStates.
  • ToolTipService.InitialShowDelay = 400, BetweenShowDelay = 0, ToolTip = an Isotone.RichToolTip.
  • AutomationProperties.Name = "Brush Tool (B)".

Window chrome

Custom title bar: app mark, menu bar, caption buttons

The custom title bar every Isotone document window draws: app mark in the app accent, the menu bar inside the title bar (as Photoshop does), a drag area, and the three Windows 11 caption buttons. There is one title bar per window; the OS frame is removed, never doubled.

Anatomy

PartSizeTokens
Barfull width x titlebar-h (32px)fill frame, 1px divider under it only when the options bar is hidden
App mark40px zone, the app icon at 16px (20px at 125 percent scale and up)the hand-tuned <app>-16.svg from the App icons group, drawn as is: never recolored, never a catalog glyph
Menu bartitles 24px tall, 8px side paddingsee Menu
Drag areathe remaining widthframe
Caption buttonscaption-button-w x titlebar-h (46 x 32)glyphs 10px drawn from the icon catalog at stroke 1 in text-primary

The document name is not repeated in the title bar: the document tabs carry it. With no document open, the drag area shows the app name in text-secondary.

States

  • Caption button: rest (transparent), hover surface-control-hover, pressed surface-control-pressed, keyboard focus (focus ring inset).
  • Close: hover caption-close-hover with the glyph in caption-close-on, pressed caption-close-pressed. Never tinted by the Highlight color or the app accent.
  • Maximized: the maximize glyph becomes restore; the bar keeps 32px and gains a 7px top inset handled by WindowChrome (no content under the screen edge).
  • Inactive window: menu titles, title text and caption glyphs go to text-disabled; the app icon stays in full color, as Windows draws app icons in inactive windows.

Keyboard

  • Alt or F10 moves focus to the first menu title and shows access-key underlines; Alt+letter opens that menu.
  • Alt+Space opens the system menu (Restore, Move, Size, Minimize, Maximize, Close).
  • Caption buttons are not tab stops; they stay reachable through the system menu.

WPF

  • Window with WindowChrome (CaptionHeight = 32, ResizeBorderThickness = 6, GlassFrameThickness = 0 on Windows 10, -1 to keep the Windows 11 rounded corners and snap shadow, UseAeroCaptionButtons = False).
  • Every interactive element in the bar sets WindowChrome.IsHitTestVisibleInChrome="True".
  • Caption buttons are Buttons styled Isotone.CaptionButton / Isotone.CaptionCloseButton; the maximize button returns HTMAXBUTTON from a WM_NCHITTEST hook so Windows 11 Snap Layouts open on hover.
  • AutomationProperties.Name: "Minimize", "Maximize" / "Restore", "Close".
  • Brushes: {DynamicResource frame}, {DynamicResource caption-close-hover} and so on: brush keys are token names.
  • Watch IsActive with a DataTrigger for the inactive state.

Feedback

Dialog

Modal dialog over a scrim; Enter = OK, Escape = Cancel

A modal window for a focused task (Image Size, Export, Preferences, confirmations). Enter does what the primary button says; Escape does what Cancel says.

Anatomy

PartSizeTokens
Scrimthe owner window's client areascrim
Surface360 to 640px wide, radius-lgsurface-raised, 1px border-popup, shadow-dialog
Header12px top, 16px left, title dialog-title; 24px close buttontext-primary; close icon
Body12px top, 16px sides and bottom, 8px row gap, 72px label columnlabels text-secondary
Footer12px by 16px padding, 1px divider above, buttons right aligned with 8px gapprimary last (rightmost), then Cancel to its left
Controlscontrol-h-dialog 28pxas components

Rules

  • The title is the command without the ellipsis ("Image Size"); the primary button is a verb ("Resize", "Export") or OK.
  • The primary button uses the app accent; there is exactly one.
  • Confirmations name what, how many and how large: "Delete 12 photos (84 MB) from disk?"; the destructive verb is the button label.
  • Dialogs that preview changes show a Preview checkbox and apply live to the canvas.
  • Open with a duration-slow pop from scale 0.95 and fade; close in duration-fast; none when animations are off.

About dialog

Help, About <App> is a Dialog with the app icon master at 128px (docs/design/app-icons.md), the app name in dialog-title, and these lines in body, top to bottom, with no other legal text:

  • "Version 0.1.0 (commit 5a8bdd4)": the informational version with the short commit, and a "Copy version info" button.
  • "Copyright (C) 2025-2026 Rizonetech (Pty) Ltd": the copyright holder is the company, never the brand.
  • "Rizonesoft is a brand of Rizonetech (Pty) Ltd.": the publisher users see stays Rizonesoft.
  • "Licensed under the GNU General Public License v3.0" with a link opening the license text shipped with the app.
  • "Source code: https://github.com/rizonesoft/Isotone/tree/<tag>": the GPL source offer, a link to the exact tag the build came from (stilus-v0.1.0); a build with no tag links the commit instead.
  • The product page link: one configured value, https://www.rizonesoft.com/ until the per-app pages are decided, never a hardcoded per-app URL.
  • The credits list (package, version, license, link) and the repository and issue links.

The footer has one button, Close, which is the default and the cancel button. Stilus, Gesso, and Albumen show the same dialog from Isotone.UI, filled from the app's identity.

Keyboard

Focus starts on the first field (or the primary button for confirmations). Tab order follows reading order and wraps inside the dialog. Enter activates the default button unless focus is in a multi-line field; Escape cancels; Alt+underlined letter jumps to a labeled control.

WPF

Window subclass Isotone.DialogWindow with WindowStyle="None", AllowsTransparency="True" (for the rounded corners and shadow), Owner set, ShowInTaskbar="False", WindowStartupLocation="CenterOwner"; the owner draws the scrim through an adorner while the dialog is open. Buttons: IsDefault on the primary, IsCancel on Cancel. FocusManager.FocusedElement sets the first focus.

Progress

Determinate and indeterminate bars, rings, launch progress

Bars and rings for work that takes longer than a second. Anything slower than a second shows progress and can be cancelled.

Anatomy

PartSizeTokens
Bar4px tall, 2px radius, width from the hosttrack surface-field with a 1px divider-strong inner edge; fill state-line
Launch bar340 x 3px, 1.5px radius, splash screen only (see Splash)track #3A3B41 with no edge, fill accent-<app>
Failedfill stops where it failedstatus-error fill and a helper line
Ring16px (stroke 2) inline, 32px (stroke 3) in empty statestrack divider-strong, arc state-line
Labelcaption: percent and counts ("42% · 104 of 248")text-secondary

Rules

  • Determinate whenever the total is known; indeterminate (a 30% segment sliding in 1.6s) only while counting.
  • Pair long operations with Cancel (subtle button) next to the bar.
  • Status bar progress uses a 96px bar with the percent after it.
  • Reduced motion: indeterminate bars show a static 30% segment and the label says "Working…"; rings stop spinning and show a static arc.

Keyboard

Not focusable; Cancel is. Screen readers get the value through UIA RangeValue and a polite live region at 10% steps.

WPF

ProgressBar style Isotone.ProgressBar (parts PART_Track, PART_Indicator, and PART_GlowRect repurposed as the indeterminate segment); Isotone.ProgressRing (Control drawing an ArcSegment Path with a RotateTransform storyboard, stopped when SystemParameters.ClientAreaAnimation is false).

Toast and info bar

Toasts and in-window info bars

Two ways to report outcomes: toasts for finished background work and failures after the fact; info bars for conditions that persist while the user works.

Toast

PartSizeTokens
Surface320px, 10px by 16px padding (12px left), radius-lgsurface-raised, 1px border-popup, shadow-dialog
Icon16px status iconstatus-error, status-success, status-warning or status-info
Titlebody-strongtext-primary
Messagecaptiontext-secondary
Actiona linkstate-text
Dismiss20px subtle icon buttonicon

Toasts stack bottom right above the status bar, 8px apart, at most three. They slide in 20px and fade over duration-standard, stay 6s (errors stay until dismissed), and pause while hovered. Error text names the action, the file and what it needed (Bezier's error toast, now neutral with a colored icon instead of an orange fill).

Info bar

Full width under the options bar, infobar-h 28px min, 12px side padding, caption text; the lead phrase in body-strong text-primary.

KindFillIcon
Infostatus-info-subtleinfo in status-info
Warningstatus-warning-subtlealert in status-warning
Errorstatus-error-subtleerror in status-error
Successstatus-success-subtlesuccess in status-success
Hint (Bezier info bar)surface-tabstripbulb in icon, text text-secondary

Text on every subtle fill is text-primary (4.5:1 checked in all four themes). Status always pairs color with an icon and a word.

Keyboard

Toasts are announced through a live region (assertive for errors, polite otherwise) and never take focus; F6 reaches the toast stack; Escape dismisses the focused toast. Info bar actions are ordinary tab stops.

WPF

Isotone.ToastHost (an ItemsControl in an adorner layer over the window) with Isotone.Toast items and Isotone.InfoBar (Control with Severity, Title, Message, ActionCommand, IsClosable). AutomationProperties.LiveSetting per severity.

Tooltip

Rich tooltip: title, shortcut chip, one-line description

Bezier's rich tooltip: a title, a shortcut chip and one line of description, opening after 400ms.

Anatomy

PartSizeTokens
Surfacemax 260px wide, 6px by 10px padding, radius-smsurface-raised, 1px border-popup, shadow-tooltip
Titlebody-strongtext-primary
Shortcut chip8px after the title, mono caption, 1px divider-strong border, radius-smtext-secondary
Descriptioncaption, one or two linestext-secondary

Rules

  • Every icon-only control has one: the command name and its shortcut. Tools and complex commands add the description (what it does, the main modifier).
  • Disabled controls get a tooltip that says why ("Select two or more layers to align them.").
  • Open after tooltip-delay 400ms; move between neighbors with no delay; close on pointer leave, click, Escape or after 10s.
  • Never interactive, never the only place information lives.
  • Placement: right of tool rail buttons, below everything else, flipping at screen edges.

Keyboard

Keyboard focus shows the tooltip after the same delay; Escape dismisses. Screen readers get the same text through AutomationProperties.HelpText.

WPF

ToolTip style Isotone.ToolTip (implicit, HasDropShadow false, template draws the shadow) and Isotone.RichToolTip content: a StackPanel with Title, Shortcut and Description bound from a ToolTipInfo record on the command. ToolTipService.InitialShowDelay="400", BetweenShowDelay="0", ShowOnDisabled="True".

Canvas

Canvas surround, rulers and guides

Surround, rulers, guides, marching ants, transform handles, checkerboard

The document area: the pasteboard around the image or artboard, rulers, guides, selection outlines, transform handles and the transparency checkerboard. The artwork is the brightest thing on screen; everything here is thin and neutral or fixed-color so it reads over any image.

Parts

PartSizeTokens
Surround (pasteboard)fills the viewcanvas-surround (distinct from frame and surface-panel); user can override per document
Document edge1px outside the imagedivider-strong
Rulersruler-w 18px, top and left, square corner cellruler-surface, major ticks every 100 units in text-secondary with 9px numbers, minor ticks divider-strong, 1px divider-strong edge
Cursor marker on rulers1px linestate-line
Guides1px, full viewguide (cyan); locked guides the same color
Smart guides1px, only while dragging, with distance labelsguide-smart (magenta)
Marching ants1px, 4px dashes alternating, animated 4px per 150msants-dark, ants-light
Bounding box1pxhandle-stroke (follows the Highlight color)
Transform handleshandle-size 7px squares at corners and midpoints; rotate zone 12px outside the cornersfill handle-fill, 1px handle-stroke
Checkerboard8px squares (checker-tile) at 100%, fixed screen sizechecker-light, checker-dark
Artboard (Stilus)document colorartboard

Rules

  • Guide, ants, handle and checker colors are the same in every theme on purpose: they sit on artwork, not on chrome.
  • Handles scale with the display (7px at 100%, 14px at 200%), never with zoom.
  • Pixel grid appears above 800% zoom as 1px lines in ants-dark at 15% opacity.
  • Reduced motion: marching ants stop and show a static dashed outline.

WPF

The canvas is SkiaSharp (SKElement / SKGLElement); read these colors from the theme once per theme change into SKColor fields (an Isotone.UI.CanvasPalette singleton), never per frame. Rulers are WPF FrameworkElements with OnRender and GuidelineSets for crisp 1px lines at every scale. The surround color is a document setting defaulting to canvas-surround.