← Design styles

Swiss

A grid, hairlines, square corners and no shadows: order and legibility first.

Rendered in designStyle("swiss"). Atlas terms: DS001, DS002.

Where it comes from

This style comes from mid-century print, where designers in a few European cities decided that a page should be built from a grid and a small, strict set of type sizes instead of from decoration. Everything was set flush on a column, hierarchy came from size and weight rather than from ornament, and white space was treated as a working part of the layout.

It travelled to screens because screens are grids too. Tables, forms, dashboards and documentation reward a layout where every element lines up, where one sans-serif family does all the work and where a thin rule is enough to separate two things. It reads as neutral, which is its strength in tools and its weakness in anything that needs a personality.

Written by us, in our own words, as background. It is not a claim about users.

Traits

Type

One neutral sans-serif family for body and display. Headings are bold with slightly tight tracking; small labels are uppercase with open tracking, so a label never competes with the heading above it.

--ca-font-sans --ca-font-display --ca-font-weight-heading --ca-heading-tracking --ca-label-case --ca-label-tracking

Colour

Mostly paper and ink. The brand colour is a single accent used for the one thing you want noticed; surfaces stay neutral so the grid, not the palette, carries the structure.

--ca-brand-fill --ca-surface-base --ca-surface-raised --ca-outline-default

Shape

Square corners everywhere and a visible one-pixel rule around surfaces (the outlined material). Controls are rectangles; nothing is a pill.

--ca-radius-scale --ca-border-width --ca-border-width-strong

Depth

None. Separation comes from rules and spacing, not from shadow, blur or tint, so a card and the page differ by a line, not by a lift.

--ca-shadow-sm --ca-shadow-md --ca-mat-edge

Motion

Short and plain. Transitions run at about 70% of the default duration with the standard curve; nothing bounces and nothing moves unless the state changed.

--ca-motion-scale --ca-ease-standard

Before and after, on real components

The same components twice: with the package default and with this style. Use the toggle to flip between them or put them side by side.

Same components, same markup. Only the tokens change.

designStyle("swiss")
Active Pending Overdue

As on your ID.

NameRoleStatus
Ana SouzaAdminActive
Bruno LimaEditorInvited
Carla DiasViewerActive

Do and don't

Do

  • Align everything to one column grid and one spacing scale, and let the gaps between groups be larger than the gaps inside a group.
  • Use size and weight for hierarchy before you reach for colour.
  • Keep one accent colour and spend it on the primary action of each screen.
  • Use a rule, not a shadow, to separate a surface from the page.

Don't

  • Do not add gradients, glows or rounded pills to soften it; the style is the absence of them.
  • Do not centre long text. Set it flush left on the grid.
  • Do not use more than two weights of the family on one screen.
  • Do not mistake plain for finished: neutral surfaces still need a clear focus state and states for hover, pressed and disabled.

These are our own guidance for using the recipe well. The accessibility items below carry their sources.

Accessibility pitfalls

Each item names what goes wrong, what the library already does about it and what is left to you.

Hairlines can fall below the contrast a control needs

Standard or guidelineW3C WAI 2023

A field that is only a pale one-pixel outline can fail the non-text contrast requirement even when the page looks tidy.

Scope: WCAG 2.2 criterion 1.4.11: meaningful visual cues, such as the boundary of an input, need 3:1 against the background. The criterion sets no minimum line width, so a thin line is allowed when its contrast is enough.

What to do. Keep control outlines on the stronger outline token (`--ca-outline-control`), not on the subtle divider token. The preset contrast test measures 3:1 for it in every built-in preset.

Tight, uppercase labels get hard to read when a user widens the spacing

Standard or guidelineW3C WAI 2023

Open uppercase tracking is safe by itself; clipping a label inside a fixed-height box is what breaks when a user applies their own spacing.

Scope: WCAG 2.2 criterion 1.4.12: no loss of content or function when a user sets line height to 1.5, letter spacing to 0.12 and word spacing to 0.16 times the font size. It constrains what breaks, not what the page must use.

What to do. Do not rely on a fixed box height for a label. Let the line grow when text spacing is overridden, which the components do by using min-height rather than height.

Components that fit

Tools, documentation, admin screens, reports and anything dense where people scan and compare. It tends to fit teams that want the interface to disappear behind the content.

Avoid it when: A product that has to be remembered for its look, a children's or entertainment audience, or a screen where one hero moment has to carry emotion.

Where it fits is our judgement from using the recipe, not a measured result.

  • SimpleTable: Rules and a column grid are what a dense table needs.
  • TextField: A rectangular outlined field reads clearly as an input.
  • Tabs: Line tabs on a hairline suit a grid layout.
  • Breadcrumb: Plain, aligned navigation text.

SimpleTable

ServiceRegionLatency
apieu-142 ms
workerus-2118 ms
searcheu-167 ms

TextField

Square, outlined, labelled.

Tabs

Overview content.

Breadcrumb

Overlays such as Dialog and Tooltip render in the page body, outside this style's subtree, so they are not shown here. Apply the style to the whole site to see them wear it.

The ThemeOptions recipe

One call in src/lib/theme.ts. Everything below is what the recipe sets; override any of it on top.

ts
import { designStyle, type ThemeOptions } from "@codeatlasdev/ui";

export const theme: ThemeOptions = designStyle("swiss");

With your own brand colour on top:

ts
import { designStyle, type ThemeOptions } from "@codeatlasdev/ui";

export const theme: ThemeOptions = designStyle("swiss", {
	presets: [{ id: "acme", color: "#ff5c00" }],
	defaultPreset: "acme",
});
Every knob this recipe sets
json
{
	"defaultStyle": "outlined",
	"radius": 0,
	"elevation": "none",
	"border": {
		"width": 1,
		"strong": 2
	},
	"fonts": {
		"body": "\"Helvetica Neue\", Helvetica, Arial, sans-serif",
		"display": "\"Helvetica Neue\", Helvetica, Arial, sans-serif"
	},
	"typography": {
		"weights": {
			"heading": 700,
			"semibold": 600
		},
		"headingTracking": "-0.01em",
		"labelCase": "uppercase",
		"labelTracking": "0.06em"
	},
	"motion": {
		"scale": 0.7,
		"easing": "standard"
	},
	"iconStroke": 1.5
}

Try it on this site

Try it on every page of this site, only in this browser. Nothing is published or changed for anyone else.

Prompt for your AI

Paste this into a coding agent. It carries the recipe, the limits and the accessibility rules.

markdown
Build this interface in the "Swiss" style with @codeatlasdev/ui: A grid, hairlines, square corners and no shadows: order and legibility first.

1. In src/lib/theme.ts export `theme = designStyle("swiss")` (import it from "@codeatlasdev/ui", or from "@codeatlasdev/ui/vite" in a file shared with vite.config). Add your brand as a preset on top: `designStyle("swiss", { presets: [{ id: "brand", color: "#…" }], defaultPreset: "brand" })`.
2. Use the library components as they are. Change the look only through ThemeOptions or `--ca-*` tokens: no `!important`, no overrides of `.ca-*` classes, no hard-coded colours.
3. The style's traits: type: One neutral sans-serif family for body and display. Headings are bold with slightly tight tracking; small labels are uppercase with open tracking, so a label never competes with the heading above it. Shape: Square corners everywhere and a visible one-pixel rule around surfaces (the outlined material). Controls are rectangles; nothing is a pill. Depth: None. Separation comes from rules and spacing, not from shadow, blur or tint, so a card and the page differ by a line, not by a lift. Motion: Short and plain. Transitions run at about 70% of the default duration with the standard curve; nothing bounces and nothing moves unless the state changed.
4. Do: Align everything to one column grid and one spacing scale, and let the gaps between groups be larger than the gaps inside a group. Use size and weight for hierarchy before you reach for colour. Keep one accent colour and spend it on the primary action of each screen. Use a rule, not a shadow, to separate a surface from the page.
5. Do not: Do not add gradients, glows or rounded pills to soften it; the style is the absence of them. Do not centre long text. Set it flush left on the grid. Do not use more than two weights of the family on one screen. Do not mistake plain for finished: neutral surfaces still need a clear focus state and states for hover, pressed and disabled.
6. Accessibility, which this style puts at risk: Hairlines can fall below the contrast a control needs. Keep control outlines on the stronger outline token (`--ca-outline-control`), not on the subtle divider token. The preset contrast test measures 3:1 for it in every built-in preset. Tight, uppercase labels get hard to read when a user widens the spacing. Do not rely on a fixed box height for a label. Let the line grow when text spacing is overridden, which the components do by using min-height rather than height.
7. Fits: Tools, documentation, admin screens, reports and anything dense where people scan and compare. It tends to fit teams that want the interface to disappear behind the content. Avoid it when: A product that has to be remembered for its look, a children's or entertainment audience, or a screen where one hero moment has to carry emotion.
8. Keep content, hierarchy and behaviour identical to a plain baseline so the two can be compared. Do not claim the style performs better; validate it with your users.
Docs: https://ui.codeatlas.com.br/styles/swiss/

References

  1. W3C WAI (2023). Understanding SC 1.4.11: Non-text Contrast. W3C WAI, WCAG 2.2 Understanding (Level AA).Standard or guideline

    Supports: Meaningful visual cues must achieve 3:1 against the background. The document notes authors do not control font smoothing and anti-aliasing, so evaluation uses the colors obtained from the user agent or the markup.

    Does not support: That thin lines are always inadequate. The document does not set a minimum line width.

    Checked 2026-10-25.

  2. W3C WAI (2023). Understanding SC 1.4.12: Text Spacing. W3C WAI, WCAG 2.2 Understanding (Level AA).Standard or guideline

    Supports: No loss of content or functionality occurs when a user sets line height to at least 1.5 times the font size, spacing after paragraphs to 2 times, letter spacing to 0.12 times and word spacing to 0.16 times, changing no other style property.

    Does not support: A requirement that the page itself uses those values; it must tolerate them when the user applies them. Languages and scripts that do not use a property are excepted.

    Checked 2026-10-25.