Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Pressmark, a fictional research archive, rendered entirely from this theme's tokens, grid and components

The international typographic style, web native. A stated type ratio with every size derived from it, twelve columns the layout confesses to, one grotesque doing all the work through weight and size, hairlines instead of boxes, and one red spent sparingly. Müller-Brockmann's grid work is the source. Vignelli's signage is the same discipline at the scale of a transit system. Grilli Type's site sits here now. Lineto's sits here.

This is the oldest register in the collection and the only one that has never been a trend. It was largely resolved by 1960 and has outlived every style it has watched arrive since. Adopting it is a bet that not much will happen to it in the next decade either.

The demo

The screenshot above is demo/index.html, a fictional research archive called Pressmark. Open it live, or clone the repo and open the file. There is no build step, no framework, no node_modules, and no server to start.

The demo declares no colour of its own. It links tokens/tokens.css, components/grid.css and components/components.css and reads every value from them, so it stays honest about what the theme actually produces.

It is deliberately text-dense. A register whose whole claim is grid discipline should be shown carrying a page that would fall apart without one, so the demo's centre is a record index rather than a feature grid. There is a section partway down called "The grid, shown" where the columns and the baseline are drawn over live content.

There is a second page worth opening: components/index.html renders the type scale and all five components with their variants and the markup to copy.

Position map

A visual style is a set of coordinates, not a mood. This theme sits at one point in the creative direction framework, which sets brand direction on four axes. Here is where this register lands and what each choice pays for.

Axis Position What the position buys
Tone register Professional A voice that carries weight without reaching for it. The page states what it holds and declines to sell it.
Aesthetic philosophy Editorial Restrained Type doing the work, whitespace composed rather than left over, and a colour count of two. Every element has to justify being on the page.
Audience relationship Authority Square corners, a masthead rule, and a hierarchy the reader does not get a vote on. The grid decides where the eye goes.
Sensory ambition Considered The discipline is visible without becoming the subject. Four appearances of the accent per page, placed where the composition wants them.

Those four position names are the exact strings the framework uses. If you want the long version of any of them, the links go to the position page.

Two of the four are worth arguing rather than asserting.

Authority rather than Peer. The founding claim of the style is that the designer is a neutral transmitter, which sounds like a refusal to talk down and therefore like Peer. It is not. The grid tells the reader where to look, the type scale tells them what matters, and neither is up for negotiation. That is the front of the room. What the position rules out is condescension, not hierarchy, and this register has never been condescending: it assumes a reader capable of reading a timetable.

Considered rather than Functional. This is the closer call, and it is close enough that CUSTOMIZE.md works the move between them as the theme's main axis move. The style is famous for saying that form follows function, which sounds like Functional on its face. But a Müller-Brockmann concert poster is not a page you get in and out of, and this theme ships the expressive settings: a major-third scale, generous gutters, an accent spent on composition rather than on status. Compress the scale, tighten the gutters and put the red to work and the same theme is at Functional. Nothing on the aesthetic axis moves while you do it, which is the clearest proof in the collection that the two axes are independent.

Quick start

Clone once, then pick the path that matches your stack.

git clone --depth 1 https://github.com/rampstackco/swiss-style-theme

Plain CSS. Copy the two directories and link three files in order. This is the whole install.

cp -r swiss-style-theme/tokens swiss-style-theme/components your-project/styles/
<link rel="stylesheet" href="/styles/tokens/tokens.css" />
<link rel="stylesheet" href="/styles/components/grid.css" />
<link rel="stylesheet" href="/styles/components/components.css" />

All three are load-bearing. Unlike the neobrutalism sibling, this theme has no optional layer to leave out; see below.

Tailwind v4. One import. theme.css pulls in tokens.css and maps it onto Tailwind's theme namespaces, so you get text-sw-h1, leading-sw-h1, tracking-sw-label, max-w-sw-measure.

@import "tailwindcss";
@import "./styles/tokens/theme.css";

All twelve namespaces in that file were compiled with Tailwind 4.2.2 and read back out of the generated CSS rather than checked against the documentation. All 56 utilities emit. The per-namespace results are in the file's header, along with the control runs and the harness sanity check.

The rule weights are worth a note, because the documentation is misleading about them and this repo got it wrong first time round. --border-width-* is absent from the v4 namespace table, which makes it look like a namespace that does not exist, and the adapter originally omitted it on that basis. It is processed anyway: the three entries generate border-sw-hair, border-sw-mid, border-sw-heavy and their side and axis forms, and a control build with those three lines removed loses all five. Undocumented and working is not the same as supported, so the adapter ships both routes and they compile to identical declarations:

<div class="border-t-sw-heavy">                  <!-- via the namespace -->
<div class="border-t-(length:--sw-rule-heavy)">  <!-- via the documented shorthand -->

The length: hint in the second form is load-bearing. Drop it and Tailwind resolves the utility to border-top-color, emitting a valid rule that sets the wrong property with nothing to tell you.

The twelve-column grid is mapped too, so grid-cols-sw produces the same track list .sw-grid does. It goes through --grid-template-columns-* rather than through the column count: --columns-* looks like the obvious home for a number like --sw-columns and it compiles happily, but it is the CSS multi-column property and sets something this theme never uses. That is the same trap as the border colour, and the header names both.

Tailwind v3. Load the tokens in your stylesheet, then register the preset. The v3 preset carries the rule weights properly, since v3 has a real borderWidth key.

@import "./styles/tokens/tokens.css";
@tailwind base;
@tailwind components;
@tailwind utilities;
// tailwind.config.js
module.exports = {
  presets: [require("./styles/tokens/preset.js")],
  content: ["./src/**/*.{html,js,jsx,ts,tsx}"],
};

Already on shadcn/ui. The tokens are namespaced --sw-* so they will not clobber yours. Bridge the two in your global stylesheet and shadcn's components inherit the register:

:root {
  --background: var(--sw-ground);
  --foreground: var(--sw-ink);
  --card: var(--sw-ground);
  --muted: var(--sw-ground-shade);
  --muted-foreground: var(--sw-ink-muted);
  --primary: var(--sw-ink);
  --primary-foreground: var(--sw-ground);
  --destructive: var(--sw-accent);
  --border: var(--sw-rule);
  --ring: var(--sw-focus);
  --radius: var(--sw-radius);
}

--primary maps to the ink rather than to the accent on purpose. Spending the register's one colour on the most repeated element on a site leaves nothing to mark the element that matters.

Where the reasoning lives

tokens/tokens.css is the single source of truth. Every literal value in the theme appears there exactly once; theme.css and preset.js hold no values of their own and point back at it with var(). Change a hex there and the demo, the components, the grid and both Tailwind adapters follow.

The file is annotated. Each group of tokens carries a comment naming the axis the choice serves and why, so the leading tokens explain themselves:

/* TYPE: LEADING, MEASURED IN BASELINES
   Aesthetic philosophy axis. Leading here is a length, not a ratio.

   A unitless line-height of 1.5 gives 24px on 16px type and 58.6px on the
   display step, and neither of those has any relationship to a grid. The
   register works the other way round: the grid is fixed first and the type is
   set into it, which is why a Müller-Brockmann grid is specified in lines per
   column rather than in leading ratios. */

Two things in that file are doing more work than a token file usually does.

The scale is executable. The seven type steps are calc() chains that each multiply the step below them by --sw-scale-ratio. The ratio is stated once, the derivation runs at render time, and the scale cannot drift out of true because there is nothing to drift. Changing the ratio moves all seven sizes in one line, which is what makes the worked move in CUSTOMIZE.md a one-line move.

Leading is measured in baselines, not ratios. Every leading token is a whole number of --sw-baseline, so every line box in the theme lands on the grid by construction. The useful consequence: because leading holds no reference to the type sizes, you can change the entire scale and the rhythm survives untouched.

CUSTOMIZE.md is the half-finished layer, and it is half-finished deliberately. It documents retheming as axis moves rather than as a colour picker: pick an axis, move along it, change the two or three tokens that carry the move. One move is worked through in full with before and after values. Two more are sketched so the format is obvious enough to finish yourself.

The grid layer

components/grid.css holds the part of this register that a token file cannot.

tokens.css can hold a size and it can hold a leading. What it cannot hold is the fact that they are one decision. Taking --sw-text-h2 without also taking --sw-leading-h2 puts the whole column off the rhythm from that heading down, and nothing in a list of custom properties says so. grid.css is where a size, its leading, its tracking and its weight ship as one class, so the pairing cannot come apart. The twelve-column grid lives there for the same reason: the container, the column count and the gutter are three tokens that only mean something together.

It also carries a rule that is easy to get wrong and invisible until you look for it. A rule takes its own border width back out of the padding beneath it, so the distance from the top of a rule to the first line under it is a whole number of baselines rather than a whole number plus a border. A 2px rule over 16px of padding puts everything below it two pixels off the grid, and every block after it inherits the error.

This layer is not optional. The neobrutalism sibling ships an extra file, play.css, that can be deleted whole, and deleting it is documented there as a real move along the sensory axis. This one is different. Delete grid.css and the tokens still resolve and the components still render, and what you have left is a page set in one grotesque with no system running underneath it. That is a page. It is not this register.

What is separable is the last section of the file: two classes, .sw-reveal-columns and .sw-reveal-baseline, that draw the columns and the baseline over live content. They are a development aid and they paint nothing that ships. They are in the box because in this register the skeleton is the argument, and a reader evaluating whether the discipline is real should not have to take it on trust. Turning the overlay on is the fastest way to find the block someone nudged four pixels to make something fit. It is how the rule-and-padding errors in this theme's own first draft were caught: every rule in the theme was pushing the block beneath it off the grid by exactly its own border width, which is invisible until something draws the grid next to it.

Consuming this from a Claude skill. The design-standards skill asks for a project's design tokens as a required input and offers to define a working set when none exist. Point it at tokens/tokens.css instead. The file already covers every category the skill asks for, in the order it asks: colour with measured contrast ratios, spacing scale, type scale, radius. Every text pairing in it clears WCAG AA, and the ratios are in the comments so the skill's contrast pass has nothing left to compute.

Registers get mixed rather than adopted whole, and this one mixes unusually well because it contributes structure rather than surface. A product can run this grid and this type scale underneath a surface treatment from glassmorphism-theme and stay coherent, which is intended use.

bento-grid-theme is the sibling that tests the claim from the other direction. It is a layout archetype, and its re-skin demo holds one arrangement still while swapping the surface tokens underneath it, including a quiet register read from this theme's own token file. If the layout and the surface are genuinely separable, that page is where it shows.

Adjacency: why this is not brutalism

Swiss style and brutalist web design both refuse ornament, and they refuse it for opposite reasons.

This register strips the page so the material comes through without interference. The restraint is hospitality: the grid, the scale and the single family exist to make dense information reachable, and every one of them is a service to the reader.

Brutalist web design strips the page to make the reader uncomfortable. Default browser styles, unstyled blue links, cramped measures, no concession offered. The discomfort is the argument, aimed at the polish of commercial web design.

The tell is what happens when a page in either register succeeds. This one becomes easy to read and stays out of the way. The other one stays difficult, because being difficult was the point.

If you came here looking for the hostile one, it is brutalist-web-theme, which is that argument made properly rather than a harsher version of this one.

License and questions

MIT. See LICENSE. Use it commercially, fork it, rename the tokens, ship it. No attribution required.

Issues and pull requests are welcome here. For questions, ideas, and anything conversational, use the discussions on the claude-skills repo, which is where all discussion for these repos lives.

About

Swiss international typographic style for the web: an executable modular scale, baseline rhythm, and a visible grid with a debug overlay. Tailwind and shadcn tokens plus a live demo.

Topics

Resources

Security policy

Stars

1 star

Watchers

1 watching

Forks

Contributors

Languages