Project

its-swiss

0.0
The project is in a healthy, maintained state
Tokens, reset, typography, grid primitives and components in the spirit of the International Typographic Style, as plain CSS plus a Rails engine that ships it. Monochrome by default: the value scale does the work and the one accent is the consuming application's to set.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Runtime

>= 8.0, < 10
>= 2.0, < 4
>= 1.0, < 3
>= 8.0, < 10
 Project Readme

its-swiss

sensible Swiss defaults for Rails

Tokens, reset, typography, grid primitives and components in the spirit of the International Typographic Style, as plain CSS plus a Rails engine that ships it. Monochrome by default: the value scale does the work, and the one accent is the consuming application's to set.

quickstart

# Gemfile
gem "its-swiss", github: "bobbymeyer/its-swiss"
bundle install
bin/rails generate its_swiss:install

The generator fills the four slots an application owns:

It writes Which is
app/assets/stylesheets/theme.css The accent, the typeface, the value scale, the field count, the baseline
app/views/layouts/application.html.erb A nested layout inside the shell — no layout line on any controller
A route for the specimen Development only; skipped if already mounted

Everything else is a gem dependency: Propshaft finds the stylesheets, and the engine pins its own JavaScript, so upgrading the gem is enough.

Specimen → — every component, the type scale, the value scale and the grid primitives, rendered by the library and published from this repository.

the shell

layouts/its_swiss/shell carries the view-transition opt-in, the stylesheets in layer order, a skip link, and the slots. All optional:

Slot Is
:title The page's title; falls back to the application's name
:head Anything else belonging in <head>
:mark The wordmark. No mark and no nav means no masthead at all
:nav The destinations
:subnav A second layer, inside the one you are in
:main_class What the page's main region is, if it is a grid
:footer Whatever belongs after the page

It stops there. A page layout beyond the shell is the application's, for the same reason its grid is.

tokens

Set in theme.css; everything else reads them.

Group Custom properties
Value scale --value-chroma, --value-hue, --value-0 … --value-5
Roles --paper, --paper-shaded, --rule, --rule-strong, --ink-quiet, --ink, --accent, --accent-ink
Rules --rule-hair, --rule-heavy
Type --font-family, --font-mono, --face-100, --face-150, --face-200, --face-mono, --cap-correction
Scale --size-1 … --size-5
Baseline --line, --line-2, --line-3, --line-4, --half-line, --module
Space --space-unit, --space-1, --space-2, --space-3, --space-4, --space-6, --space-8
Page --columns, --gutter, --page-max, --page-inset, --field
Measure --measure, --measure-characters, --card, --filter-label
Transitions --transition-page, --transition-morph, --transition-ease

grid primitives

.page, .grid, .run, .stack, .modules, .fields, .measure.

components

Class Is
.masthead, .nav, .subnav, .menu, .menu--current, .skip-link Navigation
.page-head, .sections, .footer Page furniture
.button, .button--primary, .button--quiet, .button--danger Buttons
.form, .form--inline, .form--dense, .field, .field--inline, .field--invalid, .choice, .errors Forms
.filters, .filter Filter bars
.cards, .card Cards
.table, .numeric Tables
.pairs, .pairs--stacked Definition pairs
.figure, .figure--cover, .figure--modular Figures
.pagination Pagination
.md, .measure, .copy, .explain, .link-quiet, .empty Prose and states
.css, .components, .visually-hidden, .no-metric-overrides, .rule--heavy Utilities

helpers

Helper Does
its_swiss_form_with The form builder
its_swiss_stylesheet_tags The seven stylesheets, in layer order
its_swiss_page_numbers Page numbers for pagination
its_swiss_application_name The application's name
its_swiss_face, its_swiss_typeface The typeface slots
page_head, page_sections Page head and section destinations
nav_link_to, nav_menu Navigation
search_form, filter_register Filter bars
copy_button A value that copies itself
explain An explanatory note

Partials: its_swiss/shared/masthead, flash, errors, pagination.

form builder

its_swiss_form_with adds field, select, collection_select, check_box, radio_button, text_area and submit, each rendering its own label, hint and error, wired with aria-describedby.

JavaScript

Three Stimulus controllers, registered by the module the shell imports. The host adds nothing to its importmap.

Controller Does
its-swiss-clipboard A value that copies itself
its-swiss-live-search Search on an index
its-swiss-mono Monospace metric handling

the cascade

Every file states its own layer, and the order is declared before the first import:

@layer its-swiss.tokens, its-swiss.faces, its-swiss.reset, its-swiss.type,
       its-swiss.grid, its-swiss.components, its-swiss.transitions;

Everything is inside @layer, so any application rule wins without effort. A stylesheet the application adds after the library takes its place in the order from where its layer is first named.

its-swiss.css is the whole library in one <link>; the Rails helper writes the seven separately. Both resolve identically.

tech

Rails engine, v1.1.0. Ruby >= 3.2. 1,457 lines of CSS in seven files. No build step and no CSS framework.

bundle exec rake test

150 runs. 30 of them drive a real browser through Capybara and Selenium, and need a Chrome matching the installed ChromeDriver. The specimen is measured in Chromium, WebKit and Firefox before it is published.

license

MIT.