Euma Design

Euma is 1. a color palette 2. a design system 3. a UI-Theme, where 1 and 2 combine to make 3. Euma is something I came up with and I am using across my apps and systems. I'm open to contributions, so if you have any please let me know. You can view the source code on codeberg.org and contact me via email. If you come to like it spread the word about it.

Euma Color Palette

There are nine named colors to choose from, each comes in five different shades. In addition there is a spectrum of twenty-one colors spanning from black to white, to have more subtle differences, where it counts.

Euma Tokens

‘Design Tokens’, to organize the design language. They are like the words and grammar to tell the stroy with.

Definitions

The Design Tokens are stored as a JSON file, which follows a JSON Schema. More on that later in Token Schema.

Token Structure

What defines a token?
  1. A token ( T ) is an identifier which can refer to a non-unique value ( V ).
  2. T encodes how and where V should be used.
  3. T consists of sub-tokens ( t ).
  4. T must consist of 5 t , joined by colons. T = t1.t2.t3.t4.t5
  5. Sub-tokens must not repeat within T . t1 t2 t3 t4 t5
  6. Not every combination of sub-tokens has to map to a value, see rule 1.
  7. t must be camelCased
  8. t at position
  9. Types:
    • <category> =
      color | typo | space | fx
    • <property> =
      background | border | outline | text | textDecorationColor | fontFamily | fontFeatureSettings | fontSize | fontWeight | fontVariantLigatures | fontVariantCaps | fontVariantNumeric | fontVariantEastAsian | fontVariationSettings | fontStyle | letterSpacing | wordSpacing | textAlign | textDecorationLine | textDecorationStyle | textDecorationThickness | textUnderlinePosition | margin | marginTop | marginRight | marginBottom | marginLeft | marginBlock | padding | paddingTop | paddingRight | paddingBottom | paddingLeft | borderRadius | borderTopLeftRadius | borderTopRightRadius | borderBottomRightRadius | borderBottomLeftRadius | maxWidth | maxHeight | borderWidth | animationDuration | transitionDuration | animationTimingFunction | transitionTimingFunction | animationDelay | transitionDelay | boxShadow
    • <element> =
      button | badge | link | label | header | paragraph | small | code | select | input | legend | quote | notification | tab | entry | caption | icon | boxed | side | image | popover | list | indicator | panel | row | column | cell | window
    • <state> =
      hover | focus | active | inactive | normal | load | block | success | error | warn | info | new | visit | alert | click | drag | highlight
    • <variant> =
      default | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
  10. t2 is dependent on it's predecessor. t2(t1)
    Compatibility-Table
    t1t2
    colorbackground | border | outline | text
    typofontFamily | fontFeatureSettings | fontSize | fontWeight | fontVariantLigatures | fontVariantCaps | fontVariantNumeric | fontVariantEastAsian | fontVariationSettings | fontStyle | letterSpacing | wordSpacing | textAlign | textDecorationLine | textDecorationStyle | textDecorationThickness | textUnderlinePosition
    spacemargin | marginTop | marginRight | marginBottom | marginLeft | marginBlock | padding | paddingTop | paddingRight | paddingBottom | paddingLeft | borderRadius | borderTopLeftRadius | borderTopRightRadius | borderBottomRightRadius | borderBottomLeftRadius | maxWidth | maxHeight | borderWidth
    fxanimationDuration | transitionDuration | animationTimingFunction | transitionTimingFunction | animationDelay | transitionDelay | boxShadow
  11. t3 is dependent on it's predecessor. t3(t2)
    Compatibility-Table
    t2t3
    t2(typo)button | badge | link | label | header | paragraph | small | code | select | input | legend | quote | notification | tab | entry | caption
    t2(color) | t2(space) | t2(fx)t3(t2(typo)) | icon | boxed | side | image | popover | list | indicator | panel | row | column | cell | window
  12. t4 , t3 and t2 restrict the usage of the token to:
    • Only to be used on UI-Elements with similar names like t3 is.
    • Only to be used on such elements in a state, which names is similar to the name of what t4 is.
    • Only to be used on such elements in said state and on properties with a similar name of what t2 is.

    Refer to Sub-Token Usage on what t ' s usage should be.

    t5 then leaves room for the designer to define variants. For example differentiation between primary and secondary.

Euma Token Examples
Valid Euma Tokens
color.background.button.hover.default 
typo.fontFamily.button.normal.1  
fx.boxShadow.button.normal.default  
space.maxWidth.button.focus.1 
Invalid Euma Tokens

See if you can spot all six errors.

category.backgorund.button.hover.default  
typo.fontFamily.image.normal.1  
fx.box-shadow.button.normal.default  
space.maxwidth.button.focus.1  

Token Value Structure

What defines a token value?
  1. V is the actual value used in an application, tool, etc…, and not what is written in the file, where V is derived from. This V can also be derived differently, depending from application to application and from type to type. So let's call this, what is written in the file - at the storage place - the origin value ( O ). So the type of V depends on the application and is not acting within the same set of definitions of these rules, unlike the type of O . This makes it possible, so that T can act as a replacement for - something that is being replaced with - the V directly in the application.
  2. V is something T points to.
  3. V is non-unique. So it may also be referred to by other T .
  4. The type of O is inferred from T , the usage of V can also be inferred from T
  5. The type of O can be split into normative and non-normative ones. Normative ones are defined by the design token specification . This allows for easy interoperability and support between software application. Everything which is not standardized yet falls in the non-normative section. Those are heavily influenced by CSS types.
    • <normative> =
      <color> | <cubicBezier> | <dimension> | <duration> | <fontWight> | <number>
    • <non-normative> =
      <boxShadow> | <fontFamily> | <fontFeatureSettings> | <fontStyle> | <fontVariantCaps> | <fontVariantEastAsian> | <fontVariantLigatures> | <fontVariantNumeric> | <textAlign> | <textDecorationLine> | <textDecorationStyle> | <textUnderlinePosition>
  6. The type of O depends on the second sub-token ( t2 ).
    Compatibility-Table
    t2type of the O
    t2(color)<color>
    animationDuration | transitionDuration | animationDelay | transitionDelay<duration>
    animationTimingFunction | transitionTimingFunction<cubicBezier>
    t2(space) | fontSize | wordSpacing | letterSpacing | textDecorationThickness<dimension>
    every property not included abovetype with the same name as the property

Schema & Types

This section covers the details in what sort of schema the tokens are stored and what how the type dependent values are validated.

Token Schema

The Tokens are defined in JSON file. To save a token is simple, just start with t1 as the first key and create a new object under that key. Continue in the new object and repeat with t2 until all you reach t5 . So now we have no more sub-tokens to continue the chain with. Just an empty and dangling object.

So for T = color.background.button.hover.default we get this:

{
  "color": { 
  | "background": {
  | | "button": {
  | | | "hover": {
  | | | | "default": {}
  | | | }
  | | }
  | }
  }
}

This is where we want our O to be. Looking at the design token spec and using the correct type we want, we should arrive at something like this:

{
  "$type": "color",
  "$value": "#cdadf0",
  "$description": "use this for primary buttons"
}

Inserting this and adding a JSON Schema Path, to get autocompletion and error detection for our IDE, the final result looks like this:

{
  "$schema": "https://codeberg.org/39zde/euma/raw/branch/main/src/schema/tokens.schema.json",
  "color": {
  | "background": {
  | | "button": {
  | | | "hover": {
  | | | | "default": {
  | | | | | "$type": "color",
  | | | | | "$value": "#cdadf0",
  | | | | | "$description": "use this for primary buttons"
  | | | | }
  | | | }
  | | }
  | }
  }
}
Type Definitions

We already got a quick look at the <color> type. Let's take this as an example to take a deeper dive.

Like most types, value with the <color> type are valid, if they pass the test of a Regular Expression (regex) (Read up on what these are here or here ). So if "$type" is "color", then $value must get a positive evaluation from this regex:

^(#([0-9a-f]{2}){3,4})$

Translated, so that a human can understand, this means a $value passes, if it

  • begins with #
  • followed by 2 characters in a row, part of either a-f or 0-9
  • repeat this pattern, so there are in total 3 (min.) or 4 (max.) such duos in a row

If we check this with our example above, this #cdadf0 is indeed a valid color.

Values of some types are compared against a lookup table, but those are the minority. In the end the steps above happen automatically thanks to the the IDE in combination with the JSON Schema.

Sub-Token Usage

To allow the usage of a token to be inferred it's important to have some guides in place. These guides come in form of a short description for every subtoken.

Category
sub-tokenusage
coloreverything related to color
typoeverything related to typography
spaceeverything related to spacings, margins, and predefined shapes and dimensions
fxeverything related to animation/motion and effects (fx), shadows, filters and sound
Property
sub-tokenusage
backgroundthe background property for background-colors
borderthe border property
outlinethe outline property
textthe text property contains the text colors, to be more precise, the coloring/fill of the glyphs
textDecorationColorthe text property contains the text-decoration colors, behaves just like the CSS property
fontFamilythe font family
fontFeatureSettingsset flags to change the appearance of the font
fontSizethe font size
fontWeighthe font weight
fontVariantLigaturesthe ligature (joining of two characters into one shape) settings
fontVariantCapsthe caps (alternate glyphs used for small or petite capitals or for titling) settings
fontVariantNumericthe numeric (usage of alternate glyphs for numbers, fractions, and ordinal markers) settings
fontVariantEastAsianthe asian (the use of alternate glyphs for East Asian scripts, like Japanese and Chinese) settings
fontVariationSettingsfont settings for variable fonts
fontStylewhether a font should be styled with a normal, italic, or oblique face from its font-family
letterSpacingthe spacing between letters
wordSpacingsets the length of space between words and between tags.
textAlignthe text alignment
textDecorationLinethe kind of line that is used on text in an element, such as an underline or overline
textDecorationStylethe kind of style for the textDecorationLine that is used on text in an element
textDecorationThicknesssets the stroke thickness of the decoration line
textUnderlinePositionwhere the underline is positioned relative to the letters
margineven margin all around
marginTopthe top margin
marginRightthe right margin
marginBottomthe bottom margin
marginLeftthe left margin
marginBlockthe top and bottom margin
paddingeven padding all around
paddingTopthe top padding
paddingRightthe right padding
paddingBottomthe bottom padding
paddingLeftthe left padding
borderRadiusthe border/corner radius of all corners
borderTopLeftRadiusthe top left border/corner radius
borderTopRightRadiusthe the top right border/corner radius
borderBottomRightRadiusthe bottom right border/corner radius
borderBottomLeftRadiushe bottom left border/corner radius
maxWidthredefined max widths
maxHeightpredefined max heights
borderWidththe thickens of a border
animationDurationthe duration a an animation
transitionDurationthe duration of a transition
animationTimingFunctionanimation easing functions
transitionTimingFunctiontransition easing functions
animationDelaythe delay before the start of an animation
transitionDelaythe delay before the start of a transition
boxShadowbox/drop shadow
Element
sub-tokenusage
buttona button element
badgea badge element
labela label element
headera header text element
paragraphthe body text element, which is used the most
smalla small text element
codea code-text/preformatted-text element
selecta 'select one from many' element. Different from 'tab', which when pressed changes the content of the much of screen space
inputa text input element
legenda legend element
quotea quoted text element
notificationa notification element
tabelement in a set of similar items, ordered horizontally; horizontal version of entry
entryelement in a set of similar items, ordered vertically; vertical version of tab
captiondescription for another element
icona icon element
boxeda box element, which is used the most. Think of the HTML 'div' element
sidea side element, think of a sidebar, HTML 'aside', Androids 'Drawer'. A vertical element to the left or right of the main content
imagean image element
popovera popover/popup element, temporary visible
listthe list element, containing list items
indicatora indicator element, can be something like a dot besides text, a colored border,…
panela panel element. more distinct than the box element
rowa row element
columnthe column element
cellthe cell in a table. less distinct than the box element
windowthe window of an application
State
sub-tokenusage
hoverthe state when the cursor hovers over the element
focusthe state when the element is in focus
activethe state when the element is active, regarding plain text: it means it's selected
inactivethe state when the element is inactive, but more distinct than normal
normalthe state when the element is loading
loadthe state when the element is loading
blockthe state when the element is being blocked or can not proceed
successthe state when the element was successful in doing something
errorthe state when something is wrong with the element
warnthe state when something is wrong with the element
infothe state when the element wants to warn about something
newthe state when the element holds additional information
visitthe state when the element is was newly added
alertthe state when the elements needs immediate attention and want to alert about something, more distinct than warn
clickthe state when the element is being clicked
dragthe state when the element is being dragged
highlightvolatile, looses it's highlight after a short while, if unattended
Variant
sub-tokenusage
defaultthe default value variant for the state
1Variant 1 (Primary)
2Variant 2 (Secondary)
3Variant 3 (Tertiary)
4Variant 4 (Quaternary)
5Variant 5 (Quintary)
6Variant 6 (Senary)
7Variant 7 (Septenary)
8Variant 8 (Octonary)
9Variant 9 (Nonary)

Default Values

Everything on this page is actually styled be in line with the default values, so what are they exactly?

Armed with the knowledge from above we can now create our own UI-Theme.

Typography

Let's start with how we want to display texts.

Font Families
  • Source Serif 4 Display: display font

    for very large headers, extra crisp and nuanced

  • Source Serif Variable: serif font

    default header font

  • Source Sans Variable: sans-serif font

    default body font

    The font feature settings are slightly adjusted, to improve readability. The Lexend font was used as reference on what font feature settings to modify. In short: no ligatures, alt-character for 'a' and 'g' plus added serifs to the capital 'I' to better differentiate between 'l', slightly increased letter- and word-spacing, dotted zero '0' to better differentiate between 'O'.

    aglI0O - this is default
    aglI0O - this is Euma

    As to how much this improves readability remains to be seen. With that said, this all might be undone with with the text alignment set to 'justify'. I guess this is a tradeoff I'm willing to put up with… for now.

  • SourceCodeVF: monospace font

    default code font for data & numbers

Font Sizes

Viewport dependent font sizes. Try adjusting the viewport width somewhere between 420px and 1440px and observe the changes. The dynamic scaling is fully implemented in CSS, no JS required.

Normally the font-sizes adjust them self with the viewport width. But since this is a very new feature your browser does not support it yet. Try checking it out later or on another device. Currently on display is either nothing or the default font sizes. The numbers in the table are the would-be values, were your browser to support it.

Type Scale for your inner window size:
Font SizeSample Text

Hello, World!

Hello, World!

Hello, World!

Hello, World!

Hello, World!
Hello, World!

Hello, World!

Hello, World!
Hello, World!

Coloring

coming soon

Spacing

coming soon

Effects

coming soon

Acknowledgements