# BH Tools — Master Design System

> **The single source of truth.** Paste this file into any AI tool (Lovable, Claude, Cursor) or drop it into `/docs/design-system.md` to keep every build on-brand. If something is not specified here, default to the closest rule rather than inventing a new style.

**One-line brief:** Editorial, warm, confident, operator-grade. Fraunces serif display + JetBrains Mono labels on a warm cream canvas. Hard offset shadows, sharp 1.5px borders. Calm and opinionated. Light theme only. Aligned with the Rize Master Design System.

---

## 0. How to use this file

**In an AI prompt (Lovable, Claude, Cursor):** paste the whole file and say *"Build X using the BH Tools Design System above. Follow the tokens and component patterns exactly."* For strongest results, attach a finished BH mockup as a visual reference.

**In a codebase:** copy the `:root` block into your global CSS. Everything keys off CSS variables.

**The five rules that keep it consistent:**
1. Two fonts only: Fraunces (all display + body) + JetBrains Mono (all labels). Never a third.
2. Color comes from the token list only. Never hand-pick a hex.
3. Borders are `1.5px solid var(--ink)`. Shadows are hard offsets, never blurred.
4. Headings are Fraunces 900 with tight negative letter-spacing. One italic rust accent per heading, never more.
5. Labels, eyebrows, buttons, captions = JetBrains Mono, uppercase, letter-spaced. Body and display = Fraunces.

---

## 1. Design Principles

- **Editorial, not corporate.** Feels like a well-set magazine meets an operator's notebook. Serif headlines, generous space, real hierarchy.
- **Warm, not sterile.** Tan/cream canvas. Never cold white or dark-mode gray.
- **Operator voice.** Direct, confident, specific. No hype words. Real things to get done.
- **Honest.** Mark illustrative data as illustrative. Trust is the moat.
- **Hard edges.** No gradients, no blur, no soft shadows. Everything is flat and bordered.

---

## 2. Tokens — paste verbatim into global CSS

```css
:root {
  /* ink / text */
  --ink:          #1c1c20;   /* primary text, borders, hard shadows */
  --ink-dim:      #52524c;   /* secondary text, ledes */
  --ink-dimmer:   #8a8a82;   /* captions, placeholders, disclaimers */

  /* canvas */
  --bg:           #f4f3ef;   /* page background — warm cream */
  --bg-warm:      #ede9e2;   /* insets, band headers, card header strips */
  --panel:        #fafaf6;   /* card / raised surface — never pure #fff */

  /* lines */
  --line:         #dcd8d0;   /* hairline dividers */
  --line-2:       #cac4b8;   /* input borders, stronger lines */

  /* accents */
  --rust:         #c44d2e;   /* PRIMARY — CTAs, italic emphasis, active states */
  --rust-soft:    #faeae4;   /* rust tint background for callouts */
  --olive:        #5c6b3f;   /* positive / success / approve */
  --olive-bg:     #eef1e8;
  --gold:         #b88a1f;   /* warning / highlight / reward */
  --gold-bg:      #f5edd8;
  --slate:        #5e7a8a;   /* neutral / info / secondary data */
  --slate-bg:     #eaf0f3;
  --green:        #2f7d3e;   /* money-positive */
  --green-bg:     #e6f2e9;
  --bad:          #b54a3d;   /* error / reject / destructive */

  /* hard shadows — NEVER blurred */
  --shadow-sm:    3px 3px 0 var(--ink);    /* default — cards, buttons */
  --shadow:       6px 6px 0 var(--ink);    /* emphasized cards */
  --shadow-lg:    10px 10px 0 var(--ink);  /* hero frames only */
}
```

---

## 3. Typography

**Load both fonts, use only these:**
```html
<link href="https://fonts.googleapis.com/css2?family=Fraunces:ital,opsz,wght@0,9..144,400..900;1,9..144,400..900&family=JetBrains+Mono:wght@400;500;700&display=swap" rel="stylesheet">
```

**Fraunces** (serif) — all display headlines AND body copy. Use italic for accent words and lede copy.
**JetBrains Mono** — all labels, eyebrows, buttons, pills, nav links, captions. Always uppercase + letter-spaced when used as a label.

**Body default:**
```css
body {
  font-family: 'Fraunces', serif;
  font-size: 16px;
  line-height: 1.6;
}
```

**Type scale:**

| Role | Font | Size | Weight | Letter-spacing | Notes |
|---|---|---|---|---|---|
| Hero H1 | Fraunces | 58px | 900 | -0.04em | line-height 0.98 |
| Section title | Fraunces | 44px | 900 | -0.035em | line-height 1.04 |
| Card / panel heading | Fraunces | 17–20px | 800 | -0.02em | italic |
| KPI / stat number | Fraunces | 40–42px | 900 | -0.03em | italic, colored |
| Lede / subline | Fraunces | 18–19px | 400 | normal | italic, --ink-dim |
| Body | Fraunces | 16px | 400 | normal | line-height 1.6 |
| Eyebrow / kicker | JetBrains Mono | 11px | 700 | 0.16em | uppercase |
| Button | JetBrains Mono | 11–12px | 700 | 0.08em | uppercase |
| Small label | JetBrains Mono | 9–10px | 700 | 0.06–0.1em | uppercase |
| Disclaimer | JetBrains Mono | 8.5px | 700 | 0.1em | uppercase |

**The signature heading move:** Fraunces 900 upright, one italic word in `--rust`. One accent per heading only.
```html
<h2 class="sec-title">Build the <em>AI Mind.</em></h2>
```
```css
.sec-title { font-family:'Fraunces',serif; font-weight:900; font-size:44px; line-height:1.04; letter-spacing:-0.035em; }
.sec-title em { font-style:italic; color:var(--rust); }
```

---

## 4. Logo Mark

**Mark:** "BH" in a rust square. Fraunces 900 upright (not italic). Hard 2px ink shadow. 3px radius.
**Wordmark:** "Better Human Tools" — Fraunces 800 upright, "Tools" in italic rust.
**Byline:** "By Colin Stuckert" — JetBrains Mono 8.5px, uppercase, letter-spaced, --ink-dimmer. Sits directly below the wordmark.

```html
<a class="logo" href="/">
  <div class="mark">BH</div>
  <div class="logo-text">
    <h1>Better Human <em>Tools</em></h1>
    <span class="byline">By Colin Stuckert</span>
  </div>
</a>
```

```css
.logo { display:flex; align-items:center; gap:12px; text-decoration:none; }
.logo .mark {
  width:38px; height:38px; background:var(--rust);
  border:1.5px solid var(--ink); box-shadow:2px 2px 0 var(--ink);
  border-radius:3px; display:flex; align-items:center; justify-content:center;
  font-family:'Fraunces',serif; font-style:normal; font-weight:900;
  font-size:14px; letter-spacing:-0.02em; color:#fff; line-height:1;
}
.logo-text { display:flex; flex-direction:column; gap:2px; }
.logo h1 { font-family:'Fraunces',serif; font-weight:800; font-style:normal; font-size:19px; letter-spacing:-0.03em; line-height:1; color:var(--ink); }
.logo h1 em { font-style:italic; color:var(--rust); }
.logo .byline { font-family:'JetBrains Mono',monospace; font-size:8.5px; font-weight:700; text-transform:uppercase; letter-spacing:0.14em; color:var(--ink-dimmer); line-height:1; }
```

---

## 5. Core Components

### Nav
```css
nav {
  display:flex; align-items:center; justify-content:space-between;
  padding:16px 28px; border-bottom:1.5px solid var(--ink);
  background:var(--bg); position:sticky; top:0; z-index:50;
}
.nav-link {
  font-family:'JetBrains Mono',monospace; font-size:11px; font-weight:700;
  text-transform:uppercase; letter-spacing:0.08em; color:var(--ink-dim);
  padding:7px 12px; border:1.5px solid transparent; border-radius:3px;
}
.nav-link:hover { color:var(--ink); border-color:var(--line-2); }
.nav-link.active { color:#fff; background:var(--rust); border-color:var(--ink); box-shadow:2px 2px 0 var(--ink); }
```

### Eyebrow (section kicker)
```html
<div class="sec-eyebrow">Free Training</div>
```
```css
.sec-eyebrow {
  font-family:'JetBrains Mono',monospace; font-size:11px; text-transform:uppercase;
  letter-spacing:0.16em; font-weight:700; color:var(--rust);
  margin-bottom:14px; display:flex; align-items:center; gap:10px;
}
.sec-eyebrow::before { content:""; width:28px; height:2px; background:var(--rust); }
```

### Buttons
```css
.btn {
  display:inline-flex; align-items:center; gap:8px; padding:11px 20px;
  border-radius:3px; font-family:'JetBrains Mono',monospace; font-size:11px;
  font-weight:700; text-transform:uppercase; letter-spacing:0.08em;
  cursor:pointer; border:1.5px solid var(--ink); transition:all .14s;
  background:var(--panel); color:var(--ink);
}
.btn:hover { transform:translate(-2px,-2px); box-shadow:var(--shadow-sm); }
.btn.rust   { background:var(--rust); color:#fff; border-color:var(--rust); }
.btn.ink    { background:var(--ink);  color:var(--bg); }
.btn.lg     { padding:15px 28px; font-size:12px; }
```

### Feature Card
```css
.fcard {
  background:var(--panel); border:1.5px solid var(--ink);
  border-radius:3px; box-shadow:var(--shadow-sm); padding:24px 22px; transition:all .14s;
}
.fcard:hover { transform:translate(-3px,-3px); box-shadow:var(--shadow); }
.fcard .ic {
  width:46px; height:46px; background:var(--bg-warm);
  border:1.5px solid var(--ink); border-radius:3px; box-shadow:2px 2px 0 var(--ink);
  display:flex; align-items:center; justify-content:center; font-size:22px; margin-bottom:14px;
}
.fcard h4 { font-family:'Fraunces',serif; font-weight:800; font-size:20px; letter-spacing:-0.02em; margin-bottom:7px; }
.fcard p  { font-family:'Fraunces',serif; font-size:14px; color:var(--ink-dim); line-height:1.55; }
```

### Card with Header
```css
.card    { background:var(--panel); border:1.5px solid var(--ink); border-radius:3px; box-shadow:var(--shadow-sm); overflow:hidden; }
.card-h  { padding:14px 18px; border-bottom:1px solid var(--line); display:flex; align-items:center; justify-content:space-between; background:var(--bg-warm); }
.card-h h4 { font-family:'Fraunces',serif; font-weight:800; font-style:italic; font-size:17px; letter-spacing:-0.02em; }
.card-h .ha { font-family:'JetBrains Mono',monospace; font-size:9px; text-transform:uppercase; letter-spacing:0.08em; color:var(--ink-dim); font-weight:700; }
.card-b  { padding:18px; font-family:'Fraunces',serif; font-size:14.5px; color:var(--ink-dim); }
```

### KPI Card
```css
.kpi-card { background:var(--panel); border:1.5px solid var(--ink); border-radius:3px; padding:16px 18px; box-shadow:var(--shadow-sm); border-left:3px solid var(--rust); }
.kpi-card.olive { border-left-color:var(--olive); }
.kpi-card.gold  { border-left-color:var(--gold); }
.kpi-card.slate { border-left-color:var(--slate); }
.kpi-label { font-family:'JetBrains Mono',monospace; font-size:9.5px; text-transform:uppercase; letter-spacing:0.06em; font-weight:700; color:var(--ink-dim); }
.kpi-val   { font-family:'Fraunces',serif; font-style:italic; font-weight:900; font-size:42px; letter-spacing:-0.03em; line-height:1.1; margin:6px 0; }
.kpi-val.r { color:var(--rust); } .kpi-val.o { color:var(--olive); } .kpi-val.g { color:var(--gold); } .kpi-val.s { color:var(--slate); }
.kpi-sub   { font-family:'Fraunces',serif; font-size:13px; color:var(--ink-dim); }
```

### Pill / Badge
```css
.pill { display:inline-block; padding:3px 8px; border-radius:2px; font-family:'JetBrains Mono',monospace; font-size:8.5px; font-weight:700; text-transform:uppercase; letter-spacing:0.06em; white-space:nowrap; }
.pill.solid   { background:var(--olive); color:#fff; }
.pill.info    { background:var(--slate); color:#fff; }
.pill.warn    { background:var(--gold);  color:#fff; }
.pill.bad     { background:var(--bad);   color:#fff; }
.pill.outline { background:transparent; color:var(--ink-dim); border:1px dashed var(--line-2); }
```

### Callout
```css
.callout { background:var(--rust-soft); border:1.5px solid var(--rust); border-left-width:4px; border-radius:3px; padding:16px 18px; }
.callout .ch { font-family:'JetBrains Mono',monospace; font-size:10px; text-transform:uppercase; letter-spacing:0.1em; font-weight:700; color:var(--rust); margin-bottom:8px; }
.callout p   { font-family:'Fraunces',serif; font-size:14.5px; font-style:italic; color:var(--ink); }
```

### Prompt Card (BH-specific)
```css
.prompt-card {
  background:var(--bg-warm); border:1.5px solid var(--ink);
  border-left:4px solid var(--rust); border-radius:3px;
  padding:14px 48px 14px 16px; font-family:'JetBrains Mono',monospace;
  font-size:13px; color:var(--ink-dim); line-height:1.55; margin-bottom:8px; position:relative;
}
```

### Time Pill (BH-specific)
```css
.time-pill {
  font-family:'JetBrains Mono',monospace; font-size:9px; font-weight:700;
  text-transform:uppercase; letter-spacing:0.1em;
  color:var(--olive); background:var(--olive-bg);
  border:1px solid var(--olive); border-radius:2px;
  padding:3px 8px; white-space:nowrap; display:inline-block;
}
```

### Stat Row
```css
.stats { display:grid; grid-template-columns:repeat(4,1fr); border:1.5px solid var(--ink); border-radius:3px; box-shadow:var(--shadow-sm); overflow:hidden; background:var(--panel); }
.stat  { padding:24px 18px; text-align:center; border-right:1.5px solid var(--line); }
.stat:last-child { border-right:none; }
.stat-num { font-family:'Fraunces',serif; font-weight:900; font-style:italic; font-size:42px; letter-spacing:-0.03em; color:var(--rust); line-height:1; }
.stat-lbl { font-family:'JetBrains Mono',monospace; font-size:9px; font-weight:700; text-transform:uppercase; letter-spacing:0.1em; color:var(--ink-dim); margin-top:8px; }
```

### Toggle
```css
.toggle { width:42px; height:24px; border-radius:14px; border:1.5px solid var(--ink); background:var(--bg-warm); position:relative; cursor:pointer; transition:background .15s; display:inline-block; }
.toggle::after { content:""; position:absolute; top:2px; left:2px; width:16px; height:16px; border-radius:50%; background:var(--ink); transition:left .15s; }
.toggle.on { background:var(--olive); }
.toggle.on::after { left:21px; background:#fff; }
```

### Form Fields
```css
.field  { margin-bottom:14px; }
label   { font-family:'JetBrains Mono',monospace; font-size:9.5px; text-transform:uppercase; letter-spacing:0.06em; color:var(--ink-dim); font-weight:700; margin-bottom:5px; display:block; }
input, select, textarea {
  font-family:'Fraunces',serif; font-size:15px; color:var(--ink);
  background:var(--bg); border:1.5px solid var(--line-2); border-radius:3px; padding:9px 12px; width:100%;
}
input:focus, select:focus, textarea:focus { outline:none; border-color:var(--rust); }
```

### Final CTA Band
```css
.final { text-align:center; background:var(--rust); border-top:2px solid var(--ink); border-bottom:2px solid var(--ink); padding:64px 28px; }
.final h2 { font-family:'Fraunces',serif; font-weight:900; font-size:46px; letter-spacing:-0.04em; line-height:1; color:#fff; margin-bottom:14px; }
.final p  { font-family:'Fraunces',serif; font-style:italic; font-size:18px; color:rgba(255,255,255,0.9); margin-bottom:28px; }
.final .btn { background:#fff; color:var(--rust); border-color:var(--ink); box-shadow:4px 4px 0 var(--ink); }
```

### Footer
```css
footer { padding:32px 28px; display:flex; justify-content:space-between; align-items:center; flex-wrap:wrap; gap:14px; border-top:1.5px solid var(--ink); }
.foot-copy { font-family:'JetBrains Mono',monospace; font-size:9px; color:var(--ink-dimmer); letter-spacing:0.08em; text-transform:uppercase; }
```

---

## 6. Layout

```css
.wrap        { max-width:1080px; margin:0 auto; padding:64px 28px; }
.wrap-narrow { max-width:780px;  margin:0 auto; padding:64px 28px; }
.band        { background:var(--bg-warm); border-top:1.5px solid var(--line); border-bottom:1.5px solid var(--line); }
.band-ink    { background:var(--ink); border-top:1.5px solid var(--ink); border-bottom:1.5px solid var(--ink); }
.grid-2      { display:grid; grid-template-columns:repeat(2,1fr); gap:18px; }
.grid-3      { display:grid; grid-template-columns:repeat(3,1fr); gap:18px; }
.grid-4      { display:grid; grid-template-columns:repeat(4,1fr); gap:14px; }
@media(max-width:760px) { .grid-2,.grid-3,.grid-4 { grid-template-columns:1fr 1fr; } }
@media(max-width:480px) { .grid-2,.grid-3,.grid-4 { grid-template-columns:1fr; } }
```

**Section rhythm:** never put two identical-background sections back to back. Alternate `--bg` → `--bg-warm` band → `--bg` → `--panel` so the eye gets edges.

---

## 7. Motion

- Hover lift: `transform:translate(-2px,-2px)` + `box-shadow:var(--shadow-sm)`, `transition:all .14s`
- Marketing cards: lift `-3px,-3px` to `--shadow`
- No parallax, no bounce, no long easings. The brand is calm.

### BH Mark — Random Loop Animation

The BH mark runs a random idle animation loop. Three animations rotate randomly, firing every 2–5 seconds and on scroll (throttled to every 800ms / 120px delta). Add `transform-origin:center center; will-change:transform` to any `.mark` element.

**Keyframes — paste verbatim:**
```css
@keyframes bh-shake {
  0%   { transform: rotate(0deg) translate(0,0); }
  15%  { transform: rotate(-4deg) translate(-2px, 0); }
  30%  { transform: rotate(4deg)  translate(2px, -1px); }
  45%  { transform: rotate(-3deg) translate(-1px, 1px); }
  60%  { transform: rotate(3deg)  translate(1px, -1px); }
  75%  { transform: rotate(-2deg) translate(-1px, 0); }
  90%  { transform: rotate(1deg)  translate(0, 0); }
  100% { transform: rotate(0deg) translate(0,0); }
}
@keyframes bh-bounce {
  0%   { transform: translateY(0) scaleY(1) scaleX(1); }
  25%  { transform: translateY(-7px) scaleY(1.06) scaleX(0.96); }
  50%  { transform: translateY(0) scaleY(0.94) scaleX(1.04); }
  65%  { transform: translateY(-3px) scaleY(1.03) scaleX(0.98); }
  80%  { transform: translateY(0) scaleY(0.98) scaleX(1.01); }
  100% { transform: translateY(0) scaleY(1) scaleX(1); }
}
@keyframes bh-wiggle {
  0%   { transform: rotate(0deg); }
  20%  { transform: rotate(-6deg); }
  40%  { transform: rotate(6deg); }
  55%  { transform: rotate(-4deg); }
  70%  { transform: rotate(4deg); }
  82%  { transform: rotate(-2deg); }
  92%  { transform: rotate(1deg); }
  100% { transform: rotate(0deg); }
}
.mark-shake  { animation: bh-shake  0.5s  ease forwards; }
.mark-bounce { animation: bh-bounce 0.55s cubic-bezier(.36,.07,.19,.97) forwards; }
.mark-wiggle { animation: bh-wiggle 0.6s  ease forwards; }
```

**Random loop script — paste before `</body>`:**
```html
<script>
(function(){
  var marks  = ['bh-mark-nav','bh-mark-footer']; // add any mark id here
  var anims  = ['mark-shake','mark-bounce','mark-wiggle'];
  var lastScroll = 0, scrollCooldown = false;

  function fire(id, cls) {
    var el = document.getElementById(id);
    if (!el || el.dataset.animating) return;
    el.dataset.animating = '1';
    el.classList.remove('mark-shake','mark-bounce','mark-wiggle');
    void el.offsetWidth;
    el.classList.add(cls);
    el.addEventListener('animationend', function() {
      el.classList.remove(cls);
      delete el.dataset.animating;
    }, { once: true });
  }

  function pickRandom() {
    var id  = marks[Math.floor(Math.random() * marks.length)];
    var cls = anims[Math.floor(Math.random() * anims.length)];
    fire(id, cls);
  }

  function scheduleNext() {
    setTimeout(function() { pickRandom(); scheduleNext(); }, 2200 + Math.random() * 2800);
  }

  // scroll trigger — fires on nav mark, throttled
  window.addEventListener('scroll', function() {
    if (scrollCooldown) return;
    var sy = window.scrollY;
    if (Math.abs(sy - lastScroll) > 120) {
      fire('bh-mark-nav', anims[Math.floor(Math.random() * anims.length)]);
      lastScroll = sy;
      scrollCooldown = true;
      setTimeout(function() { scrollCooldown = false; }, 800);
    }
  }, { passive: true });

  setTimeout(function() { pickRandom(); scheduleNext(); }, 1200);
})();
</script>
```

**Rules:**
- Give every mark an `id` matching the `marks` array above (`bh-mark-nav`, `bh-mark-footer`, etc.)
- Never run two animations simultaneously on the same element — the `dataset.animating` guard handles this
- Interval: 2.2–5s random gap between fires. Not too frequent — the brand is calm
- Scroll trigger only fires on the nav mark (always visible), not footer

---

## 8. Dark Mode / Color Scheme

Light only. Prevent auto-darkening:
```html
<meta name="color-scheme" content="light only">
<meta name="supported-color-schemes" content="light">
```
```css
html { color-scheme:light; }
body { background:var(--bg); } /* explicit — never transparent */
```

---

## 9. Rules

**Always:**
- Warm cream `--bg` canvas. Never cold white or dark.
- 1.5px solid `--ink` borders. Hard offset shadows only.
- One italic rust accent per heading.
- Fraunces for anything display or sentence-like. JetBrains Mono for anything label-like.
- Mark illustrative/sample data with `.disclaimer` style.

**Never:**
- A third typeface.
- Hex colors outside the token list.
- Soft/blurred drop shadows — breaks the brand instantly.
- `border-radius` above 4px (only avatars/toggles are round).
- Dark mode.
- Cold pure-white `#fff` page backgrounds — use `--panel` for cards, `--bg` for pages.
- Em dashes in copy. Commas or periods instead.

---

## 10. Voice & Copy

- **Headlines:** short, declarative, confident. One italic rust word. "Build the *AI Mind.*" "You are your own *moat.*"
- **Labels:** terse, mono, uppercase. "FREE TRAINING", "SKILL #01", "BY COLIN STUCKERT"
- **Body:** plain, direct, specific. No hype ("revolutionary", "game-changing"). Say the real thing.
- **Signature closers:** "Go be unfuckwithable." "You are your own moat."

---

## 11. One-line prompt for any AI tool

> "Use the BH Tools Design System: Fraunces serif (display + body) + JetBrains Mono (labels only); warm cream #f4f3ef canvas, ink #1c1c20, rust #c44d2e primary accent with olive/gold/slate/green secondaries; near-white #fafaf6 panels; hard-edge shadows only (3px small, 6px emphasis — never blurred); 1.5px ink borders; 3px radius; light theme only; one italic-rust accent word per heading; uppercase mono labels; BH mark is 'BH' in Fraunces 900 upright in a rust square; wordmark is 'Better Human Tools' Fraunces 800 upright with italic rust 'Tools'; byline 'By Colin Stuckert' in JetBrains Mono 8.5px below. No em dashes. Match the attached design system markdown exactly."

---

*BH Tools Master Design System — keep it warm, keep it sharp, keep it honest.*
*Aligned with Rize Master Design System. Last updated 2026.*
