Skip to main content

Story Flow Theme

A content-first reading design for clifford.ressel.fyi. Serif typography, narrow content width, generous whitespace.

Colors​

:root {
--sf-bg: #fafafa;
--sf-bg-secondary: rgba(0, 0, 0, 0.03);
--sf-text: #333;
--sf-text-muted: #999;
--sf-text-secondary: #555;
--sf-accent: #111;
--sf-border: #ddd;
}

[data-theme='dark'] {
--sf-bg: #1a1a1a;
--sf-bg-secondary: rgba(255, 255, 255, 0.03);
--sf-text: #e8e8e8;
--sf-text-muted: #9a9a9a;
--sf-text-secondary: #aaa;
--sf-accent: #fff;
--sf-border: #333;
}

Dark mode muted text uses #9a9a9a (not #777) to meet WCAG AA 4.5:1 contrast.

Fonts​

  • Body/headings: 'Libre Baskerville', Georgia, serif
  • UI/metadata: 'Inter', sans-serif
  • Code: 'JetBrains Mono', 'SF Mono', Monaco, Consolas, monospace
  • Loaded via Google Fonts in docusaurus.config.js headTags

Typography Scale​

ElementSizeWeightLine Height
Body text17px4001.9
Post title (list)28px7001.35
Post title (page)32px7001.3
h224px700-
h320px700-
h418px700-
Metadata13-14px4001.4
Drop cap56px (48px mobile)7001.0

Spacing​

ElementValue
Post card margin60px bottom
Admonitions/code blocks2.5em vertical
Pagination60px top
Paragraph margin1.5em bottom
h2 margin2em top, 0.75em bottom
h3 margin1.75em top, 0.5em bottom

No blue links. Links use --sf-text color with underlines for WCAG distinguishability:

.markdown a:not(.hash-link) {
text-decoration: underline;
text-decoration-thickness: 1px;
text-underline-offset: 2px;
}

Footer links also get underlines for accessibility.

Key Learnings​

Container width: Don't set .container to 600px - it breaks sidebars. Docusaurus uses one container for the entire row. Keep container at 1200px and constrain main content:

.theme-blog-post-page main > .container > .row > .col:not([class*="col--3"]) {
max-width: 650px;
margin: 0 auto;
}

Blog list uses 700px max-width.

Sidebar widths: 280px default, 320px on screens > 1400px.

Drop caps: Use .markdown > p:first-of-type (direct child >) to prevent drop caps inside admonitions. Also add explicit resets:

.blog-list-page .markdown .admonition p::first-letter,
.blog-list-page .markdown .theme-admonition p::first-letter {
font-size: inherit;
float: none;
/* ... reset all properties */
}

Giscus spacing: CSS margin on .giscus doesn't work (iframe isolation). Use <br /> and <hr /> elements in the BlogPostItem component. Giscus themes: dark_dimmed / light.

Sidebar hiding: Needs explicit display: none at 996px breakpoint (Docusaurus mobile breakpoint).

Flat design exclusions: Apply box-shadow: none; border-radius: 0; only to Docusaurus components, not globally. Exclude .giscus, .giscus-frame, [class*="mermaid"]. Preserve .avatar__photo { border-radius: 50% !important; }.

Admonition borders: Use Infima color variables for semantic colors:

  • note: --ifm-color-secondary-dark
  • tip: --ifm-color-success
  • info: --ifm-color-info
  • warning: --ifm-color-warning
  • danger: --ifm-color-danger

Inline code vs code blocks: Must explicitly reset inline code styles inside pre code:

.theme-blog-post-page .markdown pre code {
background: none;
border: none;
padding: 0;
}

Accessibility​

  • Focus: outline: 2px solid var(--sf-accent); outline-offset: 2px;
  • Reduced motion: transition-duration: 0.01ms !important;
  • Selection: background: var(--sf-accent); color: var(--sf-bg);

Lighthouse Scores​

  • Accessibility: 96%
  • Performance: 75% (fonts + Docusaurus core)

Remaining issue: Prism/Dracula comment color (#6272a4) is 4.31:1 - slightly under WCAG AA 4.5:1. Outside our scope.