Skip to content
Style Guide
v0.1.0

Basics

Colour

Tomatico's palette is five values from white to near-black. Everything else in the system is either derived from that ramp for interface needs, or a small functional set reserved for status.

The brand palette

These five values come straight from the brand book's colour and construction section. They are locked: no additions, no substitutions, no tints of a brand colour presented as a brand colour.

White #FFFFFF --tmt-white Primary light surface. The default page background.
Grey 100 #E8E8E8 --tmt-grey-100 Quiet fills: hover states, badge backgrounds, disabled controls.
Grey 500 #606060 --tmt-grey-500 Secondary text on light surfaces. 6.3:1 on white.
Grey 700 #363636 --tmt-grey-700 Strong borders, hover state for the black interactive colour.
Black #020106 --tmt-black Body text, the interactive colour, and the dark surface.
Tomatico's black is #020106, not #000000. The trace of blue in it is what stops large black areas looking like a hole in the screen. Use the token, not black.

The derived ramp

Five steps is enough for a logo and not enough for an interface. A screen needs to separate a page background from a card, a card from an input, an input from its border, and a border from a divider — all without crossing into a value that reads as text.

So the system fills in the gaps. The four brand greys keep their names and values; the seven derived steps sit between them. Derived steps are for interface surfaces, borders and states only. They never appear in a logo, a printed piece or a marketing layout.

050
100
200
300
400
500
600
700
800
900
black
TokenHexOriginContrast on whiteUse for
--tmt-grey-050#F7F7F7Derived1.07:1Sunken surfaces, table header fill, code blocks
--tmt-grey-100#E8E8E8Brand1.23:1Muted fills, hover on ghost controls
--tmt-grey-200#D2D2D2Derived1.51:1Default borders
--tmt-grey-300#B4B4B4Derived2.07:1Dividers on dark, muted text in dark mode
--tmt-grey-400#8B8B8BDerived3.41:1Disabled text and placeholder edges only — not body text
--tmt-grey-500#606060Brand6.30:1Secondary and muted text on light surfaces
--tmt-grey-600#4A4A4ADerived8.86:1Pressed states
--tmt-grey-700#363636Brand12.08:1Strong borders, hover on the primary button
--tmt-grey-800#232323Derived15.72:1Dark-mode muted surfaces, masthead dividers
--tmt-grey-900#141414Derived18.42:1Dark-mode raised surfaces
--tmt-black#020106Brand20.80:1Body text, interactive colour, dark surface

Semantic tokens

Components never reference a grey directly. They reference a role, and the role resolves to a different grey in each theme. This is the single most important rule on the page: get it right and dark mode is free, get it wrong and every component needs a dark-mode patch.

TokenLightDarkRole
--tmt-surfacewhiteblackThe page itself
--tmt-surface-raisedwhitegrey 900Cards and panels that sit above the page
--tmt-surface-sunkengrey 050#000000Wells, table headers, code
--tmt-surface-mutedgrey 100grey 800Quiet fills and disabled backgrounds
--tmt-textblackwhiteBody and headings
--tmt-text-secondarygrey 700grey 200Supporting copy
--tmt-text-mutedgrey 500grey 300Captions, hints, metadata
--tmt-text-disabledgrey 400grey 500Inactive controls only
--tmt-bordergrey 200grey 700Default component edges
--tmt-border-stronggrey 700grey 300Emphasis edges, outlined buttons
--tmt-interactiveblackwhiteButtons, links, active markers
--tmt-interactive-textwhiteblackText on the interactive colour
--tmt-focusblackwhiteThe focus ring

Status colour

The brand palette has no hue, but an interface has to say "this went wrong" without relying on the person reading every word. So the system adds four functional colours. They are an interface extension, not brand colours: they never appear in marketing, never fill a large area, and never carry meaning on their own.

Success #2E7D32 --tmt-success 5.1:1 on white. Confirmations, valid fields.
Warning #9A5B00 --tmt-warning 5.4:1 on white. Something needs attention but still works.
Error #C62828 --tmt-error 5.6:1 on white. Failures, invalid input, destructive actions.
Information #1565C0 --tmt-info 5.7:1 on white. Neutral notices and tips.

Each has a matching -surface and -border token for building alerts and badges, and each is replaced by a lighter value in dark mode so it still clears AA on a near-black background.

Do

  • Pair every status colour with an icon and a word.
  • Keep them to small areas: an alert's accent bar, a badge, an invalid border, error text.
  • Use error red for destructive buttons — that is the one button that carries hue.

Don't

  • Use them decoratively, or to make a chart look livelier.
  • Fill a whole panel or a page header with one.
  • Use green and red as the only difference between two states.
  • Introduce a fifth hue. If you need one, the design is doing too much.

Themes

Light and dark are both official. Switch with one attribute on the root element:

<html data-tmt-theme="light">  <!-- default -->
<html data-tmt-theme="dark">
Theme switch

Dark mode is not an inversion. Surfaces get lighter as they rise (black → grey-900), text steps back from pure white for supporting copy, and the status hues lighten. Use the Dark button in this guide's header to check any page.

Never hard-code a colour in a component. A literal #363636 looks correct in light mode and disappears in dark mode. If a component needs a value the semantic tokens do not cover, that is a signal the token set is missing something — raise it rather than working around it.

Contrast requirements

Tomatico interfaces meet WCAG 2.1 level AA. In practice:

  • Body text: at least 4.5:1 against its background.
  • Large text (18.66px bold or 24px and above): at least 3:1.
  • Borders and icons that carry meaning: at least 3:1.
  • Disabled controls are exempt, which is why --tmt-text-disabled sits at 3.4:1 — but never use that token for text a person is expected to read.

The semantic tokens are built so that any legitimate pairing passes. Combinations to avoid: --tmt-grey-400 or lighter as text on white, and --tmt-grey-500 as text on a dark surface — it only reaches 3.3:1 there, which is why dark mode uses grey 300 for muted text instead.