diff --git a/AGENTS.md b/AGENTS.md index 794c391..86d6132 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -57,7 +57,7 @@ When the user mentions these keywords, load the corresponding skill: | "debug this", "root cause", "why is this broken", "fix this bug" | [systematic-debugging](systematic-debugging/SKILL.md) | | "epub", "ebook", "EPUB file", "ebook format", "read epub", "write epub", "create ebook", "extract from epub", "epub to text", "edit epub", "repair epub", "convert epub2", "epub images", "batch epub", "ebook metadata" | [epub](epub/SKILL.md) | | "gutenberg", "public domain", "download a book", "classic literature", "free ebook", "gutenberg.org", "project gutenberg", "PG", "gutendex" | [gutenberg](gutenberg/SKILL.md) | -| "hugo theme", "hugo cms", "hugo template", "hugo pipes", "hugo module", "hugo shortcode", "render hook", "tailwindcss hugo", "hugo i18n", "hugo seo", "hugo output format", "hugo site", "hugo static site" | [hugo-theme](hugo-theme/SKILL.md) | +| "hugo theme", "hugo cms", "accessible theme", "wcag theme", "theme design", "theme accessibility", "theme UX", "design tokens", "css theme", "theme contrast", "responsive theme", "hugo template", "hugo pipes", "hugo module", "hugo shortcode", "render hook", "tailwindcss hugo", "hugo i18n", "hugo seo", "hugo output format", "hugo site", "hugo static site" | [hugo-theme](hugo-theme/SKILL.md) | | "weather", "forecast", "temperature", "is it raining", "Tempest" | [tempest-cli](tempest-cli/SKILL.md) | | "reverse-engineer", "understand this codebase", "PRD from code", "architecture document" | [software-architecture-analysis](software-architecture-analysis/SKILL.md) | | "data architecture", "data platform", "data strategy", "data mesh", "governance" | [data-architect](data-architect/SKILL.md) | diff --git a/README.md b/README.md index e0a3892..860a22a 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ Search, download, and extract public-domain books from Project Gutenberg. Look u ### [hugo-theme](hugo-theme/SKILL.md) -Build, customize, and debug advanced Hugo CMS themes. Covers template architecture, asset pipeline (Hugo Pipes, Tailwind CSS, PostCSS, images), shortcodes and render hooks, page bundles and content adapters, Hugo Modules, performance optimization, SEO/structured data, custom output formats, and CI/CD. Ships 6 reference files covering each topic area. +Build, customize, and debug advanced Hugo CMS themes. Covers template architecture, asset pipeline (Hugo Pipes, Tailwind CSS, PostCSS, images), shortcodes and render hooks, page bundles and content adapters, Hugo Modules, performance optimization, SEO/structured data, design/UX/accessibility, custom output formats, and CI/CD. Ships 7 reference files covering each topic area. ### [ghost-cli](ghost-cli/SKILL.md) diff --git a/hugo-theme/SKILL.md b/hugo-theme/SKILL.md index dd3c3bc..3a321dc 100644 --- a/hugo-theme/SKILL.md +++ b/hugo-theme/SKILL.md @@ -27,6 +27,7 @@ Intermediate-to-advanced patterns for Hugo CMS theme development. Load the relev | **Shortcodes & Render Hooks** | You need complex nested shortcodes, raw HTML shortcodes, markdown rendering inside shortcodes, custom render hooks for links/images/headings/code blocks, or language-specific code block rendering (Mermaid, etc.) | `references/shortcodes-and-hooks.md` | | **Content Organization & i18n** | You're working with leaf vs branch bundles, headless bundles, custom taxonomies, content adapters (v0.126+, dynamic pages), section-specific layouts, archetypes, or internationalization (translation tables, multilingual) | `references/content-and-i18n.md` | | **Modules & Performance** | You're using Hugo Modules (init, import, vendor, workspace), building theme components with mount configuration, optimizing build speed with `partialCached`, configuring cache TTLs, or using configuration-driven theming (params, cascade) | `references/modules-and-performance.md` | +| **Design, UX & Accessibility** | You need typography systems, accessible color palettes, design tokens, semantic HTML landmarks, ARIA patterns, keyboard navigation, accessible forms, content-first layouts, responsive navigation, engagement patterns (reading progress, dark mode toggle, sharing), Core Web Vitals optimization, container queries, `:has()` selectors, or testing/QA automation (axe-core, Lighthouse CI, visual regression) | `references/design-accessibility.md` | | **SEO, Output Formats & CI/CD** | You need JSON-LD structured data, Open Graph / Twitter Cards, custom output formats (JSON, AMP), sitemap customization, or CI/CD pipelines for themes (GitHub Actions, testing, deployment) | `references/seo-outputs-testing.md` | ## Quick Start diff --git a/hugo-theme/references/design-accessibility.md b/hugo-theme/references/design-accessibility.md new file mode 100644 index 0000000..d3faad3 --- /dev/null +++ b/hugo-theme/references/design-accessibility.md @@ -0,0 +1,1454 @@ +# Design, UX & Accessibility for CMS Themes + +Platform-agnostic guidance for building beautiful, inclusive, and performant CMS themes. Applies to Hugo, WordPress, Ghost, Statamic, Craft CMS, Jekyll, Eleventy — any system that renders templates to HTML. + +--- + +## Table of Contents + +1. [Typography Systems](#1-typography-systems) +2. [Accessible Color & Contrast](#2-accessible-color--contrast) +3. [Spacing & Layout](#3-spacing--layout) +4. [Design Tokens & Theming](#4-design-tokens--theming) +5. [Semantic HTML & Landmarks](#5-semantic-html--landmarks) +6. [ARIA & Dynamic Content](#6-aria--dynamic-content) +7. [Keyboard Navigation & Focus](#7-keyboard-navigation--focus) +8. [Accessible Forms & Search](#8-accessible-forms--search) +9. [Content-First Design Patterns](#9-content-first-design-patterns) +10. [Navigation & Information Architecture](#10-navigation--information-architecture) +11. [Engagement Patterns](#11-engagement-patterns) +12. [Performance & Core Web Vitals](#12-performance--core-web-vitals) +13. [Modern CSS for Themes](#13-modern-css-for-themes) +14. [Theme Testing & QA](#14-theme-testing--qa) +15. [Sources & References](#15-sources--references) + +--- + +## 1. Typography Systems + +### 1.1 Fluid Type Scale + +A modular type scale ensures visual harmony across headings and body text. Use `clamp()` to size fluidly between viewport widths without media queries: + +```css +:root { + --step--2: clamp(0.6944rem, 0.6515rem + 0.2144vw, 0.8333rem); + --step--1: clamp(0.8333rem, 0.7708rem + 0.3125vw, 1rem); + --step-0: clamp(1rem, 0.9115rem + 0.4427vw, 1.25rem); + --step-1: clamp(1.2rem, 1.0755rem + 0.6224vw, 1.5625rem); + --step-2: clamp(1.44rem, 1.2665rem + 0.8671vw, 1.9531rem); + --step-3: clamp(1.728rem, 1.4885rem + 1.1979vw, 2.4414rem); + --step-4: clamp(2.074rem, 1.7466rem + 1.6372vw, 3.0518rem); + --step-5: clamp(2.488rem, 2.0463rem + 2.2084vw, 3.8147rem); +} + +h1 { font-size: var(--step-5); } +h2 { font-size: var(--step-3); } +h3 { font-size: var(--step-2); } +body { font-size: var(--step-0); } +small { font-size: var(--step--1); } +``` + +**Typography best practices:** +- Body text: 16–18px (1rem–1.125rem) as base +- Line height: 1.5–1.7 for body, 1.1–1.3 for headings +- Measure (line length): 45–75 characters per line, ideal 66 CPL. WCAG 1.4.8 (AAA) mandates max 80 CPL. +- Use `ch` units for text container width: `max-width: 65ch` +- Limit to 2–3 font families and 3–4 weights total + +### 1.2 Font Loading Strategy + +Self-host fonts as WOFF2 for performance and privacy: + +```css +@font-face { + font-family: 'BodyFont'; + src: url('/fonts/body-regular.woff2') format('woff2'); + font-display: swap; /* Show fallback text immediately */ + font-weight: 400; + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, + U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, + U+FEFF, U+FFFD; +} +``` + +```html + + +``` + +Never use `font-display: block` — it hides text for up to 3 seconds while the font loads, creating a flash of invisible text (FOIT). Use `swap` to render fallback text immediately, or `optional` if you'd rather fall back to the system font entirely on slow connections. + +### 1.3 WCAG Text Spacing (SC 1.4.12) + +Users may override your text spacing for readability. Ensure no content loss when these overrides are applied: + +```css +.prose p { + line-height: 1.5; /* minimum 1.5× font size */ + margin-bottom: 1.5em; /* 1.5× spacing between paragraphs */ + word-spacing: 0.16em; + letter-spacing: 0.12em; +} +``` + +The WCAG text spacing bookmarklet applies these overrides — test with it during development. + +--- + +## 2. Accessible Color & Contrast + +### 2.1 WCAG Contrast Requirements + +**WCAG 2.2 minimum ratios (SC 1.4.3 & 1.4.6):** + +| Level | Normal text | Large text (18pt+ / 14pt bold) | UI components & graphics | +|-------|-------------|--------------------------------|--------------------------| +| AA | ≥ 4.5:1 | ≥ 3:1 | ≥ 3:1 (SC 1.4.11) | +| AAA | ≥ 7:1 | ≥ 4.5:1 | n/a | + +### 2.2 Designing an Accessible Palette + +Choose color tokens that meet contrast from the start — don't fix them later: + +```css +:root { + /* Text — all ≥8.6:1 on white */ + --color-text-primary: #1a1a1a; /* 15:1 on white */ + --color-text-secondary: #4a4a4a; /* 8.6:1 on white */ + + /* Use muted text sparingly — it must still be readable */ + --color-text-muted: #6b6b6b; /* 5.2:1 on white — small text minimum */ + + /* Brand colors with accessible contrast on their expected backgrounds */ + --color-primary: #0055cc; /* 4.8:1 on white, passes AA for text */ + --color-primary-text: #ffffff; /* for buttons on --color-primary */ + + /* Surface */ + --color-surface: #ffffff; + --color-surface-secondary: #f5f5f5; /* Sufficient contrast from white for borders */ + --color-border: #d4d4d4; +} +``` + +**Hard rules:** +- Never convey information by color alone — add icons, underlines, or text labels +- Links must have ≥ 3:1 contrast from body text AND an underline OR hover/focus underline +- Test all color pairs with WebAIM contrast checker or axe DevTools before shipping +- Test with `prefers-contrast: more` — a user preference for increased contrast + +### 2.3 Dark Mode + +```css +@media (prefers-color-scheme: dark) { + :root { + --color-surface: #1a1a2e; + --color-text-primary: #e8e8e8; + --color-text-secondary: #a0a0a0; + --color-border: #2a2a3e; + --color-link: #6ba3ff; + --color-link-hover: #8bb9ff; + --shadow-sm: 0 1px 3px rgba(0,0,0,0.3); + } +} + +/* Manual toggle override */ +[data-theme="dark"] { + --color-surface: #1a1a2e; + --color-text-primary: #e8e8e8; + /* ... same overrides ... */ +} +``` + +**Modern browsers** support `light-dark()` for simpler theme switching (Chrome 123+, Firefox 128+): + +```css +:root { + color-scheme: light dark; + --color-surface: light-dark(#ffffff, #1a1a2e); + --color-text-primary: light-dark(#1a1a1a, #e8e8e8); + --color-link: light-dark(#0055cc, #6ba3ff); +} +``` + +### 2.4 Theme Switching Without Flash + +Apply the user's preferred theme before any CSS renders to prevent a flash of incorrect theme: + +```html + +``` + +Place this inline in `` before any stylesheets. It blocks rendering for microseconds but prevents the jarring light-to-dark flash. + +--- + +## 3. Spacing & Layout + +### 3.1 Consistent Spacing Scale + +Base on a 4px or 8px unit: + +```css +:root { + --space-0: 0; + --space-1: 0.25rem; /* 4px */ + --space-2: 0.5rem; /* 8px */ + --space-3: 0.75rem; /* 12px */ + --space-4: 1rem; /* 16px */ + --space-5: 1.5rem; /* 24px */ + --space-6: 2rem; /* 32px */ + --space-7: 3rem; /* 48px */ + --space-8: 4rem; /* 64px */ + --space-9: 6rem; /* 96px */ +} +``` + +**Vertical rhythm** — consistent spacing between elements without thinking about each one: + +```css +/* CUBE CSS flow utility */ +.flow > * + * { + margin-top: var(--flow-space, 1em); +} +``` + +### 3.2 Content-Out Page Layout + +A content-first grid that gives you full-bleed and constrained regions without nested wrappers: + +```css +.page-layout { + display: grid; + grid-template-columns: + [full-start] minmax(1rem, 1fr) + [main-start] minmax(0, 65ch) + [main-end] minmax(1rem, 1fr) + [full-end]; +} + +.page-layout > * { + grid-column: main-start / main-end; /* All children default to content column */ +} + +.page-layout > .full-width { + grid-column: full-start / full-end; /* Opt in to full bleed */ +} +``` + +### 3.3 Responsive Card Grid + +No media queries needed: + +```css +.card-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(min(300px, 100%), 1fr)); + gap: var(--space-5); +} +``` + +**Responsive testing guidance:** +- Use content-driven breakpoints, not device-driven ones +- Test at every 100px width from 320px to 1600px +- WCAG 1.4.10 (Reflow) requires no horizontal scroll at 320px equivalent width +- Consider container queries for component-level responsiveness + +--- + +## 4. Design Tokens & Theming + +### 4.1 Token Architecture + +Layer tokens in a hierarchy: **Global → Semantic → Component** + +```css +/* Layer 1: Raw values (seldom change) */ +:root { + --color-blue-600: #0055cc; + --color-blue-700: #003d99; + --font-body: 'Inter', system-ui, sans-serif; + --font-heading: 'Inter', system-ui, sans-serif; + --font-mono: 'JetBrains Mono', 'Cascadia Code', monospace; +} + +/* Layer 2: Semantic tokens (theme-aware) */ +:root { + --color-surface: #ffffff; + --color-text: #1a1a1a; + --color-link: var(--color-blue-600); + --color-link-hover: var(--color-blue-700); + --spacing-section: 4rem; + --border-radius-sm: 4px; + --border-radius-md: 8px; + --shadow-sm: 0 1px 3px rgba(0,0,0,0.1); +} + +/* Layer 3: Component-level overrides (in component CSS files) */ +.card { + --card-padding: var(--space-4); + --card-radius: var(--border-radius-md); +} +``` + +### 4.2 User Preference Detection + +Always respect these user preferences: + +```css +/* High contrast */ +@media (prefers-contrast: more) { + :root { + --color-text: #000000; + --color-text-secondary: #1a1a1a; + --color-border: #000000; + } +} + +/* Reduced transparency */ +@media (prefers-reduced-transparency: reduce) { + * { + opacity: 1 !important; + backdrop-filter: none !important; + } +} +``` + +--- + +## 5. Semantic HTML & Landmarks + +### 5.1 Page Landmarks (WCAG 1.3.1) + +Every CMS theme should provide these landmark regions: + +```html + + + +
+ +
+ +
+
+

Page Title

+ +
+ +
+ + + +``` + +### 5.2 Heading Hierarchy (WCAG 1.3.1) + +- One `

` per page (usually the page/post title in CMS) +- Heading levels must not skip (h1 → h2 → h3, never h1 → h3) +- For CMS themes: ensure editors can't break hierarchy — provide visual guidance in the editor, or use a render hook that maps heading levels to a semantic hierarchy + +```html +
+

Post Title

+
+

Introduction

+

Sub-point

+
+
+``` + +### 5.3 Proper `