Install
$ agentstack add skill-peterhadorn-swiss-design-skill-swiss-design-skill ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Skill: Swiss Design (International Typographic Style for the Web)
1. What this skill produces
A website that feels Swiss before any word is read: orderly, generous, left-aligned, restrained, confident. Quality through structure and typography, not through effects. The output is agency-grade and looks deliberately built — not generated. It should be impossible to mistake the result for "another modern AI-template landing page."
This skill is the descendant of Müller-Brockmann, Ruder, and Hofmann translated into 2026 web idioms used by award-winning Swiss and Swiss-influenced agencies (Mobiliar, seoagentur.de, Doppio, favorit.studio, eseagency.ch, Stink Studios).
Use this skill when the brief calls for: "Swiss style," "International Typographic Style," "editorial-clean," "minimalist-premium," "agency-grade," "Mobiliar-conservative-cousin," "Notion/Linear sensibility but more disciplined." Pair with a brand-specific style file when the project has its own palette and voice.
2. The Swiss canon — what we are translating to web
The International Typographic Style emerged in Basel and Zurich in the late 1940s. Its core principles, distilled from Müller-Brockmann's Grid Systems and Ruder's Typography, are:
- Asymmetric balance on a strict grid. Symmetry is for ceremony; structure is for communication.
- Sans-serif, Swiss neo-grotesque. Akzidenz-Grotesk, Helvetica, Univers — and their modern descendants.
- Flush-left, ragged-right. Readability over decorative justification.
- Generous, deliberate whitespace. Whitespace is active — it carries information about hierarchy and rest.
- Objective photography over decoration. When images appear, they document; they do not embellish.
- Color is functional. A single deliberate accent over neutral substrate.
- Type carries the design. Decoration is forbidden; hierarchy comes from scale, weight, and spacing.
These are not aesthetic preferences. They are an information design discipline.
3. Absolute negative constraints (BANNED)
A design that contains any of the following has failed:
Banned typography
- Inter, Roboto, Open Sans, Arial, system-ui, Lato, Poppins. The AI-default tells. Use proper Swiss neo-grotesque or modern descendants (see §5).
- Decorative serif as body type. Editorial serif is permitted only for one display-scale moment per page (a hero, a pull quote).
- Monospace as a "techy aesthetic" shortcut. Monospace is for code, metadata, numerals — never as primary headline type unless the brand explicitly demands it.
- More than three weights across the entire site (typically Regular, Medium, Bold).
- More than two type families (one neo-grotesque + at most one editorial serif for accent moments).
Banned color
- Purple/blue gradients. The single most common AI-design fingerprint. Never appears in a Swiss design.
- Three-stop gradients in any direction (the "wine→coral→wine" ribbon energy).
- Multiple accent colors. One accent. Ever.
- Saturation above 80% on supporting accents.
#000000body type or#FFFFFFbackground as defaults — use ink (#111or#1A1A1A) on warm/neutral paper (#F7F6F3,#FAFAF7, or pure#FFFFFFwhen the brand demands it).- Dark sections randomly inserted into a light page (the "let's add visual variety" anti-pattern). Commit to the substrate.
Banned layout
- Centered hero blocks. Swiss design is left-aligned, ragged-right by canon.
- Three equal cards in a row as a feature section. (Use a 2-column zig-zag, asymmetric grid, or single-column flow.)
- Edge-to-edge sticky navbars with no breathing room.
100vh(use100dvhto prevent iOS Safari viewport jump).- Forced equal-height cards via flexbox when content varies.
- Symmetrical vertical padding on sections (bottom should usually be optically slightly larger than top).
- Two-column "text + image" grids for every content section. Default is single-column flow with images embedded inline.
- Width constraints on text elements (
max-widthon `,`, etc.). Width belongs on the container; text fills it.
Banned components / decoration
- Glassmorphism, neumorphism, claymorphism (anything *-morphism beyond restrained navbar blur).
- Generic thin-stroke icon libraries (Lucide / Feather / Heroicons stock). Use Phosphor (Bold/Fill), Radix UI Icons, or hand-drawn SVG primitives standardized to one stroke width.
- Drop shadows above
0.05opacity. Heavyshadow-md/shadow-lg. - Rounded-full pill containers for cards or large blocks. Round shapes (pill, circle) are reserved for action items only — primary CTAs, button-arrow wrappers, interactive chips. Eyebrows, tags, badges, and other static labels stay flat (no frame, or square corners if filled). A pill-bordered eyebrow reads like a tiny button and competes with the actual CTA.
rounded-3xlon everything. Vary radius — softer on outer containers, tighter on inner elements.- Decorative icons-with-rounded-corners above every heading. (The templated AI-tell.)
- Emojis. Anywhere. Including code, alt text, copy.
Banned 2026 AI-template fingerprints
- shadcn/ui defaults verbatim —
bg-zinc-950dark cards withborder-zinc-800, the "AI startup" aesthetic. Restyle if you must use shadcn primitives. - Tailwind UI hero patterns — centered hero with radial-gradient blur (the "Spotlight" template). Instantly readable as template.
- Vercel deploy template aesthetic — Inter + linear gradient mesh + dark glass card.
- Linear / Cal.com glass header —
backdrop-filter: blur(16px); background: rgba(...,0.6)outside one restrained nav use. - Bento grid as default layout — 3×2 cards-of-varying-sizes is now an AI tell. Use only when content genuinely demands it.
Banned motion
- Default
linearorease-in-outtransitions. Slop tells. window.addEventListener('scroll')for entry animations. Use CSSanimation-timeline: view()(preferred) orIntersectionObserver(fallback). See §8 pattern #6.- Animations that run continuously without dampening (rotating logos, pulsing CTAs, blinking arrows).
- Mounting all elements at once. Use staggered reveals.
- Ignoring
prefers-reduced-motion. Every animation must have a reduced-motion override (see §8).
Banned copy in design output
- AI-marketing clichés: "Elevate," "Seamless," "Unleash," "Next-Gen," "Game-changer," "Delve," "Empower," "Revolutionize," "Transform your business."
- Filler placeholders: "Lorem Ipsum," "John Doe," "Acme Corp."
- Vague promises ("powerful tools," "great results"). Specific or silent.
4. Grid system (Müller-Brockmann web)
Container
- Outer container: max-width
1200–1440px, centered with auto margins. - Side gutters:
clamp(1rem, 5vw, 2.5rem). - Inner content (text-heavy): typically nested in a
max-width: 720–860pxreading column, left-aligned within the outer container (not centered).
Column grid
- 12-column grid is the Swiss default.
- Use CSS Grid, not flexbox percentage math.
- Gutters between columns: 16–32px depending on density.
- Asymmetric occupation. Headline often takes columns 1–7; body takes 1–6; supporting visual takes 8–12. Never default to 50/50.
Vertical rhythm
- Define a modular spacing scale as CSS variables:
``css --space-xs: 0.5rem; /* 8px */ --space-sm: 1rem; /* 16px */ --space-md: 1.5rem; /* 24px */ --space-lg: 2.5rem; /* 40px */ --space-xl: 4rem; /* 64px */ --space-2xl: 6rem; /* 96px */ --space-3xl: 8rem; /* 128px */ --space-4xl: 12rem; /* 192px */ ``
- Section spacing:
--space-3xlto--space-4xlbetween major sections. Generous. The page should feel like a Swiss publication, not a feed. - Within a section: every gap (margin, padding, grid
gap) comes from the scale. Never raw pixel values. - Optical bias: bottom padding of a section is usually slightly larger than top (e.g.,
padding: var(--space-3xl) 0 var(--space-4xl)).
Hairline rules
- Section dividers, table rows, list separators:
1px solid var(--rule)— defined in §6 asoklch(92% 0.005 90)(≈#EAEAEA). These hairlines are a Swiss-design signature and replace heavy borders.
5. Typography
Font selection
Sans-serif (primary): A Swiss neo-grotesque. In order of preference:
- Suisse Int'l (commercial — Swiss Typefaces, ideal for Swiss brands)
- Neue Haas Grotesk (Helvetica's serious sibling)
- Helvetica Neue (system-available fallback, acceptable but tired)
- Söhne (Klim, modern Swiss-inspired)
- GT America (Grilli Type, modern American grotesk with Swiss DNA)
- Open-source fallbacks: Inter Tight (yes, Inter Tight, not default Inter — the tighter cut with proper grotesk character), Geist Sans, Switzer
Editorial serif (accent only): For one display-scale moment per page (hero pull, large quote). Options: Lyon Text, Newsreader, Instrument Serif, PP Editorial New. Apply tight tracking (-0.02em to -0.04em) and tight line-height (1.05–1.1).
Monospace (data only): Geist Mono, JetBrains Mono, IBM Plex Mono. For numerals in tables, code, metadata badges. Never as primary type.
Type scale
Use fluid clamp() so type breathes responsively:
--text-xs: clamp(0.75rem, 0.7rem + 0.2vw, 0.875rem); /* metadata, eyebrows */
--text-sm: clamp(0.875rem, 0.85rem + 0.2vw, 1rem);
--text-base: clamp(1rem, 0.95rem + 0.25vw, 1.125rem); /* body */
--text-lg: clamp(1.125rem, 1.05rem + 0.4vw, 1.375rem);
--text-xl: clamp(1.375rem, 1.25rem + 0.6vw, 1.75rem); /* H4 */
--text-2xl: clamp(1.75rem, 1.5rem + 1.2vw, 2.5rem); /* H3 */
--text-3xl: clamp(2.25rem, 1.8rem + 2.2vw, 3.75rem); /* H2 */
--text-4xl: clamp(3rem, 2.2rem + 3.5vw, 5.5rem); /* H1 */
--text-display: clamp(4rem, 2.5rem + 7vw, 10rem); /* viewport-bleeding hero */
Hierarchy via type, not decoration
- Headlines: tight tracking (
-0.02emto-0.04em), tight leading (1.05–1.15). - Body: line-height
1.55–1.7, letter-spacing0, max 65–75 characters per line. - Eyebrow tags:
text-xs, uppercase,letter-spacing: 0.18em–0.22em. No frame by default — just the typographic styling identifies them. If you must frame, use a small square filled chip (filled bg, no border, square corners). Never pill-bordered — that reads as a button and competes with the actual CTA. Always above H1/H2 to set rhythm. - Numerals in data: enable tabular figures (
font-variant-numeric: tabular-nums). - All-caps ONLY for eyebrows, micro-labels, and metadata. Never for body or H1/H2.
- Use medium (500) weight more than people expect — it's the workhorse weight in Swiss design (regular reads thin, bold reads heavy; medium is the editorial sweet spot).
- Fix orphans with
text-wrap: balance(headlines) andtext-wrap: pretty(body).
Baseline CSS (apply globally before any component)
html {
font-optical-sizing: auto; /* enables opsz axis in variable fonts */
text-rendering: optimizeLegibility;
-webkit-text-size-adjust: 100%;
hanging-punctuation: first last allow-end; /* Safari today; progressive */
}
body {
font-feature-settings: "kern" 1, "liga" 1, "calt" 1;
}
h1, h2, h3, h4 {
text-wrap: balance;
font-feature-settings: "kern" 1, "liga" 1;
}
p, li, figcaption, blockquote { text-wrap: pretty; }
Font loading — font-display: optional — never FOUT-flash. With optional, the browser swaps the custom font only if it loaded in the first ~100ms; otherwise the page renders in fallback and stays that way for the session. Premium Swiss-agency discipline:
@font-face {
font-family: 'Suisse Int\'l';
src: url('SuisseIntl-Variable.woff2') format('woff2-variations');
font-weight: 100 900;
font-display: optional;
}
Pair the fallback stack to match metrics (size-adjust, ascent-override, descent-override) so any swap is invisible.
Variable font intermediate weights — variable fonts allow sub-step precision:
h2 { font-weight: 450; } /* between Regular and Medium — very Swiss */
.eyebrow { font-weight: 520; }
.stat-label { font-weight: 480; }
OpenType features — Suisse Int'l, GT America, Söhne all carry alternates:
.headline-alt { font-feature-settings: "ss01" 1; } /* alt a, g forms */
.body-humanist { font-variant-numeric: oldstyle-nums; }
Hyphenation — Swiss print tradition. Web supports it natively. Set regional lang on the root: ` (or fr-CH, it-CH). The :lang() pseudo-class inherits through the DOM, so inline ` switches correctly:
:lang(de), :lang(de-CH) { hyphens: auto; hyphenate-limit-chars: 8 4 3; }
:lang(fr), :lang(fr-CH) { hyphens: auto; hyphenate-limit-chars: 10 4 3; }
:lang(it), :lang(it-CH) { hyphens: auto; hyphenate-limit-chars: 8 3 3; }
h1, h2, h3, .eyebrow { hyphens: none; } /* never on display type */
Color of type
- Body: off-black, never
#000. Use#111,#1A1A1A, or#2F3437. - Muted/secondary: a single neutral gray (warm-tinted if substrate is warm, cool if substrate is cool — never both). e.g.
#787774on warm bone paper. - Headlines: same off-black as body unless the brand explicitly uses an accent for display type.
6. Color — ink-on-paper philosophy
A Swiss design has at most four colors:
- Paper — the substrate.
#FFFFFF,#FAFAF7,#F7F6F3, or#F4F4F0. Warm-leaning off-white reads more print/Swiss; pure white reads more SaaS-clinical. Pick deliberately. - Ink — body and headline color.
#111,#1A1A1A, or#2F3437. Never#000. - Rule — hairline gray.
#EAEAEA,#E5E5E2, orrgba(0,0,0,0.06). - Accent — exactly one. Used for CTAs, links, the hero word the page wants you to remember, the active nav state. Saturation ` meta — without it, browser chrome (scrollbars, root background) stays light even when CSS switches:
Swiss-themed thin scrollbars (works in both schemes):
:root {
scrollbar-color: var(--rule) var(--paper);
scrollbar-width: thin;
}
@media (prefers-color-scheme: dark) {
:root {
--paper: oklch(12% 0.010 260); /* dark substrate, not #000 */
--ink: oklch(94% 0.005 90); /* warm off-white, not #fff */
--rule: oklch(20% 0.010 260);
/* --accent stays same hue; optionally bump lightness +5% */
}
.grain::before { mix-blend-mode: screen; opacity: 0.02; }
.ambient { opacity: 0.03; }
}
Brand variant: when the project has multiple brand colors
If the brand has two related shades (e.g., a deep and bright variant of the same hue), permit:
- Brand-deep used for primary type accents, dividers, the mark.
- Brand-bright used for hover states, active CTA, the single high-contrast moment.
- They must be from the same hue family. Three-color brand systems break this skill — drop one or use it only on the logo.
Texture, not gradients
- A subtle 3% film-grain noise overlay as a fixed background or section background is permitted — gives flat color physical-paper texture. SVG noise filter is preferred (one element, GPU-cheap).
- Single-color radial light at very low opacity (
opacity: 0.02–0.04) as aposition: fixed; pointer-events: noneambient layer is permitted as the "parallax" unifier (see §8 pattern #10). - Linear gradients, mesh gradients, animated gradients: banned.
7. Layout patterns
Hero — two modes only
Mode A — Typographic hero (no image).
- Big left-aligned headline (use
--text-displayor--text-4xl) over paper. - Subhead at
--text-lgor--text-xl, max 2 lines, generous line-height. - One primary CTA (arrow-in-circle pill, see §9), optional one secondary text link.
- Eyebrow tag above the H1 (uppercase micro-label, e.g., "WEB DESIGN AGENTUR").
- Optional: a single ambient layer behind (radial light, film grain, or subtle structural numerals like a section counter "01 / 06" in the corner).
**Mode B
…
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: peterhadorn
- Source: peterhadorn/swiss-design-skill
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.