JJK.engineer — Design Tokens

For Claude Code: Reference this file when writing any CSS. All visual values come from these tokens. Never hardcode colors, font sizes, spacing, or breakpoints — always use the corresponding --jjk-* custom property. If a value you need isn’t here, ask the developer before inventing one.

Last Updated: February 13, 2025


Color System

The palette reads as “serious technical publication” in both modes. Accent color provides just enough personality without screaming “look at me.” All colors must maintain WCAG AA contrast ratios against their intended backgrounds.

Light Mode (default)

Token Value Usage
--jjk-color-bg #FAFAF8 Page background — warm white, not sterile
--jjk-color-surface #FFFFFF Cards, elevated containers
--jjk-color-surface-alt #F0EFEB Subtle differentiation — code blocks, callout backgrounds
--jjk-color-ink #1A1A1A Primary text — near-black, easy on the eyes
--jjk-color-ink-muted #6B6B6B Secondary text — dates, captions, metadata
--jjk-color-ink-faint #A3A3A3 Tertiary text — placeholders, disabled states
--jjk-color-accent #B45309 Burnt orange — links, interactive elements, the “corporate safety sign” energy
--jjk-color-accent-hover #92400E Darker accent for hover states
--jjk-color-accent-subtle #FEF3C7 Light amber wash — accent backgrounds, highlights
--jjk-color-on-accent #FFFFFF Text/icons placed directly on accent-colored surfaces (buttons, badges)
--jjk-color-border #E5E5E0 Dividers, card borders — barely there
--jjk-color-border-strong #C5C5BE Emphasized borders when needed
--jjk-color-danger #DC2626 Errors, destructive actions
--jjk-color-success #16A34A Confirmations, positive states
--jjk-color-draft-banner #FBBF24 Draft post banner background
--jjk-color-scheduled-banner #60A5FA Scheduled post banner background

Dark Mode (prefers-color-scheme: dark)

Token Value Usage
--jjk-color-bg #141413 Deep warm black
--jjk-color-surface #1E1E1C Elevated surfaces
--jjk-color-surface-alt #2A2A27 Code blocks, callouts
--jjk-color-ink #E8E8E3 Primary text — warm off-white
--jjk-color-ink-muted #9C9C95 Secondary text
--jjk-color-ink-faint #6B6B65 Tertiary text
--jjk-color-accent #F59E0B Amber — slightly brighter in dark mode for contrast
--jjk-color-accent-hover #FBBF24 Lighter on hover in dark mode
--jjk-color-accent-subtle #292218 Muted amber wash
--jjk-color-on-accent #FFFFFF Unchanged — white maintains contrast on amber
--jjk-color-border #2E2E2B Subtle dividers
--jjk-color-border-strong #4A4A45 Emphasized borders
--jjk-color-danger #EF4444 Slightly brighter for dark backgrounds
--jjk-color-success #22C55E Slightly brighter for dark backgrounds
--jjk-color-draft-banner #92400E Darker amber for dark mode
--jjk-color-scheduled-banner #1E40AF Darker blue for dark mode

Background Decoration Layer

Token Value Usage
--jjk-color-decoration 0, 0, 0 (light) / 255, 255, 255 (dark) RGB base for SVG background elements — used with rgba()
--jjk-decoration-opacity 0.04 Default opacity for background SVGs — barely visible until you look

Typography

The type system pairs a clean serif for headings (the “serious publication” energy) with a readable sans-serif for body text. Monospace for code. All sizes use a modular scale.

Font Families

Token Value Fallback Stack
--jjk-font-heading 'Playfair Display' Georgia, 'Times New Roman', serif
--jjk-font-body 'Inter' system-ui, -apple-system, sans-serif
--jjk-font-mono 'JetBrains Mono' 'Fira Code', 'Cascadia Code', monospace

Font Sizes (modular scale, base 1rem = 16px, ratio ~1.25)

Token Value Usage
--jjk-text-xs 0.75rem Fine print, legal jokes
--jjk-text-sm 0.875rem Captions, metadata, tag labels
--jjk-text-base 1rem Body text
--jjk-text-lg 1.125rem Lead paragraphs, slightly emphasized body
--jjk-text-xl 1.25rem H4, sub-sub-headings
--jjk-text-2xl 1.5rem H3
--jjk-text-3xl 1.875rem H2
--jjk-text-4xl 2.25rem H1 (post titles)
--jjk-text-5xl 3rem Hero/display text (rare)

Line Heights

Token Value Usage
--jjk-leading-tight 1.25 Headings
--jjk-leading-normal 1.6 Body text — generous for reading comfort
--jjk-leading-loose 1.8 Spacious layouts if needed

Font Weights

Token Value Usage
--jjk-weight-normal 400 Body text
--jjk-weight-medium 500 Slightly emphasized text, nav items
--jjk-weight-semibold 600 Sub-headings, bold UI elements
--jjk-weight-bold 700 Headings, strong emphasis

Spacing

Eight-point grid. Every spacing value is a multiple of 0.5rem (8px). Do not invent spacing values outside this scale.

Token Value Common Usage
--jjk-space-1 0.25rem Tight internal padding (icon gaps)
--jjk-space-2 0.5rem Compact padding, inline element gaps
--jjk-space-3 0.75rem Button padding, tight card padding
--jjk-space-4 1rem Default element spacing
--jjk-space-6 1.5rem Section internal padding
--jjk-space-8 2rem Between content blocks
--jjk-space-12 3rem Between major sections
--jjk-space-16 4rem Page-level vertical rhythm
--jjk-space-24 6rem Large section separators, hero spacing

Layout

Token Value Usage
--jjk-content-width 42rem Max width for prose content — optimal reading line length
--jjk-wide-width 64rem Max width for wider layouts (tools, dashboards)
--jjk-full-width 80rem Max width for the outermost page container
--jjk-sidebar-width 16rem Navigation sidebar when present
--jjk-header-height 3.5rem Sticky header height

Aspect Ratios

Token Value Usage
--jjk-aspect-cover 16 / 9 Post feature images — hero and card thumbnail

Breakpoints

Mobile-first. Styles default to mobile, then layer on complexity at wider viewports.

Token Value Target
--jjk-bp-sm 640px Large phones, small tablets
--jjk-bp-md 768px Tablets
--jjk-bp-lg 1024px Small desktops, landscape tablets
--jjk-bp-xl 1280px Standard desktops
--jjk-bp-2xl 1536px Wide desktops

Note: CSS custom properties can’t be used in @media queries. Use these values directly in media queries but keep them consistent with the tokens documented here. If using a build step or CSS-in-JS that supports variable media queries in the future, migrate to tokens then.


Borders & Radii

Token Value Usage
--jjk-radius-sm 0.25rem Subtle rounding — tags, small buttons
--jjk-radius-md 0.5rem Cards, input fields
--jjk-radius-lg 0.75rem Modals, large containers
--jjk-radius-full 9999px Pills, avatars
--jjk-border-width 1px Default border width
--jjk-border-width-thick 2px Table headers, active tab underlines

Component Sizing

Token Value Usage
--jjk-badge-size 1.25rem Notification badge min-width & height

Heatmap Palette

GitHub contribution-graph palette used for the timeclock heatmap. Responds to light/dark theme via tokens.

Token Light Dark
--jjk-heatmap-level-1 #9be9a8 #0e4429
--jjk-heatmap-level-2 #40c463 #006d32
--jjk-heatmap-level-3 #30a14e #26a641
--jjk-heatmap-level-4 #216e39 #39d353

Level 0 uses the existing --jjk-color-surface-alt token.


Transitions

Token Value Usage
--jjk-transition-fast 120ms ease Hover states, micro-interactions
--jjk-transition-normal 200ms ease Most UI transitions
--jjk-transition-slow 350ms ease Expanding panels, layout shifts
--jjk-transition-color 200ms ease Color/background transitions — used for dark/light mode switch

Shadows

Token Value Usage
--jjk-shadow-sm 0 1px 2px rgba(0,0,0,0.06) Subtle lift — tags, small elements
--jjk-shadow-md 0 2px 8px rgba(0,0,0,0.08) Cards, dropdowns
--jjk-shadow-lg 0 8px 24px rgba(0,0,0,0.12) Modals, floating elements

Dark mode should reduce shadow intensity since dark surfaces don’t cast visible shadows — rely on border or surface color differentiation instead.


Z-Index Scale

Defined scale prevents z-index wars. Do not use arbitrary z-index values.

Token Value Usage
--jjk-z-base 0 Default stacking
--jjk-z-raised 10 Sticky elements within flow
--jjk-z-header 100 Sticky header
--jjk-z-dropdown 200 Dropdowns, popovers
--jjk-z-modal 300 Modal overlays
--jjk-z-toast 400 Notifications, toasts
--jjk-z-tooltip 500 Tooltips (always on top)


Token Gaps — Planned Additions

These gaps exist in the current codebase. Add the tokens here (and to tokens.css) before fixing the affected files.

Planned Token Value (light) Needed For
--jjk-color-accent-rgb 180, 83, 9 rgba() in pulse-ring animation (investors.component.css lines 529, 535, 538)
--jjk-color-danger-rgb 220, 38, 38 rgba() for danger focus ring and error background (contact.component.css lines 132, 201)

Use the same pattern as --jjk-color-decoration: store as bare RGB components (R, G, G) so consumers can write rgba(var(--jjk-color-accent-rgb), 0.4).

Dark mode values: --jjk-color-accent-rgb: 245, 158, 11 / --jjk-color-danger-rgb: 239, 68, 68.


These tokens are the single source of truth for all visual values. If a component needs a value not listed here, add it to this file first — then use it. Never hardcode.