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):
- 60% deep ink
#0F1419(colors.surface) - page bg, hero zone, footer, prose - 30% oxblood
#5C2A2A(colors.primary) - tile mass, accent shapes (one-step lift off ink) - 10% sand
#e8dcc4(colors.tertiary, alsocolors.on-surface) - body text + warm accents - Preserved lavender
#d6d3f0(colors.secondary) - doodle field inner (non-negotiable across all variants) - Sparing cream
#f5efe1(colors.accent-highlight) - bright callouts only (never body)
The five-tells discipline from the umbrella still applies. Sanity Check's hits:
- Signature character beat: the founder's hand-drawn doodle plate (lavender field on dark) is the recurring hero element.
- Editorial type: Source Serif headline + italic "Check" in the wordmark (oxblood).
- Textured background: deep ink + ~5% sand-tinted graph-paper motif (28x28px grid).
- One confident accent: oxblood - wordmark italic, primary CTA fill, link :hover, hero
<em>. - 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):
- DoodleFrame - the signature recipe. 16:9 aspect,
object-fit: contain(NEVER cover - v2 regression), lavender inner field, thin oxblood hairline border. One unified frame across hero / tile / article placements (only sizing varies). - Sand-tinted graph-paper motif at ~0.55 opacity behind body content. 28x28px grid via two linear-gradients in
rgba(120, 95, 60, 0.08). Same intent as Commoncog topography on the dark canvas. - Grainy paper noise overlay (inherited from umbrella
body::before) - SVG fractalNoise overlay, opacity 0.32,mix-blend-mode: multiply. Adds tactile warmth to the dark surface.
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. MMXXVI · VOL. 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:
- Use deep ink + oxblood + sand + lavender (doodle field) + sparing cream - the Variant C palette
- Use the DoodleFrame recipe for every doodle (hero/tile/article - one recipe, three sizing variants)
- Set
object-fit: containon.sc-doodle-frame-img(NEVER cover) - Use italic Playfair-style "Check" in oxblood in the wordmark - SC-only flourish
- Include
EST. MMXXVI · VOL. IIin the wordmark meta line (nbsp-joined, nowrap) - End every Vol. II article with the
## Connectionssection - Use italic display serif for pull-quotes, with ink-soft color (NOT oxblood)
- Use ink color for drop-caps (NOT oxblood)
- Make tap targets 44px+ on mobile
Never:
- Stray from the Variant C palette
- Put a human character in a doodle (founder's archive is object-/scene-based; sole exception is
grok-hero-sanity-check.jpg) - Use
object-fit: coveron.sc-doodle-frame-img(v2 regression - caused hero clipping) - Fork the doodle frame recipe per placement
- Use oxblood on captions, body italic emphasis, tile borders that aren't the doodle frame, hover underlines on archive lists, drop-caps, blockquote rules, or selection backgrounds
- Use emoji on Sanity Check surfaces (editorial register, not chat)
- Use "AI will replace you" panic tone
- Use question marks in subject lines or display headlines
- Use clickbait formats
- Use the legacy stamp-tile palette
- Use the stingray mark as a primary brand mark on SC (downgraded to placeholder fallback only)
RDCO extension beyond Stitch core: Voice & Copy
Inherits the umbrella's 5 voice attributes + mechanics. Layered SC-specific rules:
Newsletter-format rules:
- Issue-numbered cadence. Vol. I =
SC NNNnumeric orSC E0Nearly/supplemental. Vol. II = sequential from 001. Title format:SC NNN - <Title-Case Headline>. - Volume identity visible. Wordmark meta + hero eyebrow:
A weekly essay · Vol. II · Apr 2026. - Subject lines: short, declarative, often two-part.
Fundamentals first. Agents second./I stopped writing about data. Here's what brought me back. - Article arc: hook → frame → argument → close. Hook is tangible scene OR concession OR framework label. Close is one declarative sentence, often self-deprecating or operational.
- Pull-quotes: italic blockquote, display serif 1.25rem, ink-soft (NOT oxblood - accent budget protected).
- Inline asides: em-dashes preferred for rhythm, but use sparingly (≤2 per paragraph) per softened
feedback_no_em_dashes2026-05-23. Parentheses also fine. Overuse of em-dashes is the AI-tell, not single use. - Connections section. Every Vol. II article ends with
## Connections(vault cross-refs). Usevault-linkclass witharia-disabled="true"until vault is public.
Banned phrases / patterns:
- Question marks in subject lines or display headlines (declarative only)
- Clickbait formats ("How I X-ed Y in N days", "The one trick", etc.)
- "AI will replace you" panic tone in CTAs, footers, or email copy
- "From the editor" lockup using oxblood (use ink-soft)
- Removing the issue-numbered cadence (brand-load-bearing)
- Removing the Connections section from articles
- Em-dash overuse (more than ~2 per paragraph) - single em-dash is fine per softened
feedback_no_em_dashes2026-05-23
Signature moves:
- Hook with a tangible scene or concession ("I published my last Sanity Check in October 2023. Then I went quiet.")
- Frame with plain practitioner reframe
- Argument built from concrete examples + personal anecdotes (Squarely, TagaPet, ConnectWise)
- One-line punch close
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
- Parent:
/Users/ray/rdco-vault/02-sops/DESIGN-rdco.md - Sticker recipe (xAI Grok Imagine workflow):
/Users/ray/.claude/skills/sanity-check-design/brand-spec.txt(STICKER RECIPE section) - Build notes for current live implementation:
~/rdco-sc/DESIGN.md - v3 positioning lock:
~/rdco-vault/01-projects/sanity-check/v3-positioning-2026-05-08.md - Reference sample:
/Users/ray/rdco-vault/02-sops/design-samples/sanity-check-sample.html+.pdf