Ray Data Co - Umbrella Design System
Section name aliases. This file uses the longer descriptive names "Brand & Style", "Layout & Spacing", "Elevation & Depth". These are aliases for the Stitch canonical short names "Overview", "Layout", "Elevation". Pick one set per file; do not mix. Stitch-recommended consumer behavior table is included in the Brand & Style section below.
Inheritance. This is the root umbrella. Children declare
inherits: DESIGN-rdco.mdand list explicitoverrides.
Brand & Style
Ray Data Co (RDCO) is a brand house holding a portfolio of opinionated bets in and around data, AI agents, analytics craft, and adjacent puzzles. The umbrella site (raydata.co) is the editorial point of view that ties the bets together; each bet is its own authored artifact under the umbrella. Founder is Ben Wilson, analytics engineer turned operator turned writer. Brand voice is "a working practitioner with skin in the game", not "a vendor selling a stack".
Every umbrella surface MUST hit five tells:
- Signature character beat in the hero (Ray, doodle, stingray mark, or a named editorial visual).
- Editorial-intent type pairing (Source Serif on hero, never default-Inter-bold).
- Textured / warm background (cream + graph-paper, lavender, or committed color - never flat white).
- One confident accent (terracotta on the umbrella, used boldly + sparingly).
- Visible authorship (founder photo, mascot beat, hand-touched detail).
Color discipline: 60/30/10 rule. Cream (surface) dominates 60% of canvas, lavender (secondary) supports 30%, terracotta (primary accent) takes 10%. If a page squints into "everything is lavender" or "everything is terracotta", it is failing the rule.
Mood reference: warm editorial quarterly, practitioner's notebook, hand-touched detail beats restraint. Hand-drawn / engraving / glitch / Memphis over flat / Bauhaus / modern-minimal (per founder taste memo feedback_design_taste_high_personality).
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 |
This makes RDCO DESIGN.md files parseable by future tools (Style Dictionary, Tailwind config sync, agent design-checkers), not just by humans.
Colors
v2 Tampa Bay sky+sun palette (2026-05-24). RDCO is the light sibling of Sanity Check — same Gulf-coast family, opposite hour. SC is Gulf-at-twilight (navy + coral); RDCO is Gulf-at-noon (soft sky + sun-ray yellow). Navy is shared with SC for sibling-lock.
Token names use Stitch-recommended semantic names. CSS prefix --rdco-.
| Token | Hex | Proposed CSS var | Role | Contrast notes |
|---|---|---|---|---|
colors.surface |
#eaf2f8 |
--rdco-sky |
Page surface (60%) — nearly-white soft sky blue | Navy on sky = 13.8:1 AAA |
colors.surface-elevated |
#dde9f2 |
--rdco-sky-lift |
Card bg, callout bg, doodle frame outer | Navy on lift = 12.4:1 AAA |
colors.surface-soft |
#f3f7fb |
--rdco-sky-soft |
Recessed surface, code blocks | Navy on soft = 14.7:1 AAA |
colors.primary |
#f0b820 |
--rdco-sun |
Sun-ray yellow — CTA fill, link hover, hero <em> (10%) |
Navy on sun = 9.4:1 AAA (preferred CTA pair) |
colors.secondary |
#e08570 |
--rdco-coral |
Cross-bet sibling-cameo (echoes SC). Sparing only. | Navy on coral = 5.1:1 AA — display sizes only |
colors.tertiary |
#0D2438 |
--rdco-navy |
Body type, headlines, icon fill (sibling-locked with SC) | Highest contrast against surface |
colors.on-surface |
#0D2438 |
--rdco-navy |
Synonym of tertiary | Same |
colors.on-surface-soft |
#2c4661 |
--rdco-navy-soft |
Secondary body | 9.1:1 AAA on sky |
colors.sun-glow |
#fff2cc |
--rdco-sun-glow |
Soft sun-tint, prominent emphasis callouts | Navy on glow = 14.2:1 AAA |
colors.sun-deep |
#d99e0a |
--rdco-sun-deep |
Sun hover, sun-callout left rail | Navy = 6.4:1 AA-large |
colors.bay |
#4d8aac |
--rdco-bay |
Hairline rules, blueprint grid | Decorative only — not for text |
colors.neutral |
#5a6e82 |
--rdco-muted |
Bylines, captions, eyebrow labels | 6.6:1 AAA on sky |
colors.divider |
#b8c8d6 |
--rdco-paperline |
Hairlines | Decorative |
colors.error |
#e08570 |
--rdco-coral (alias) |
Error (paired with icon + weight) | Same as secondary |
Heritage palette (v1 cream/lavender/terracotta) — preserved for legacy memo templates only. Do not use on new umbrella surfaces. Legacy tokens: legacy-cream #f5efe1, legacy-lavender #d6d3f0, legacy-terracotta #a64f3a, legacy-ink #1f1d1a.
Hard NO: no algorithmically-generated palettes (Coolors.co, etc.). No pure white surfaces. No legacy terracotta on new content. New tokens require a deliberate decision, not a spitball.
Live CSS state (open question — see delivery summary)
The live RDCO CSS at ~/Projects/claw-raydata-co/src/styles/global.css still uses the v1 cream/terracotta palette AND has confused variable naming (--ink is cream, --sand is ink, --yellow is terracotta, dead --oxblood). A v2 CSS rewrite that aligns to the new sky/sun palette AND fixes the naming inversion is queued. Surfaced to founder for direction; not auto-applied in this build.
Banker's-note wave underline (v2 signature, shared with SC)
The wave is the shared RDCO + SC v2 inline-emphasis treatment — replaces flat background-highlight. Use as an UNDERLINE never as a background. Wave SVGs:
wave-sun.svg— default umbrella emphasis (sun-yellow)wave-coral.svg— sibling-cameo when content references Sanity Check directlywave-band.svg— 3-line wave band (section divider option)
Density rule: 1-3 waves per page maximum. Wave is rare emphasis, not running highlighter. Pair with semibold weight on the highlighted phrase. CSS pattern:
.wave-em {
font-weight: 600;
background-image: url('/wave-sun.svg');
background-repeat: repeat-x;
background-position: 0 100%;
background-size: 24px 8px;
padding-bottom: 6px;
}
.wave-em.coral { background-image: url('/wave-coral.svg'); }
SVG assets staged at /tmp/style-guides-v2/assets/textures/. Promotion target: ~/.claude/skills/ray-data-co-design/assets/textures/.
Accessibility
Status: contract-grade as of 2026-05-24 (SpaceX v5 build defect-list). Filed after v4 shipped a recommendation callout in oxblood-italic-on-lavender that violated body-text contrast and after the v4 decision-trigger table coded one zone as blue (not in canonical palette). Both were mechanically catchable by token-time validation.
Minimum contrast ratios (WCAG 2.1 AA):
| Surface | Minimum ratio | Use case |
|---|---|---|
| Body text (under 18pt) | 4.5:1 | Body paragraphs, captions, table cells, callout body |
| Large text (≥18pt or ≥14pt bold) | 3:1 | Headlines, dek, oversized eyebrow |
| Non-text UI (borders, icons) | 3:1 | Left rails, hairlines, icon strokes |
| Inactive / disabled | (exempt) | Skip if visibly inactive |
Token-pair contrast reference (precomputed):
| Foreground | Background | Ratio | Verdict |
|---|---|---|---|
colors.tertiary (ink) |
colors.surface (cream) |
14.3:1 | AAA — default body pair |
colors.tertiary (ink) |
colors.secondary (lavender) |
12.8:1 | AAA — body on accent surfaces |
colors.on-surface-soft (graphite) |
colors.surface (cream) |
7.6:1 | AAA — eyebrow / byline |
colors.surface (cream) |
colors.tertiary (ink) |
14.3:1 | AAA — cream-on-ink reverse (e.g. PASS zone in trigger table) |
colors.surface (cream) |
colors.primary (terracotta) |
4.85:1 | AA-large ONLY — body type fails; use only for buttons/badges with ≥14pt bold or ≥18pt |
colors.primary (terracotta) |
colors.secondary (lavender) |
2.6:1 | FAIL — never as body text. Acceptable as a non-text accent (e.g. 3pt left rail) only |
colors.primary (terracotta) |
colors.surface (cream) |
4.85:1 | AA-large only — same caveat as above |
Callout token-contract (load-bearing, prevents v4-class violations):
- Callout background:
colors.surfaceORcolors.secondaryONLY. Nevercolors.primary(terracotta) as a fill behind body text. - Callout body text:
colors.tertiary(ink) ONLY. Nevercolors.primaryorcolors.erroras body text on any background. - Callout accent:
colors.primary(terracotta) as a LEFT RAIL (3-4pt vertical stroke) ONLY. Never as background fill behind body type, never as text color for body copy. - Heavy-emphasis "PASS / Negative" zones may invert to
colors.tertiary(ink) background withcolors.surface(cream) text (14.3:1 AAA, verified).
Hard NO additions:
- No blue, no green, no algorithmic-palette colors — only the 7 canonical tokens above. (Added 2026-05-24 after v4 trigger-table used a blue zone.)
- No oxblood/terracotta body text on lavender. (Added 2026-05-24 after v4 recommendation block leaked oxblood italic on lavender via
#show emph.) - No tertiary-on-primary (ink-on-terracotta) text — only 5.2:1, just AA-normal but tight; default to cream-on-terracotta for any in-button label and only at ≥14pt bold.
Validator hook: the /verify-pdf-output skill mechanically catches color sprawl (>5 distinct hues, check 4) and unapproved fonts (check 11). Token-pair contrast validation is not yet automated — a Phase-5 enhancement is to extend the critic to read token pairs from a fixture and assert ratios. Until then, this Accessibility subsection is the authoritative reference designers/skills consult at token-definition time.
Typography
Three families, contract-grade pairing:
- Source Serif 4 (variable, OFL) - display / editorial headlines. Transitional serif that says "we have things to say".
- Inter (variable, OFL) - body / UI. Humanist sans, the modern UI default with zero learning curve.
- JetBrains Mono (OFL) - code / metadata / file paths. IBM Plex Mono is an accepted alt.
Canonical scale (token names follow Stitch convention; sizes preserved from existing brand-spec):
| Token | Family | Size | Weight | Line-height | Notes |
|---|---|---|---|---|---|
typography.headline-display |
Source Serif 4 | 96px | 600 | 1.0 | Hero only, max 18ch |
typography.headline-lg |
Source Serif 4 | 56px | 600 | 1.05 | H1 |
typography.headline-md |
Source Serif 4 | 36px | 600 | 1.15 | H2 |
typography.body-lg |
Inter | 19px | 400 | 1.6 | Lead paragraph, max 65ch |
typography.body-md |
Inter | 17px | 400 | 1.6 | Default body, max 65ch |
typography.body-sm |
Inter | 15px | 400 | 1.55 | Compact body |
typography.label-lg |
Inter | 15px | 600 | 1.4 | Button text, CTA labels |
typography.label-md |
Inter | 14px | 500 | 1.4 | UI labels, uppercase tracking 0.06em |
typography.label-sm |
Inter | 13px | 400 | 1.4 | Captions in on-surface-soft |
typography.code-md |
JetBrains Mono | 15px | 400 | 1.6 | Code blocks, file paths, mono captions |
Measure constraint: body text never exceeds 65ch. Hero display never exceeds 18ch.
Pairing rules: Source Serif carries the headline. Inter holds body + UI chrome. JetBrains Mono is code-only. Never Inter on pure white (the SaaS-template default the founder rejects); Inter must sit on cream, lavender, or another committed background.
Font sources: Google Fonts CDN by default (see ~/.claude/skills/ray-data-co-design/fonts/index.css). Self-host on Cloudflare Pages for production.
Layout & Spacing
12-column CSS grid, gutter 24px desktop / 16px tablet / 12px mobile. Container max-width 1200px, centered with 24px side padding.
| Breakpoint | Min width | Container padding | Grid gap | Section padding (vertical) |
|---|---|---|---|---|
| mobile | 0 | 16px | 12px | 48px |
| tablet | 640 | 24px | 16px | 72px |
| desktop | 1024 | 24px | 24px | 120px |
| wide | 1440 | 24px | 24px | 120px |
Spacing token scale (Stitch-named):
| Token | Value | Use case |
|---|---|---|
spacing.none |
0 | Reset, full-bleed bands |
spacing.xs |
4px | Inline icon gap, tight pad |
spacing.sm |
8px | Base scale unit, control padding |
spacing.md |
16px | Block gap, default padding |
spacing.lg |
24px | Section internal padding, card padding |
spacing.xl |
48px | Section vertical (mobile) |
spacing.2xl |
72px | Section vertical (tablet) |
spacing.3xl |
120px | Section vertical (desktop, hero margin) |
Vertical rhythm: 8px base scale. Use the scale; don't invent 18px or 27px paddings.
Elevation & Depth
| Token | Value | Use case |
|---|---|---|
elevation.none |
none |
Body cards, full-bleed bands, doodle frames (umbrella avoids floating UI) |
elevation.sm |
0 1px 2px rgba(31, 29, 26, 0.06) |
Subtle card lift; barely visible - for table-cell or callout separation |
elevation.md |
0 4px 12px rgba(31, 29, 26, 0.08) |
Feature card on a page, hovered button, modal sheet |
elevation.lg |
0 12px 32px rgba(31, 29, 26, 0.10) |
Hero card lift, popover, sticky CTA |
Hard NO: no drop shadows on text. Use weight, color contrast, and white space for hierarchy. Shadows are for surface separation only.
Shapes
Radii system (token names follow Stitch convention):
| Token | Value | Use case |
|---|---|---|
rounded.none |
0 | Bands that span viewport edge to edge |
rounded.sm |
4px | Inputs, code blocks, table cells, badges |
rounded.md |
12px | Default card, button (non-pill), input groups |
rounded.lg |
24px | Feature cards, doodle field wrapper, cutout tiles |
rounded.xl |
32px | Oversized feature blocks |
rounded.full |
999px | Primary CTA, pill nav, tag chips |
Motif primitives (signature):
- Graph-paper background - 24px grid (32px on marketing),
colors.neutralat 0.05 opacity, underneath the surface. CSS class.rdco-graph-paper. Reads as Commoncog-topography: visible only when you look for it. - Doodle aesthetic - lavender field + dark thick wobble stroke (
colors.tertiary, 3-6px) + one warm accent (terracotta or yellow) + scene-not-character subject + optional cream paper-grain underlay. The opposite of vector flat. CSS class.rdco-doodle-field. - Cutout-character recipe - palette-forward saturated background + single-fill white (or single-color) cutout silhouette + illustration discipline as a set + editorial type lockup above. The "family of bets" tile-grid recipe for
raydata.co.
Aesthetic layers are kept separate. Doodle + Lucide icons NEVER on the same surface. Stylized Ray + canonical Ray NEVER on the same surface. One mascot variant per surface.
Components
Stitch convention: variants are separate keyed entries (button-primary, button-primary-hover), not nested under a parent component. The YAML frontmatter declares each variant explicitly.
button-primary / button-primary-hover
<button class="rdco-btn">Read the brief</button>
.rdco-btn {
display: inline-flex; align-items: center; gap: 8px;
padding: 14px 24px;
font-family: var(--rdco-font-body);
font-size: 15px; font-weight: 600;
border-radius: 999px;
border: 1.5px solid var(--rdco-ink);
background: var(--rdco-ink);
color: var(--rdco-cream);
cursor: pointer;
transition: background 120ms ease;
}
.rdco-btn:hover { background: var(--rdco-terracotta); border-color: var(--rdco-terracotta); }
When to use: primary CTA on hero or end-of-section. Max one primary button per visible viewport.
button-ghost / button-ghost-hover
.rdco-btn--ghost { background: transparent; color: var(--rdco-ink); }
.rdco-btn--ghost:hover { background: var(--rdco-ink); color: var(--rdco-cream); }
When to use: secondary action paired with a primary button, or stand-alone link-style CTA in body content.
link-default / link-hover
a { color: var(--rdco-ink); text-decoration-color: var(--rdco-paper-line); text-decoration-thickness: 1.5px; text-underline-offset: 3px; }
a:hover { color: var(--rdco-terracotta); text-decoration-color: var(--rdco-terracotta); }
When to use: inline links in body text. Underline always visible (not appear-on-hover).
card-default
<div class="rdco-card">
<h3 class="rdco-h3">Card heading</h3>
<p>Body content.</p>
</div>
.rdco-card { background: var(--rdco-cream); border: 1px solid var(--rdco-paper-line); border-radius: 12px; padding: 24px; }
When to use: content container on a cream or lavender page. For doodle/illustration tiles, use .rdco-doodle-field or .rdco-cutout-tile instead.
card-doodle-field
<div class="rdco-doodle-field"><!-- inline SVG doodle --></div>
.rdco-doodle-field { background: var(--rdco-lavender); border-radius: 24px; padding: 32px; position: relative; }
When to use: wrapping any hand-drawn illustration. The lavender field is the bed; the doodle is the subject.
citation
<figure class="rdco-citation">
<blockquote>"Quote text"</blockquote>
<figcaption><cite>- Source, 2026</cite></figcaption>
</figure>
.rdco-citation { border-left: 3px solid var(--rdco-paper-line); padding-left: 16px; }
.rdco-citation blockquote { font-family: var(--rdco-font-display); font-style: italic; font-size: 19px; color: var(--rdco-ink); margin: 0 0 8px; }
.rdco-citation figcaption { font-family: var(--rdco-font-mono); font-size: 13px; color: var(--rdco-graphite); text-transform: uppercase; letter-spacing: 0.08em; }
When to use: any quoted external source in body content. Italic display serif for the quote; mono caption for the citation.
graph-paper-band (motif, no token-bound component variant)
.rdco-graph-paper {
background-color: var(--rdco-cream);
background-image:
linear-gradient(to right, rgba(95, 78, 50, 0.05) 1px, transparent 1px),
linear-gradient(to bottom, rgba(95, 78, 50, 0.05) 1px, transparent 1px);
background-size: 24px 24px;
}
When to use: hero band, "this is editorial-grade" surfaces, footer wells. Never on top of body text.
Do's and Don'ts
Always:
- Hit all 5 tells on every umbrella surface (character beat / editorial type / textured background / one confident accent / visible authorship)
- Use the 60/30/10 palette discipline (surface / secondary / primary accent)
- Pair Source Serif (headlines) with Inter (body) and JetBrains Mono (code only)
- Set body type max-width to 65ch
- Use unspaced em-dashes sparingly (max ~2 per paragraph; overuse is the AI-tell, single use is fine) per softened
feedback_no_em_dashes2026-05-23 - Use sentence case for headlines
- Wrap doodles in
.rdco-doodle-field(lavender bed) - Use Lucide for icons
Never:
- Inter on pure white as an entire page
- Generic tech-blue CTA (terracotta is the umbrella accent)
- Flat vector character illustrations (cutout = OK; cartoon = NOT)
- Coolors.co-generated palettes
- Drop shadows on text
- Gradients on backgrounds (no aurora, mesh, grainy on the umbrella; bet skills may opt in with founder approval)
- Hand-drawn SVGs as icons (doodles and icons are separate layers)
- Mixing aesthetic layers on the same surface (doodle + Lucide, stylized + canonical Ray)
- Emoji as decoration (Ray is the only emotional glyph)
- Question marks in headlines
- "Welcome to..." opener
- Template heroes (every new surface must hit all 5 tells)
- Trust-through-restraint as the only valid posture
RDCO extension beyond Stitch core: Voice & Copy
(Sourced from 9-essay sample of Sanity Check archive 2021-2026; founder to refine periodically.)
Five attributes:
- Practitioner with receipts, not pundit. "What I'm seeing in real client engagements" - never "industry expert says." Authority through hours, not credentialing.
- Friendly contrarian. Counter-intuitive lead, paired with warmth - closer to "let me push back gently" than "you're all wrong."
- Concrete metaphor first, abstraction second. Kitchen / recipes for newsletter premise. Vending machine for black boxes. Woodworking for analytics-as-craft. Hand the reader a tangible carrier before the abstract idea.
- Em-dashes, you-pronoun, fragment paragraphs. Em-dashes load-bearing in voice but use sparingly (≤2 per paragraph). Overuse is the AI-tell, not single use. Per softened
feedback_no_em_dashes2026-05-23 (founder collapsed prior Ray-draft-ban + published-allow carve-out). - Earned closer, not a CTA. Re-state, re-frame. Never "subscribe / share / DM me."
Mechanics (hard rules):
- Em-dash spacing: unspaced (
word-word) in published HTML. Source markdown uses--, toolchain converts. - Casing: sentence case for headlines and section heads.
- Pronouns: "you" = reader; "we" = data community; "I" = personal stake.
- Numbers: spelled under ten ("three reasons"); digits 10+ and for years/metrics ("21 issues", "3am").
- Length: 300-800 words typical. Longer reserved for relaunches and manifestos.
- Tool names inline: plain text ("dbt", "Snowflake", "Looker") - NOT monospace.
Banned phrases / patterns:
- "Welcome to..." / "We're excited to announce..." / any opener that's not a claim or contrarian reframe
- "Trust through restraint" treated as the only valid posture
- Em-dash overuse (more than ~2 per paragraph) - single em-dash is fine per softened
feedback_no_em_dashes2026-05-23 - Generic vendor-pitch register ("powerful, intelligent, scalable")
- Question-mark headlines (declarative only)
Signature moves:
- Opener that names the contrarian frame in one sentence
- Concrete-metaphor-first technique
- Em-dash for the second clause in published copy
- Single-sentence rhythm paragraph for emphasis
- Earned closer that re-frames the whole piece
Corpus sources: see ~/.claude/skills/ray-data-co-design/brand-spec.txt [VOICE] section.
RDCO extension beyond Stitch core: Format-specific templates
| Surface | Dimensions | Margins / safe area | Notes |
|---|---|---|---|
| PDF letter (memo / one-pager) | 8.5" x 11" (612 x 792 pt) | 0.75" top/bottom, 1" left/right | See "PDF (letter, Typst substrate)" subsection below for contract-grade spec |
| PDF tabloid (poster / handout) | 11" x 17" (792 x 1224 pt) | 1" all sides | Hero treatment allowed |
| Landing-page hero (desktop) | 1440 x 900 | 24px gutters | Hero display 96px, 18ch max width |
| Landing-page hero (mobile) | 393 x 852 (iPhone 15 Pro reference) | 16px gutters | Hero display clamps to 48px |
| LinkedIn vertical post | 1080 x 1350 | 80px safe | Source Serif H1, single hero element |
| LinkedIn square post | 1200 x 1200 | 80px safe | Single quote treatment |
| Instagram square | 1080 x 1080 | 80px safe | Editorial type lockup over cutout tile |
| Instagram story / Reel | 1080 x 1920 | top 250 / bottom 350 safe | Hero element centered |
| Open Graph image | 1200 x 630 | 60px safe | Editorial type + signature character beat |
| Email body | max-width 600px | 32px side padding | Inter 16-17px body, single column |
| Editorial article (web) | content column 65ch | 24px gutter | Body 17-19px, Source Serif h1-h2, optional drop-cap |
iOS app screens: umbrella does not define iOS templates directly - sub-bet skills (e.g. squarely-design) do.
PDF (letter, Typst substrate)
Status: contract-grade as of 2026-05-23 (SpaceX v4 build). The Chrome-headless-to-PDF path is deprecated for investment memos and any long-form RDCO PDF. Reason: Chrome's CSS Paged Media has known gaps that produced v3-era defects (white border, orphan callouts, font-size drift). Typst is document-first with first-class page-break and embed-font primitives. See ~/.claude/state/pdf-quality-bar-synthesis.md for full diagnosis.
Substrate: Typst (open source, single-binary, Rust-based). Install via brew install typst. Verified 0.14.2 minimum.
Page setup (enforces patterns A1 / A7 / A9 from synthesis):
#set page(
paper: "us-letter", // 8.5" x 11"
margin: (top: 0.75in, bottom: 0.75in, left: 1in, right: 1in),
fill: rgb("#f5efe1"), // colors.surface — cream edge-to-edge, no white margin band
footer: footer-content, // see Footer below
)
Cream MUST be set via page(fill:), not via a body background — that is the v3 white-border fix. Typst paints the entire physical page including the margin, eliminating the Chrome bleed mismatch.
Typography (enforces pattern A1 / C1, fixes v3 font-too-small defect):
#set text(
font: "Inter",
size: 11pt, // MINIMUM. Below 11pt fails the quality bar.
fill: rgb("#1f1d1a"), // colors.tertiary
lang: "en", region: "US",
)
#show heading.where(level: 1): set text(font: "Source Serif 4", weight: "semibold", size: 28pt)
#show heading.where(level: 2): set text(font: "Source Serif 4", weight: "semibold", size: 20pt)
#show heading.where(level: 3): set text(font: "Source Serif 4", weight: "semibold", size: 16pt)
Body family: Inter 11pt only (no 10.5pt fallback for fit). Headlines: Source Serif 4 28/20/16 scale.
Code / metadata: JetBrains Mono 9-10pt for eyebrows and inline-mono.
Color tokens (enforces pattern A2 / C3, RDCO 60/30/10 discipline):
#let cream = rgb("#f5efe1") // surface (60%)
#let lavender = rgb("#d6d3f0") // secondary (30%)
#let oxblood = rgb("#a64f3a") // primary accent (10%) — only on left rails, CTA, hero em
#let ink = rgb("#1f1d1a") // body type
#let graphite = rgb("#5a5650") // bylines, eyebrows
EXACTLY 5 colors. No additional shades. Charts use these tokens, not Excel defaults.
Callouts (enforces patterns A3 / A8, fixes v3 orphan-callout defect):
ONE class only. Lavender fill with oxblood left-rail. Use Typst's block(breakable: false) — Typst's first-class page-break primitive treats unbreakable blocks as atomic units that push to the next page rather than straddle.
#let callout(body) = block(
breakable: false, // hard rule, fixes v3 defect
width: 100%,
fill: lavender,
stroke: (left: 3pt + oxblood),
inset: (x: 14pt, y: 12pt),
radius: (right: 4pt),
)[#body]
Executive summary (enforces pattern C4): REQUIRED first content block. Always a callout, always lead-with-decision (4 sentences max: recommendation / bull anchor / bear anchor / trigger). Sits directly under the title block, before any body prose.
Page-break discipline (enforces patterns A4 / A8):
- Each H1 starts a new page via explicit
pagebreak(weak: true)immediately before each= Sectionheading (except the executive summary, which lives on page 1 with the title). - Every figure / chart / callout uses
block(breakable: false). Typst enforces atomic placement — never splits across pages. - Trailing whitespace on a page before an H1 break is ACCEPTABLE quality (per pattern C3, restraint > decoration).
Footer (enforces pattern A7, footer-only branding on body pages):
#let footer-content = context {
let pn = counter(page).get().first()
if pn == 1 [
// cover gets full brand; if no separate cover, page-1 footer is quiet too
] else [
#set text(font: "JetBrains Mono", size: 8pt, fill: graphite)
#grid(columns: (1fr, auto, 1fr),
align: (left, center, right),
[Ray Data Co.], [#memo-title], [#pn]
)
]
}
Wordmark left, memo title center, page number right. JetBrains Mono 8pt graphite. No header on body pages.
Visuals (enforces patterns A8 / A10, brand-aligned chart styling):
- Use Typst native primitives only (
grid,table,rect,block). NO Excel-default colors. NO external chart libraries unless founder approves. - Every chart, table, or block-figure wraps in
block(breakable: false). - Bar charts:
rect(fill: ink, width: 80%)style — solid brand colors, integer-percent widths. - Tables:
table()with header row filledink(cream text), body cells with lavender highlight for emphasis rows.
Cover page (optional): If used, zero body content. Title + dek + byline + (optional) doodle illustration only. Set via standalone pagebreak(to: "odd") after title block. For most memos under 5 pages, skip the cover and lead with title-block + exec-summary callout on page 1.
Font sourcing:
Inter, Source Serif 4, JetBrains Mono are RDCO-approved. Source from official open-source releases (Inter: rsms/inter GitHub; Source Serif 4: adobe-fonts/source-serif; JetBrains Mono: JetBrains/JetBrainsMono). Drop TTFs into a fonts directory and invoke typst compile --font-path ./fonts src.typ out.pdf. Permanent staging location: ~/.claude/skills/ray-data-co-design/fonts-ttf/ (move from per-build /tmp/ once first build settles).
Compile invocation:
typst compile --font-path /Users/ray/.claude/skills/ray-data-co-design/fonts-ttf \
source.typ output.pdf
Validation (the 12 pdf-critic checks, enforced before founder sees the PDF):
- Cream background edge-to-edge (no white margin band — sample corners)
- No callout straddles a page break
- Body font ≥11pt
- ≤5 distinct colors in non-image regions
- Single body font family (Inter)
- Cover page (if any) has zero body paragraphs
- Executive summary is the visually-distinct first content block
- No orphan headings (heading at bottom-of-page with body on next)
- Page numbers consistent across body pages
- Brand wordmark in footer only (not in every body header)
- Embedded fonts are only Inter / Source Serif 4 / JetBrains Mono
- Hard page break before each H1
PASS: ≥8 of 12. ITERATE: 5-7. SCRAP: <5.
Reference build: /tmp/spacex-ipo-defense-memo-v4.pdf (SpaceX IPO memo, 2026-05-23).
RDCO extension beyond Stitch core: Asset inventory
Skill home: /Users/ray/.claude/skills/ray-data-co-design/
| Path | Type | Description |
|---|---|---|
/Users/ray/.claude/skills/ray-data-co-design/SKILL.md |
spec | Agent skill entrypoint |
/Users/ray/.claude/skills/ray-data-co-design/README.md |
doc | Full brand context (306 lines) |
/Users/ray/.claude/skills/ray-data-co-design/brand-spec.txt |
spec | Plain-text grep-friendly rules (371 lines) |
/Users/ray/.claude/skills/ray-data-co-design/video-spec.txt |
spec | Video-surface extensions (362 lines) |
/Users/ray/.claude/skills/ray-data-co-design/colors_and_type.css |
code | CSS variables + semantic classes (244 lines) |
Mascot variants (/Users/ray/.claude/skills/ray-data-co-design/assets/):
| Filename | Use case |
|---|---|
editorial-engraving.png |
Editorial-essay header, drip-email header (hedcut Ray) |
hand-drawn-notebook.png |
Concept-stage / sketch surfaces, 404 page |
cyberpunk-glitch.png |
Playful / MAC-pack candidate variant |
memphis-design.png |
Puzzle-adjacent candidate variant |
modern-minimalism.png |
Restrained Ray - use sparingly |
sc-stingray.png |
Sanity Check stingray heritage mark |
sc-stingray-alt.png |
SC stingray, alternate render |
External canonical sources:
| Path | Description |
|---|---|
/Users/ray/rdco-video-studio/public/ray-character/ray-original.jpeg |
Canonical 3-layer rigged Ray - the foundational brand mark |
/Users/ray/rdco-video-studio/public/ray-character/ray-transparent.png |
Canonical, transparent PNG for compositing |
/Users/ray/rdco-video-studio/public/ray-character/ray-neutral-front.png |
Face-camera neutral pose (founder-approved 2026-05-04) |
/Users/ray/rdco-vault/06-reference/design-mood-board/ray-mascot-variants/ |
15 stylized mascot variants library |
/Users/ray/rdco-sc/public/doodles/ |
Full Sanity Check doodle archive (25+ doodles) |
/Users/ray/rdco-vault/06-reference/design-mood-board/ |
Full mood-board reference library |
/Users/ray/rdco-vault/06-reference/design-mood-board/2026-04-23-founder-taste-synthesis.md |
Load-bearing founder taste signal this design encodes |
Sub-bet design contracts (children):
/Users/ray/rdco-vault/02-sops/DESIGN-sanity-check.md/Users/ray/rdco-vault/02-sops/DESIGN-squarely.md/Users/ray/rdco-vault/02-sops/DESIGN-mac.md
Cross-references
/Users/ray/rdco-vault/02-sops/typography-guide.md- full type-classification reference/Users/ray/rdco-vault/06-reference/design-mood-board/README.md- mood board taxonomy/Users/ray/.claude/projects/-Users-ray/memory/feedback_design_taste_high_personality.md- durable founder taste memory/Users/ray/.claude/projects/-Users-ray/memory/feedback_no_em_dashes.md- em-dash discipline (softened 2026-05-23: ≤2 per paragraph, overuse is the tell)/Users/ray/.claude/skills/design-critic/SKILL.md- autonomous critic that scores surfaces against this contract- Reference sample:
/Users/ray/rdco-vault/02-sops/design-samples/rdco-sample.html+.pdf