02-sops

DESIGN sanity check

Sanity Check - Newsletter Design (Variant C "Inkwell")

Inherits: /Users/ray/rdco-vault/02-sops/DESIGN-rdco.md (RDCO umbrella). Child wins for Sanity Check surfaces only - never propagate child overrides back to the umbrella.

Overrides: Colors, Typography, Layout & Spacing, Shapes, Components, Voice & Copy, Format-specific templates, Do's and Don'ts. Other umbrella rules (asset inheritance pattern, 5-tells discipline, hard NOs not contradicted here) still apply.

Section name aliases: uses the longer descriptive names (Brand & Style, Layout & Spacing, Elevation & Depth) - aliases for Stitch's Overview, Layout, Elevation.

Brand & Style

Sanity Check (sc.raydata.co) is the weekly RDCO newsletter - Ben Wilson's editorial point of view on data engineering, AI agents, and analytics craft. Mood reference: n+1 magazine, dark editorial quarterly, "lighthouse-against-void." Doodle plates read as backlit prints on a dark gallery wall.

Variant C "Inkwell" was founder-approved 2026-05-08 during the v3 rebuild. Replaces the legacy "warm cream + lavender + terracotta" v0.1 and the intermediate v0.3 SAND-AS-ACCENT (deep navy + cream + coral). The v3 positioning lock called for dark-editorial-quarterly; Inkwell delivers it.

Color discipline (override of umbrella 60/30/10):

The five-tells discipline from the umbrella still applies. Sanity Check's hits:

  1. Signature character beat: the founder's hand-drawn doodle plate (lavender field on dark) is the recurring hero element.
  2. Editorial type: Source Serif headline + italic "Check" in the wordmark (oxblood).
  3. Textured background: deep ink + ~5% sand-tinted graph-paper motif (28x28px grid).
  4. One confident accent: oxblood - wordmark italic, primary CTA fill, link :hover, hero <em>.
  5. Visible authorship: founder's actual archive doodles in every issue; byline + editor-span in mono.

Consumer behavior table (Stitch contract)

Scenario Behavior
Unknown section heading Preserve, do not error
Unknown color/typography token name Accept if value valid
Unknown spacing value Accept; store as string if not valid Dimension
Unknown component property Accept with warning
Duplicate section heading Error, reject file

Colors

v9 Tampa Bay coastal palette — live deployment since 2026-05-08, spec aligned 2026-05-24. CSS variable prefix --sc-. Replaces the prior Variant C "Inkwell" (oxblood) spec which is retired.

Token Hex Live CSS var Role Contrast
colors.surface #0D2438 --sc-bg surface (60%) — page bg, hero, footer, prose canvas Cream on navy = 13.2:1 AAA
colors.surface-elevated #162e44 --sc-bg-elevated tile fill, card bg, doodle frame outer (one-step lift) Cream on lift = 12.6:1 AAA
colors.surface-elevated-2 #1d3a55 --sc-bg-elevated-2 bio mini-tile, variant tiles Cream = 11.8:1 AAA
colors.primary #e08570 --sc-coral / --sc-accent wordmark italic "Check", CTA fill, hero <em>, link hover Navy on coral = 5.1:1 AA (preferred)
colors.secondary #e8dcc4 --sc-sand featured-essay tile bg, warm illustration field Navy on sand = 12.4:1 AAA
colors.tertiary #f5efe1 --sc-ink primary cream text on navy (default body) 13.2:1 AAA
colors.on-surface #f5efe1 --sc-ink synonym of tertiary Same
colors.on-surface-soft #d6cfba --sc-ink-soft secondary text, byline-editor span 11.4:1 AAA
colors.neutral #b8b3a3 --sc-muted mono caption / eyebrow / nav-link 7.55:1 AAA on navy
colors.bay #4d8aac --sc-bay hairline divider, blueprint grid (low alpha) Decorative only — not for body text
colors.bay-deep #1d3a55 --sc-bay-deep inline-code background, footer band 11.8:1 AAA cream
colors.accent-highlight #f0e6d2 --sc-sand-soft sand-soft highlight, hover, sparing accent High on navy
colors.error #e08570 --sc-coral (alias) error / destructive accent (paired with icon + weight) Same as primary
legacy.lavender #d6d3f0 --sc-doodle-field (heritage) DoodleFrame inner for legacy v3 articles only Ink doodle stroke = 12.8:1 AAA

Retired tokens (v2 cleanup 2026-05-24): --sc-accent was oxblood #5C2A2A in Variant C "Inkwell" — now aliased to coral #e08570. Variant C "Inkwell" is fully deprecated; do not introduce oxblood on any new SC surface.

Banker's-note wave underline (v2 signature)

The wave is the shared SC + RDCO v2 inline-emphasis treatment — replaces flat background-highlight. Use as an UNDERLINE never as a background. SVG asset: wave-coral.svg (default), wave-sand.svg (on sand-tile surfaces). Density: 1-3 waves per page maximum. Pair with semibold weight on the highlighted phrase. CSS pattern:

.wave-em {
  font-weight: 600;
  background-image: url('/wave-coral.svg');
  background-repeat: repeat-x;
  background-position: 0 100%;
  background-size: 24px 8px;
  padding-bottom: 6px;
}

Typography

Inherits the umbrella font stack (Source Serif 4 + Inter + JetBrains Mono). SC-specific tokens - labels become MONO (not Inter) on SC because the editorial register demands it:

Token Family Size Weight Italic Notes
typography.wordmark-mark Source Serif 1.55rem (1.65rem ≥560px) 600 YES "Check" only - oxblood, SC-only italic flourish
typography.wordmark-est JetBrains Mono 0.6rem 500 NO EST. MMXXVI · VOL. II, tracking 0.16em uppercase
typography.headline-display Source Serif clamp(2.25rem, 6.5vw, 4.25rem) 700 NO Hero, line-height 1.02
typography.headline-display-em Source Serif clamp(2.25rem, 6.5vw, 4.25rem) 600 YES Oxblood, ONE per hero composition
typography.headline-lg Source Serif clamp(2rem, 4.5vw, 2.75rem) 700 NO Prose h1
typography.headline-md Source Serif 1.7rem 700 NO Prose h2
typography.headline-sm-italic Source Serif 1.3rem 600 YES Prose h3 (italic)
typography.body-lg Inter 18px 400 NO Body, line-height 1.65, max 62ch
typography.label-lg Mono 0.78rem 500 NO Nav-link, button, tracking 0.12em uppercase
typography.label-md Mono 0.72rem 500 NO Eyebrow, byline, tracking 0.18em uppercase
typography.label-sm Mono 0.65rem 500 NO Caption, tracking 0.18em uppercase

Measure: body 62ch (tighter than umbrella's 65ch to compensate for the longer reading session a newsletter assumes).

Layout & Spacing

Token Value Use case
spacing.page-x 1.25rem Page side padding
spacing.section 4rem Inter-section vertical spacing
spacing.rhythm 1.5rem .sc-prose > * + * gap between block-level elements
spacing.lg 24px Card padding

Breakpoints: mobile <560 / desktop ≥560 / wide ≥720 / wider ≥900.

Header layout: wordmark stacks above nav (column flex) at <560px; same row (row flex, space-between) at ≥560px.

Doodle grid: 1 col / 1.25rem gap mobile; 2 col / 1.5rem gap at ≥600px; 3 col at ≥900px.

Tap target minimums: nav-link 44px, button 44px (iOS HIG compliance).

Elevation & Depth

Token Value Use case
elevation.none none Doodle plates (separation comes from lavender vs ink, not shadow)
elevation.sm 0 1px 2px rgba(0, 0, 0, 0.18) Subtle card lift on ink
elevation.md 0 4px 12px rgba(0, 0, 0, 0.28) Tile hover
elevation.lg 0 8px 24px rgba(0, 0, 0, 0.4) "Backlit print on dark gallery wall" feel - SC tile shadow

Shapes

Radii (override of umbrella - sharper newsprint/letterpress register):

Token Value Use case
rounded.none 0 Full-bleed bands
rounded.sm 2px Buttons, inset matte, code, table cells
rounded.md 4px Tiles, doodle frame outer, post cards
rounded.lg 8px Modal sheets
rounded.xl 16px Feature blocks (rare on SC)
rounded.full 999px Draft badge pill only

Motif primitives (SC-specific):

Components

Stitch convention: separate keyed entries per variant.

wordmark / wordmark-est

<a class="sc-wordmark">
  <span class="lockup">
    Sanity <span class="mark">Check</span>
  </span>
  <span class="est">EST.&nbsp;MMXXVI&nbsp;·&nbsp;VOL.&nbsp;II</span>
</a>
.sc-wordmark { display: inline-flex; flex-direction: column; gap: 0.15rem; }
.sc-wordmark .lockup { white-space: nowrap; font-family: var(--sc-display); font-weight: 700; color: var(--sc-ink); font-size: 1.55rem; }
.sc-wordmark .lockup .mark { font-style: italic; font-weight: 600; color: var(--sc-accent); }
.sc-wordmark .est { font-family: var(--sc-mono); font-weight: 500; font-size: 0.6rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--sc-muted); white-space: nowrap; }
@media (min-width: 560px) { .sc-wordmark .lockup { font-size: 1.65rem; } }

Hard structure rules: .lockup uses white-space: nowrap so "Sanity" + italic "Check" never break across lines. .est uses nbsp + nowrap so "II" never orphans.

doodle-frame / doodle-frame-inner

<figure class="sc-doodle-frame" data-source="archive">
  <div class="sc-doodle-frame-inner">
    <img class="sc-doodle-frame-img" src="/doodles/kitchen-analytics.jpg" alt="Kitchen as analytics metaphor">
  </div>
</figure>
.sc-doodle-frame { aspect-ratio: 16/9; border-radius: 4px; padding: 0.5rem; background: var(--sc-bg-elevated); box-shadow: inset 0 0 0 1px rgba(166, 79, 58, 0.85); }
.sc-doodle-frame-inner { background: var(--sc-doodle-field); border-radius: 2px; height: 100%; display: flex; align-items: center; justify-content: center; overflow: hidden; }
.sc-doodle-frame-img { max-width: 100%; max-height: 100%; object-fit: contain; }

When to use: every doodle on SC - hero, tile, in-prose. One recipe, three sizing variants. NEVER fork the framing per placement.

button-primary / button-primary-hover

<a class="sc-btn">Subscribe</a>
.sc-btn { display: inline-flex; align-items: center; padding: 0.75rem 1.25rem; min-height: 44px; font-family: var(--sc-mono); font-size: 0.78rem; font-weight: 500; letter-spacing: 0.12em; text-transform: uppercase; background: var(--sc-accent); color: var(--sc-ink); border: none; border-radius: 2px; cursor: pointer; transition: background 120ms ease; }
.sc-btn:hover { background: #8a4030; }

button-ghost / button-ghost-hover

.sc-btn--ghost { background: transparent; color: var(--sc-ink); border: 1px solid var(--sc-rule-strong); }
.sc-btn--ghost:hover { background: var(--sc-ink); color: var(--sc-bg); }

pull-quote

<blockquote class="sc-pullquote">"The kitchen just got a lot more interesting."</blockquote>
.sc-pullquote { font-family: var(--sc-display); font-style: italic; font-weight: 500; font-size: 1.25rem; color: var(--sc-ink-soft); border-left: 3px solid var(--sc-ink-soft); padding-left: 1rem; margin: 1.5rem 0; }

Not oxblood border, not oxblood color - accent budget protected.

drop-cap

.sc-prose.has-dropcap > p:first-of-type::first-letter { font-family: var(--sc-display); font-style: italic; font-weight: 700; font-size: 4em; line-height: 0.85; float: left; padding: 0.1em 0.1em 0 0; color: var(--sc-ink); }

Color = ink, NOT oxblood.

eyebrow / byline

<div class="sc-eyebrow">A weekly essay · Vol. II · Apr 2026</div>
.sc-eyebrow { font-family: var(--sc-mono); font-weight: 500; font-size: 0.72rem; letter-spacing: 0.18em; text-transform: uppercase; color: var(--sc-muted); }

Do's and Don'ts

(In addition to umbrella's Do's and Don'ts not overridden here.)

Always:

Never:


RDCO extension beyond Stitch core: Voice & Copy

Inherits the umbrella's 5 voice attributes + mechanics. Layered SC-specific rules:

Newsletter-format rules:

Banned phrases / patterns:

Signature moves:


RDCO extension beyond Stitch core: Format-specific templates

Surface Dimensions Notes
sc.raydata.co home (desktop) 1440 x 900 hero Wordmark + hero doodle + bento grid
sc.raydata.co home (mobile) 393 x 852 Wordmark stacks above nav; doodle grid 1-col
Article page (web) content column 62ch Drop-cap required; Connections section required
Email body (sent issue) max-width 600px Inter 16-17px body; no doodle frame ::before/::after CSS-only effects (email-client safe); use rendered image
Open Graph image 1200 x 630 Wordmark + issue title in Source Serif; sand on ink
LinkedIn post (vertical) 1080 x 1350 Issue cover with hero doodle + title
LinkedIn post (square) 1200 x 1200 Pull-quote treatment
X / Twitter card 1200 x 675 Wordmark + title + doodle
Postcard issue (print) 6" x 4.25" Doodle hero on front, body on back

Mobile-first discipline: SC is read on phones during commute / lunch / morning coffee. Tap targets 44px+. Wordmark stack at <560px. Doodle grid 1-col at <600px.


RDCO extension beyond Stitch core: Asset inventory

Skill home: /Users/ray/.claude/skills/sanity-check-design/

Path Type Description
/Users/ray/.claude/skills/sanity-check-design/SKILL.md spec Agent skill entrypoint (118 lines)
/Users/ray/.claude/skills/sanity-check-design/README.md doc Full SC context (161 lines)
/Users/ray/.claude/skills/sanity-check-design/brand-spec.txt spec Plain-text grep-friendly SC overrides (531 lines)
/Users/ray/.claude/skills/sanity-check-design/colors_and_type.css code SC-specific CSS tokens (350 lines)

Doodle archive (symlinked single source of truth): /Users/ray/.claude/skills/sanity-check-design/assets/doodles/~/rdco-sc/public/doodles/ (25+ founder-authored doodles + Grok samples).

Live implementation (symlinked): /Users/ray/.claude/skills/sanity-check-design/ui_kits/website/sc-live/~/rdco-sc/ (canonical Variant E v3 implementation as of 2026-05-08).

Components (live Astro):

Component Path
DoodleFrame ~/rdco-sc/src/components/DoodleFrame.astro
DoodleTile ~/rdco-sc/src/components/DoodleTile.astro
Header ~/rdco-sc/src/components/Header.astro
Footer ~/rdco-sc/src/components/Footer.astro
PostCard ~/rdco-sc/src/components/PostCard.astro
Prose ~/rdco-sc/src/components/Prose.astro

Slug → doodle assignment: ~/rdco-sc/src/lib/doodleMap.ts (canonical map; homepage gated to lavenderFieldDoodles Set).

Stickers (~/rdco-vault/06-reference/design-mood-board/sc-stickers/):

Sticker Class Use
badge-new.png label Sits ON the actual newest piece. Never as decoration.
badge-vol-ii.png label Sits on Vol. II opener/anchor only. Not redundant flair.
badge-draft.png label Dev/preview only, on tiles where draft: true
fox.png character Tile corner / hero corner flair
owl-glasses.png character Editorial / archive corner flair
microscope.png character Verification / test-piece corner flair
pipeline-character.png character Pipeline-content flair
hybrid-pen-notebook-scene.png character Hero zone flair (v9 deployed)
palm-sun.png character Footer (Tampa Bay home motif)
stingray.png character (heritage) Used sparingly

Cross-references