# Swiss Design Style Guide
## Luke's Bullshit – Bluesky Portfolio

**Version:** 1.0
**Date:** November 2025
**Author:** Luke Steuber
**Based on:** Swiss/Bauhaus design principles + WCAG 2.1 AA accessibility

---

## Table of Contents

1. [Design Philosophy](#design-philosophy)
2. [Color System](#color-system)
3. [Typography](#typography)
4. [Grid System](#grid-system)
5. [Spacing & Rhythm](#spacing--rhythm)
6. [Components](#components)
7. [Accessibility](#accessibility)
8. [Content Guidelines](#content-guidelines)
9. [Implementation Checklist](#implementation-checklist)

---

## Design Philosophy

### Core Principles

**1. Form Follows Function**
Every design element serves a purpose. Ornament is eliminated.

**2. Mathematical Precision**
All measurements follow an 8px baseline grid. No arbitrary values.

**3. Extreme Color Discipline**
Only three colors: Black (#000000), White (#FFFFFF), Blue (#0D6EFD)

**4. Typography as Visual Element**
Hierarchy created through size, weight, and case—not color.

**5. Asymmetry Within Structure**
Grid provides order; content creates visual interest through placement.

**6. Zero Motion**
No transitions, animations, or parallax effects. Instant state changes only.

---

## Color System

### Palette

```css
:root {
  /* Primary Colors */
  --color-black: #000000;
  --color-white: #FFFFFF;
  --color-blue: #0D6EFD;    /* Darkened from #1185FE for WCAG AA compliance */

  /* Functional Grays (use sparingly) */
  --color-gray-light: #F5F5F5;  /* Backgrounds only */
  --color-gray-dark: #333333;   /* Secondary text (12.63:1 contrast) */

  /* Semantic Mappings */
  --bg-primary: var(--color-white);
  --bg-secondary: var(--color-gray-light);
  --text-primary: var(--color-black);
  --text-secondary: var(--color-gray-dark);
  --accent-color: var(--color-blue);
  --border-color: var(--color-black);
}
```

### Color Usage Rules

| Element | Background | Text | Border | Contrast Ratio |
|---------|------------|------|--------|----------------|
| Body | White | Black | — | 21:1 ✅ |
| Headers | White | Blue (#0D6EFD) | — | 4.52:1 ✅ |
| Buttons | White | Black | Black 3px | 21:1 ✅ |
| Buttons (hover) | Blue | White | Black 3px | 8.59:1 ✅ |
| Cards | White | Black | Black 3px | 21:1 ✅ |
| Cards (hover) | Blue | White | Black 3px | 8.59:1 ✅ |
| Skip Link | Black | White | Blue 16px | 21:1 ✅ |

**Critical Rule:** Blue (#0D6EFD) on white is ONLY for:
- Large text (≥18px or ≥14px bold)
- Interactive elements (buttons, links)
- Headers and section kickers

For normal body text on white backgrounds, use **black only**.

---

## Typography

### Font Family

```css
body {
  font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
  /* System fonts only - no Google Fonts CDN */
}
```

**Alternative (More Accessible):** Keep Inter font if Helvetica Neue creates readability issues for users with dyslexia.

### Type Scale (8px Baseline)

```css
:root {
  /* Font Sizes (all multiples of 8px or half-multiples) */
  --font-xs: 0.75rem;     /* 12px - Metadata only */
  --font-sm: 0.875rem;    /* 14px - Use sparingly, bold only */
  --font-base: 1rem;      /* 16px - Body text (WCAG minimum) */
  --font-lg: 1.125rem;    /* 18px - Large text threshold */
  --font-xl: 1.25rem;     /* 20px - Subheadings */
  --font-2xl: 1.75rem;    /* 28px - Section titles */
  --font-3xl: 2.5rem;     /* 40px - Page title */

  /* Line Heights */
  --line-height-tight: 1.2;   /* Headers only */
  --line-height-base: 1.5;    /* Body text (WCAG minimum) */
  --line-height-loose: 1.75;  /* Enhanced readability */

  /* Letter Spacing */
  --letter-spacing-tight: -0.02em;  /* Large headers */
  --letter-spacing-normal: 0;       /* Body text */
  --letter-spacing-wide: 0.05em;    /* Uppercase labels */

  /* Font Weights */
  --font-weight-normal: 400;
  --font-weight-bold: 700;
}
```

### Typography Hierarchy

```css
/* Body Text */
body {
  font-size: var(--font-base);
  line-height: var(--line-height-base);
  font-weight: var(--font-weight-normal);
  color: var(--text-primary);
}

/* Page Title */
h1 {
  font-size: var(--font-3xl);
  line-height: var(--line-height-tight);
  font-weight: var(--font-weight-bold);
  letter-spacing: var(--letter-spacing-tight);
  color: var(--text-primary);
}

/* Section Titles */
h2 {
  font-size: var(--font-2xl);
  line-height: var(--line-height-tight);
  font-weight: var(--font-weight-bold);
  letter-spacing: var(--letter-spacing-tight);
  color: var(--text-primary);
}

/* Project Titles */
h3 {
  font-size: var(--font-xl);
  line-height: 1.3;
  font-weight: var(--font-weight-bold);
  color: var(--text-primary);
}

/* Kickers (Labels) */
.site-kicker,
.section-kicker {
  font-size: var(--font-sm);
  line-height: 1.2;
  font-weight: var(--font-weight-bold);
  text-transform: uppercase;
  letter-spacing: var(--letter-spacing-wide);
  color: var(--accent-color);
}

/* Descriptions */
.project-description {
  font-size: var(--font-base);
  line-height: var(--line-height-base);
  font-weight: var(--font-weight-normal);
  color: var(--text-secondary);
  max-width: 60ch; /* Optimal reading length */
}
```

### Case Conventions

| Element | Case Rule | Example |
|---------|-----------|---------|
| Kickers | UPPERCASE | `BLUESKY` `FEATURED` |
| Section Labels | UPPERCASE | `MOST VISITED` `VISUALIZATIONS` |
| Headings | Title Case | `Featured Work` `Skymarshal` |
| Body Text | Sentence case | `Content manager for posts.` |
| Metadata | UPPERCASE | `2020–2025` `UPDATED DAILY` |

---

## Grid System

### 12-Column Grid

```css
.project-grid {
  display: grid;
  gap: 24px; /* 3 × 8px baseline */
  grid-template-columns: 1fr; /* Mobile: single column */
}

/* Tablet (≥640px) */
@media (min-width: 640px) {
  .project-grid {
    grid-template-columns: repeat(2, 1fr);
    gap: 32px; /* 4 × 8px baseline */
  }
}

/* Desktop (≥1024px) */
@media (min-width: 1024px) {
  .project-grid {
    grid-template-columns: repeat(3, 1fr);
    gap: 40px; /* 5 × 8px baseline */
  }
}
```

### Container Widths

```css
.site-header,
.main-content {
  max-width: 1200px; /* 150 × 8px */
  margin: 0 auto;
  padding: 24px; /* 3 × 8px */
}

@media (min-width: 640px) {
  .site-header,
  .main-content {
    padding: 40px; /* 5 × 8px */
  }
}
```

---

## Spacing & Rhythm

### 8px Baseline Grid

All spacing uses multiples of 8px:

```css
:root {
  --spacing-xs: 8px;    /* 1 unit */
  --spacing-sm: 16px;   /* 2 units */
  --spacing-md: 24px;   /* 3 units */
  --spacing-lg: 32px;   /* 4 units */
  --spacing-xl: 40px;   /* 5 units */
  --spacing-2xl: 48px;  /* 6 units */
  --spacing-3xl: 64px;  /* 8 units */
}
```

### Spacing Usage

| Context | Spacing |
|---------|---------|
| Gap between cards | `--spacing-md` (24px) |
| Section margins | `--spacing-xl` (40px) |
| Card padding | `--spacing-md` (24px) |
| Element gaps within cards | `--spacing-sm` (16px) |
| Page padding (mobile) | `--spacing-md` (24px) |
| Page padding (desktop) | `--spacing-xl` (40px) |

---

## Components

### Skip Link (Bauhaus Asymmetric)

```css
.skip-link {
  position: absolute;
  top: -60px;
  left: 0;

  /* Colors */
  background: var(--color-black);
  color: var(--color-white);

  /* Bauhaus asymmetric geometry */
  padding: 16px 32px;
  padding-left: 48px; /* Asymmetric emphasis */

  /* Heavy border with blue accent */
  border: 4px solid var(--color-white);
  border-left-width: 16px;
  border-left-color: var(--accent-color);
  border-radius: 0; /* No rounded corners */

  /* Typography */
  font-weight: var(--font-weight-bold);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  text-decoration: none;

  /* Layering */
  z-index: 100;
}

.skip-link:focus {
  top: 0;
  outline: none; /* Custom border handles focus */
}
```

### Toggle Button (Pure Geometric)

```css
.toggle-button {
  /* Geometry */
  width: 44px;  /* WCAG minimum touch target */
  height: 44px;
  border-radius: 0; /* Sharp corners */

  /* Colors */
  background: var(--color-white);
  color: var(--color-black);
  border: 3px solid var(--color-black);

  /* Layout */
  display: flex;
  align-items: center;
  justify-content: center;

  /* Typography */
  font-size: 1.75rem;
  font-weight: 300; /* Thin weight for + and − */
  line-height: 1;
  font-family: 'Helvetica Neue', sans-serif;

  /* Interaction */
  cursor: pointer;
  user-select: none;
  transition: none; /* Zero motion */
}

.toggle-button:hover {
  background-color: var(--accent-color);
  color: var(--color-white);
  border-color: var(--color-black);
}

.toggle-button:focus-visible {
  outline: 4px solid var(--color-black);
  outline-offset: 4px;
  z-index: 10;
}
```

### Project Card

```css
.project-card {
  /* Geometry */
  border-radius: 0; /* Sharp corners */
  border: 3px solid var(--color-black);
  padding: var(--spacing-md);
  min-height: 44px; /* WCAG touch target */

  /* Colors */
  background: var(--color-white);
  color: var(--text-primary);

  /* Layout */
  display: block;
  text-decoration: none;

  /* Remove shadows */
  box-shadow: none;

  /* Interaction */
  transition: none; /* Zero motion */
}

.project-card:hover,
.project-card:focus {
  background-color: var(--accent-color);
  color: var(--color-white);
  border-color: var(--color-black);
  text-decoration: none;
}

.project-card:hover .project-description {
  color: var(--color-white); /* Override secondary text color */
}

.project-card:focus-visible {
  outline: 4px solid var(--color-black);
  outline-offset: 4px;
}
```

### Badge Links (Header)

```css
.badge-link {
  /* Geometry */
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 16px;
  border: 2px solid var(--color-black);
  border-radius: 0; /* Sharp corners */

  /* Colors */
  background-color: var(--color-white);
  color: var(--text-primary);

  /* Typography */
  font-size: var(--font-sm);
  font-weight: var(--font-weight-bold);
  text-decoration: none;

  /* Touch target */
  min-height: 44px;

  /* Interaction */
  transition: none;
}

.badge-link:hover,
.badge-link:focus {
  background-color: var(--accent-color);
  color: var(--color-white);
  border-color: var(--color-black);
  text-decoration: none;
}
```

---

## Accessibility

### WCAG 2.1 AA Compliance

All components meet or exceed WCAG 2.1 AA standards:

#### Color Contrast Requirements

- ✅ **Normal text**: 4.5:1 minimum (we use 21:1 black on white)
- ✅ **Large text**: 3:1 minimum (we use 4.52:1 blue on white)
- ✅ **Interactive elements**: 3:1 against adjacent colors

#### Focus Indicators

```css
*:focus-visible {
  outline: 4px solid var(--color-black);
  outline-offset: 4px;
}
```

**Why this works:**
- High contrast (21:1 black outline on white background)
- Geometric (sharp rectangular outline, not rounded)
- Offset creates breathing room (4px separation)
- Meets WCAG 2.4.7 (Focus Visible)

#### Touch Targets

All interactive elements maintain **44×44px minimum**:
- Buttons: 44×44px squares
- Links: min-height: 44px
- Cards: min-height: 44px

#### Keyboard Navigation

- Skip link appears on focus
- All interactive elements reachable via Tab
- Space/Enter activates buttons
- ARIA attributes preserved:
  - `aria-expanded` on toggle buttons
  - `aria-controls` linking buttons to content
  - `aria-label` on icon-only elements
  - `role="img"` on emoji icons

#### Screen Reader Support

```html
<!-- Emoji with proper semantics -->
<span class="project-icon" role="img" aria-label="Content management icon">☁️</span>

<!-- Toggle buttons with state -->
<button aria-expanded="false" aria-controls="viz-content" aria-label="Toggle Visualizations section">
  <span class="toggle-icon">+</span>
</button>

<!-- External links with security -->
<a href="..." target="_blank" rel="noopener noreferrer" aria-label="Personal website">
  lukesteuber.com
</a>
```

#### Motion Sensitivity

- **Zero CSS transitions** (`transition: none`)
- **Zero animations** (no `@keyframes`)
- **Zero parallax effects**
- Instant state changes only

This respects `prefers-reduced-motion` by default.

---

## Content Guidelines

### Voice & Tone

- **Voice:** Direct, unpretentious, slightly irreverent
- **Tone:** Informative first, entertaining second
- **POV:** First person ("I built this") not third person ("We offer")

### Principles

1. **Clarity over cleverness** — If a joke obscures function, cut it
2. **Brevity beats verbosity** — Two short sentences > one compound sentence
3. **Precision, not jargon** — "Content manager" not "solution suite"
4. **Show, don't tell** — "Delete posts in bulk" not "powerful deletion capabilities"

### Description Structure

All project descriptions follow this 2-line pattern:

```
[Category/Type]
[Specific features or purpose]
```

**Example:**
```
Content management tool.
View and delete posts individually or in bulk.
```

### Forbidden Phrases

- ❌ "Powerful tool for..."
- ❌ "Seamlessly integrate..."
- ❌ "Leverage cutting-edge..."
- ❌ "Created with Claude" / "AI-assisted"

### Encouraged Phrases

- ✅ "I built this to..."
- ✅ "Tools I made"
- ✅ "Work archive"

### Content Examples

#### Site Header
```html
<div class="site-kicker">BLUESKY</div>
<h1 class="site-title">Luke's Bullshit</h1>
<p class="site-meta">SELECTED WORK 2020–2025</p>
```

#### Section Headers
```html
<p class="section-kicker">MOST VISITED</p>
<h2 class="section-title">Featured Work</h2>
```

#### Project Cards
```html
<!-- Skymarshal -->
<h3>Skymarshal</h3>
<p>Content management tool. View and delete posts individually or in bulk.</p>

<!-- Accessibility List -->
<h3>Accessibility Resources</h3>
<p>Comprehensive developer index. Likely the longest. I keep adding to it.</p>

<!-- BipolarSky -->
<h3>BipolarSky</h3>
<p>Mental health resources. Feed links, infographics, references.</p>

<!-- go science! -->
<h3>go science!</h3>
<p>Academic literature review series. Maximum sarcasm.</p>
```

---

## Implementation Checklist

### Pre-Implementation

- [x] Review all design documentation
- [x] Create backup of current index.html
- [x] Run low-hanging-fruit code audit
- [ ] Review this style guide completely

### Phase 1: Color & Typography

- [ ] Update CSS variables to Swiss palette (black/white/blue)
- [ ] Verify #0D6EFD blue contrast ratios
- [ ] Replace Inter with Helvetica Neue (or keep Inter for accessibility)
- [ ] Apply 8px baseline grid to all font sizes
- [ ] Update line-heights to WCAG minimum (1.5 for body)
- [ ] Add letter-spacing to uppercase elements
- [ ] Test color contrast with WebAIM checker

### Phase 2: Geometry

- [ ] Remove all `border-radius` values (set to 0)
- [ ] Replace box-shadows with 3px solid borders
- [ ] Update toggle buttons to 44×44px squares
- [ ] Ensure all cards have min-height: 44px
- [ ] Make badge links rectangular

### Phase 3: Spacing

- [ ] Convert all spacing to 8px multiples
- [ ] Update grid gaps (24px mobile, 32px tablet, 40px desktop)
- [ ] Apply consistent padding to cards (24px)
- [ ] Update section margins (40px between sections)

### Phase 4: Focus Indicators

- [ ] Implement geometric border system (4px black outline)
- [ ] Add 4px outline-offset for breathing room
- [ ] Test keyboard navigation (Tab through all elements)
- [ ] Verify focus visible on all backgrounds
- [ ] Update skip link to asymmetric Bauhaus style

### Phase 5: Content

- [ ] Update section kickers to UPPERCASE
- [ ] Add site metadata line (`SELECTED WORK 2020–2025`)
- [ ] Rewrite project descriptions to 2-line fragments
- [ ] Update ARIA labels to describe function, not decoration
- [ ] Add `role="img"` to all emoji icons
- [ ] Fix Twitter meta tag typo ("Blue Sky" → "Bluesky")

### Phase 6: Dead Code Removal

- [ ] Remove unused footer styles (lines 348-382)
- [ ] Consolidate duplicate CSS variables
- [ ] Remove console.log from production
- [ ] Fix indentation inconsistencies

### Phase 7: Testing

- [ ] **Automated Tools:**
  - [ ] axe DevTools (no violations)
  - [ ] WAVE (no errors)
  - [ ] Lighthouse Accessibility score ≥95
  - [ ] WebAIM Contrast Checker

- [ ] **Manual Testing:**
  - [ ] Keyboard navigation (Tab, Shift+Tab, Enter, Space)
  - [ ] Screen reader (NVDA/JAWS/VoiceOver)
  - [ ] Mobile devices (320px width minimum)
  - [ ] Responsive breakpoints (640px, 1024px)
  - [ ] High contrast mode (Windows)
  - [ ] Browser zoom (200%, 400%)

- [ ] **Color Vision Testing:**
  - [ ] Deuteranopia simulation
  - [ ] Protanopia simulation
  - [ ] Tritanopia simulation

### Phase 8: Documentation

- [ ] Update CLAUDE.md with Swiss design notes
- [ ] Document changes in UPDATE_LOG.md
- [ ] Create before/after screenshots
- [ ] Add commit message documenting transformation

---

## Success Criteria

The redesign is successful when:

1. ✅ **WCAG 2.1 AA compliance**: 100% (non-negotiable)
2. ✅ **Color palette**: Only black, white, blue used
3. ✅ **Border-radius**: Zero (all sharp corners)
4. ✅ **Motion**: Zero transitions or animations
5. ✅ **Typography**: Helvetica Neue or Inter with 8px scale
6. ✅ **Grid**: 12-column responsive grid functioning
7. ✅ **Focus indicators**: Geometric, high-contrast, visible
8. ✅ **Touch targets**: All ≥44px minimum
9. ✅ **Content**: Swiss-brief descriptions, UPPERCASE kickers
10. ✅ **Aesthetics**: Clean, authoritative, mathematically precise

---

## References

- **Swiss Design History**: International Typographic Style (1950s)
- **Bauhaus Principles**: Form follows function, asymmetry, geometry
- **WCAG 2.1**: https://www.w3.org/WAI/WCAG21/quickref/
- **WebAIM Contrast Checker**: https://webaim.org/resources/contrastchecker/
- **Nielsen Norman Group**: Evidence-based UX research
- **Example Sites**: dr.eamer.dev/firehose (Swiss implementation)

---

## Version History

- **v1.0 (Nov 2025)**: Initial Swiss design system created
- Design team: accessibility-specialist, design-lead, ux-researcher, ux-writer
- Based on comprehensive UX research and accessibility audit

---

**End of Style Guide**

For implementation details, see:
- `TRANSFORMATION_PLAN.md` - Strategic roadmap
- `IMPLEMENTATION_GUIDE.md` - Step-by-step code changes
- `SWISS_DESIGN_UX_RESEARCH.md` - Evidence-based research
- `USER_TESTING_PROTOCOL.md` - Testing procedures
