TimeNode

Foundations

Visual building blocks backed by semantic tokens - not raw hex or ramp step names.

Color

Use semantic color.* tokens for product UI. Avoid raw hex values in components.

Color palette contains full swatches and ramp references.

Quick rules

  • Start with surface.default for the page background.
  • Use container.low for sections and container.lowest for cards.
  • Use color.text for body copy and color.text.subtle for support text.
  • Use brand tokens only for actions, focus, and key status emphasis.

Surface stack

Build depth with tones, not heavy borders: canvas → section → card.

surface.default Page canvas
container.low Section background
container.lowest Cards and inputs

Core surface tokens

TokenValueRole
color.background.surface.default #f7f9fb App canvas
color.background.surface.container.low #f2f4f6 Sections within the canvas
color.background.surface.container.lowest #ffffff Cards and interactive surfaces
color.background.surface.container.high #e8ecef Secondary UI, progress tracks
color.background.surface.container.highest #dde2e6 Input field tracks

Text and brand tokens

TokenUsage
color.text Primary copy (do not use pure #000)
color.text.subtle Labels and sub-headers
color.text.brand Text on primary brand surfaces
color.background.brand.bold Primary action fill
color.background.brand.gradient Hero/CTA gradients when needed

Example

.my-section {
  background: var(--tn-color-background-surface-container-low);
}

.my-card {
  background: var(--tn-color-background-surface-container-lowest);
  color: var(--tn-color-text);
}

Typography

Inter (400-800) with a mobile-first scale for workforce dashboards - greeting, metric tiles, labels, and list rows.

Product typefaces and scale - full typescale table, OpenType guidance, and workforce preview mapping.

Spacing

Layout rhythm uses semantic space.* tokens with a numbered scale - not arbitrary pixel values. Token IDs map to CSS variables such as --tn-space-200.

Scale

TokenValueDesign scaleTypical use
space.00- Reset gutters
space.0504px1Tight inline gaps
space.1008px2List gaps
space.15012px3Compact stacks
space.20016px4Button padding
space.30024px6Card padding; pairs with squircle radius
space.40032px8Dense section padding
space.60048px12Section whitespace
space.80064px16Editorial section padding

When in doubt, increase whitespace - prefer space.600 or space.800 over cramming content.

.tn-card {
  padding: var(--tn-space-300);
  gap: var(--tn-space-100);
}

Elevation

Depth comes from tonal layering (surface tokens), not default drop shadows. Shadows and blur are reserved for floating UI that must read above the page.

When to use what

ApproachToken / patternUse
Default lift color.background.surface.container.lowest on …container.low Cards, panels, sections - primary depth model
Ambient shadow elevation.shadow.ambient Modals, floating action buttons only
Glass / blur elevation.backdrop.blur.default (20px) Top bars, floating nav
Subtle blur elevation.backdrop.blur.subtle (12px) Secondary floating elements

Do not stack more than three surface tiers; use glass for additional depth instead of more shadow.

.tn-fab {
  box-shadow: var(--tn-elevation-shadow-ambient);
}

.tn-top-bar {
  backdrop-filter: blur(var(--tn-elevation-backdrop-blur-default));
}

Border

TimeNode follows a no-line rule for layout: sectioning is done with surface color steps, not 1px rules between blocks.

Tokens

TokenValueWhen
border.width.none 0 Default - prefer tonal surfaces
border.width.ghost 1px With color.border.ghost - outdoor glare accessibility only
color.border.ghost 20% outline-variant Fallback edge when contrast on sunlit screens needs help
color.border.focus Brand emerald Focus rings
.tn-card--ghost-border {
  border: var(--tn-border-width-ghost) solid var(--tn-color-border-ghost);
}

Radius

Corners use semantic border.radius.* tokens. Squircle radius is the brand signature - do not use ad-hoc 4px or 8px radii on product UI.

Tokens

TokenValueUsage
border.radius.squircle 1.5rem (24dp) Cards, buttons, containers
border.radius.pill 9999px Input fields
.tn-card {
  border-radius: var(--tn-border-radius-squircle);
}

.tn-input {
  border-radius: var(--tn-border-radius-pill);
}