initial commit
This commit is contained in:
@@ -0,0 +1,166 @@
|
||||
# Accessibility Audit Workflow
|
||||
|
||||
**Purpose:** Agent-led accessibility review with explanations and suggestions
|
||||
|
||||
---
|
||||
|
||||
## How This Works
|
||||
|
||||
1. Agent reads the page specification and/or prototype code
|
||||
2. Agent evaluates each area against WCAG 2.1 AA
|
||||
3. Agent explains findings in plain language
|
||||
4. Agent proposes specific fixes
|
||||
5. User approves, rejects, or asks for alternatives
|
||||
|
||||
---
|
||||
|
||||
## Agent Instructions
|
||||
|
||||
### Step 1: Analyze Color Contrast
|
||||
|
||||
Read the design system colors and check:
|
||||
|
||||
```
|
||||
For each text element:
|
||||
- Calculate contrast ratio against background
|
||||
- WCAG AA requires: 4.5:1 for normal text, 3:1 for large text (18px+)
|
||||
|
||||
Report:
|
||||
"The button text (#FFFFFF) on primary background (#2563EB)
|
||||
has a contrast ratio of 8.6:1 ✓ Passes WCAG AA
|
||||
|
||||
The helper text (#9CA3AF) on white (#FFFFFF)
|
||||
has a contrast ratio of 2.9:1 ✗ Fails WCAG AA
|
||||
→ Suggestion: Darken to #6B7280 (4.6:1) or #4B5563 (7:1)"
|
||||
```
|
||||
|
||||
**Ask user:** "Should I darken the helper text to #6B7280?"
|
||||
|
||||
---
|
||||
|
||||
### Step 2: Analyze Keyboard Navigation
|
||||
|
||||
Read the page structure and determine logical tab order:
|
||||
|
||||
```
|
||||
Looking at the page layout, the logical keyboard flow should be:
|
||||
|
||||
1. Skip to main content link (hidden until focused)
|
||||
2. Logo (if clickable) → Home
|
||||
3. Navigation items left to right
|
||||
4. Main content, top to bottom
|
||||
5. Form fields in visual order
|
||||
6. Submit/action buttons
|
||||
7. Footer links
|
||||
|
||||
Current spec has these interactive elements:
|
||||
- `header-logo` ✓ Has behavior defined
|
||||
- `nav-home` ✓ Link
|
||||
- `form-email` ✗ Missing keyboard info
|
||||
- `submit-btn` ✗ Missing focus state
|
||||
|
||||
→ Suggestion: Add to form-email:
|
||||
| Keyboard | Tab to focus, type to enter |
|
||||
| Focus | 2px blue ring (#2563EB) |
|
||||
```
|
||||
|
||||
**Ask user:** "Should I add keyboard properties to these elements?"
|
||||
|
||||
---
|
||||
|
||||
### Step 3: Analyze Screen Reader Experience
|
||||
|
||||
Check each element has appropriate labels:
|
||||
|
||||
```
|
||||
Reviewing interactive elements:
|
||||
|
||||
`booking-submit` - Button with text "Book"
|
||||
→ Issue: "Book" alone may be unclear out of context
|
||||
→ Suggestion: aria-label="Book this walk slot"
|
||||
|
||||
`booking-cancel` - Icon button with X
|
||||
→ Issue: No text, screen reader says nothing
|
||||
→ Suggestion: aria-label="Cancel booking"
|
||||
|
||||
`status-indicator` - Colored dot (green/red/gray)
|
||||
→ Issue: Color only, no text alternative
|
||||
→ Suggestion: Add aria-label="Status: Available" and visually hidden text
|
||||
```
|
||||
|
||||
**Ask user:** "Should I add these aria-labels to the spec?"
|
||||
|
||||
---
|
||||
|
||||
### Step 4: Analyze Dynamic Content
|
||||
|
||||
Check state changes and notifications:
|
||||
|
||||
```
|
||||
This page has dynamic content:
|
||||
|
||||
State changes (drawer opens/closes):
|
||||
→ Need: aria-expanded on trigger, focus management
|
||||
→ Suggestion: When drawer opens, move focus to drawer header
|
||||
|
||||
Loading states:
|
||||
→ Need: aria-busy="true" on container, "Loading..." announcement
|
||||
→ Suggestion: Add aria-live="polite" region for status updates
|
||||
|
||||
Error messages:
|
||||
→ Need: aria-live="assertive" so errors are announced immediately
|
||||
→ Suggestion: Link error to field with aria-describedby
|
||||
```
|
||||
|
||||
**Ask user:** "Should I add these dynamic content specifications?"
|
||||
|
||||
---
|
||||
|
||||
### Step 5: Summary Report
|
||||
|
||||
```
|
||||
## Accessibility Audit Summary
|
||||
|
||||
### Passes ✓
|
||||
- Color contrast on primary buttons (8.6:1)
|
||||
- Semantic HTML structure (header, main, nav)
|
||||
- Form labels present
|
||||
|
||||
### Needs Attention ⚠
|
||||
- Helper text contrast (2.9:1 → needs 4.5:1)
|
||||
- 3 buttons missing aria-labels
|
||||
- Tab order not documented
|
||||
- Focus states not specified
|
||||
|
||||
### Recommendations
|
||||
1. Darken helper text to #6B7280
|
||||
2. Add aria-labels to icon buttons
|
||||
3. Document keyboard flow
|
||||
4. Specify focus ring style (2px #2563EB)
|
||||
|
||||
Implement these changes? [Yes to all / Review each / Skip]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference for Agent
|
||||
|
||||
| Check | WCAG Rule | Requirement |
|
||||
|-------|-----------|-------------|
|
||||
| Text contrast | 1.4.3 | 4.5:1 normal, 3:1 large |
|
||||
| Focus visible | 2.4.7 | Clear visual indicator |
|
||||
| Labels | 1.3.1 | All inputs labeled |
|
||||
| Keyboard | 2.1.1 | All functions keyboard accessible |
|
||||
| Error ID | 3.3.1 | Errors identified and described |
|
||||
| Name/Role | 4.1.2 | Interactive elements have accessible names |
|
||||
|
||||
---
|
||||
|
||||
## Agent Prompts
|
||||
|
||||
Use these to guide the conversation:
|
||||
|
||||
- "I found {N} contrast issues. Want me to explain each one?"
|
||||
- "This button has no accessible name. Should I suggest one based on its purpose?"
|
||||
- "The tab order seems unclear. Can you confirm the intended flow?"
|
||||
- "Screen readers won't announce this status change. Should I add aria-live?"
|
||||
@@ -0,0 +1,102 @@
|
||||
# Accessibility Specification
|
||||
|
||||
**Include when:** Specifying interactive elements, forms, or navigation
|
||||
|
||||
---
|
||||
|
||||
## For Each Interactive Element
|
||||
|
||||
When documenting buttons, links, inputs, add:
|
||||
|
||||
```markdown
|
||||
| Property | Value |
|
||||
|----------|-------|
|
||||
| aria-label | "{What it does}" |
|
||||
| Keyboard | {Enter / Space / Arrow keys} |
|
||||
| Focus style | {ring / outline / highlight} |
|
||||
```
|
||||
|
||||
**Example:**
|
||||
```markdown
|
||||
#### Submit Button
|
||||
**OBJECT ID:** `form-submit`
|
||||
|
||||
| Property | Value |
|
||||
|----------|-------|
|
||||
| aria-label | "Submit booking request" |
|
||||
| Keyboard | Enter or Space |
|
||||
| Focus | 2px blue ring |
|
||||
| Disabled state | aria-disabled="true", gray, no focus |
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Tab Order
|
||||
|
||||
Document the logical sequence:
|
||||
|
||||
```markdown
|
||||
## Keyboard Flow
|
||||
|
||||
1. `header-logo` → Home link
|
||||
2. `header-nav` → Main navigation
|
||||
3. `main-content` → Skip to here
|
||||
4. `form-name` → First input
|
||||
5. `form-email` → Second input
|
||||
6. `form-submit` → Submit button
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Dynamic Content
|
||||
|
||||
When content changes without page reload:
|
||||
|
||||
```markdown
|
||||
| Element | Announces |
|
||||
|---------|-----------|
|
||||
| `toast-success` | aria-live="polite" — "Booking confirmed" |
|
||||
| `error-message` | aria-live="assertive" — Error text |
|
||||
| `loading-spinner` | aria-busy="true" on parent |
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Color Independence
|
||||
|
||||
For status indicators, ensure alternatives:
|
||||
|
||||
| Status | Color | Also Has |
|
||||
|--------|-------|----------|
|
||||
| Success | Green | Checkmark icon + "Complete" text |
|
||||
| Error | Red | Warning icon + error message |
|
||||
| Active | Blue | Bold text + underline |
|
||||
|
||||
---
|
||||
|
||||
## Form Errors
|
||||
|
||||
Link errors to fields:
|
||||
|
||||
```markdown
|
||||
#### Email Error
|
||||
**OBJECT ID:** `form-email-error`
|
||||
|
||||
| Property | Value |
|
||||
|----------|-------|
|
||||
| aria-describedby | Links to `form-email` |
|
||||
| Role | "alert" |
|
||||
| Content | "Please enter a valid email" |
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Quick Checks
|
||||
|
||||
Before finalizing:
|
||||
|
||||
- [ ] Every button has aria-label or visible text
|
||||
- [ ] Every image has alt (or alt="" if decorative)
|
||||
- [ ] Every input has associated label
|
||||
- [ ] Focus visible on all interactive elements
|
||||
- [ ] Status not conveyed by color alone
|
||||
@@ -0,0 +1,69 @@
|
||||
# Data & API Requirements
|
||||
|
||||
**Include when:** Page requires data from APIs or external sources
|
||||
|
||||
---
|
||||
|
||||
## Data Sources
|
||||
|
||||
| Data Element | Source | Type | Required | Notes |
|
||||
|--------------|--------|------|----------|-------|
|
||||
| `{data-field}` | {API / static / localStorage} | {string / number / array} | {yes/no} | {notes} |
|
||||
|
||||
---
|
||||
|
||||
## API Endpoints
|
||||
|
||||
### {Endpoint Name}
|
||||
|
||||
| Property | Value |
|
||||
|----------|-------|
|
||||
| Method | {GET / POST / PUT / DELETE} |
|
||||
| Path | `/api/{path}` |
|
||||
| Purpose | {What this endpoint does} |
|
||||
| Auth | {Required / Optional / None} |
|
||||
|
||||
**Request:**
|
||||
```json
|
||||
{
|
||||
"field": "value"
|
||||
}
|
||||
```
|
||||
|
||||
**Response (Success):**
|
||||
```json
|
||||
{
|
||||
"data": {}
|
||||
}
|
||||
```
|
||||
|
||||
**Response (Error):**
|
||||
```json
|
||||
{
|
||||
"error": "message",
|
||||
"code": "ERR_XXX"
|
||||
}
|
||||
```
|
||||
|
||||
**Error Codes:**
|
||||
| Code | Meaning | User Message |
|
||||
|------|---------|--------------|
|
||||
| `{code}` | {technical meaning} | {user-friendly message} |
|
||||
|
||||
---
|
||||
|
||||
## Loading States
|
||||
|
||||
| State | Duration | UI |
|
||||
|-------|----------|-----|
|
||||
| Initial load | {expected ms} | {skeleton / spinner / etc.} |
|
||||
| Refresh | {expected ms} | {indicator type} |
|
||||
| Background | {expected ms} | {silent / toast} |
|
||||
|
||||
---
|
||||
|
||||
## Caching Strategy
|
||||
|
||||
| Data | Cache Duration | Invalidation |
|
||||
|------|----------------|--------------|
|
||||
| {data type} | {duration} | {when to refresh} |
|
||||
@@ -0,0 +1,54 @@
|
||||
# Form Validation
|
||||
|
||||
**Include when:** Page has forms or input fields
|
||||
|
||||
---
|
||||
|
||||
## Validation Rules
|
||||
|
||||
| Field | Rule | Error Code | Error Message |
|
||||
|-------|------|------------|---------------|
|
||||
| `{field-name}` | {validation-rule} | `{ERR_CODE}` | {message} |
|
||||
|
||||
---
|
||||
|
||||
## Error Messages
|
||||
|
||||
| Error Code | Trigger | EN | SE | Recovery |
|
||||
|------------|---------|-----|-----|----------|
|
||||
| `ERR_001` | {When occurs} | "{English}" | "{Swedish}" | {How to fix} |
|
||||
|
||||
---
|
||||
|
||||
## Form States
|
||||
|
||||
### Valid State
|
||||
- All fields pass validation
|
||||
- Submit button enabled
|
||||
- No error indicators
|
||||
|
||||
### Invalid State
|
||||
- Error fields highlighted
|
||||
- Error messages visible
|
||||
- Submit button disabled until fixed
|
||||
|
||||
### Submitting State
|
||||
- Submit button shows loading
|
||||
- Fields disabled
|
||||
- Cancel option available
|
||||
|
||||
---
|
||||
|
||||
## Field Specifications
|
||||
|
||||
### {Field Name}
|
||||
|
||||
| Property | Value |
|
||||
|----------|-------|
|
||||
| **OBJECT ID** | `{form-field-id}` |
|
||||
| Type | {text / email / password / select / etc.} |
|
||||
| Required | {yes / no} |
|
||||
| Placeholder EN | "{Placeholder text}" |
|
||||
| Placeholder SE | "{Swedish placeholder}" |
|
||||
| Validation | {rules} |
|
||||
| Error Message | {message} |
|
||||
@@ -0,0 +1,37 @@
|
||||
# Meta Content & Social Sharing
|
||||
|
||||
**Include when:** Page is Public (SEO/social sharing needed)
|
||||
|
||||
---
|
||||
|
||||
## Page Title
|
||||
**Limit:** 55-60 characters
|
||||
|
||||
`{title}`
|
||||
|
||||
---
|
||||
|
||||
## Meta Description
|
||||
**Limit:** 150-160 characters
|
||||
|
||||
`{description}`
|
||||
|
||||
---
|
||||
|
||||
## Social Sharing
|
||||
|
||||
| Property | Value |
|
||||
|----------|-------|
|
||||
| Title | {60-70 chars, can differ from page title} |
|
||||
| Description | {120-150 chars} |
|
||||
| Image | 1200x630px, `/images/social/{page-name}.jpg` |
|
||||
| Image Alt | {alt text} |
|
||||
|
||||
---
|
||||
|
||||
## Agent Questions
|
||||
|
||||
1. "What should appear in browser tab/search results?" (< 60 chars)
|
||||
2. "Describe this page to encourage clicks" (150-160 chars)
|
||||
3. "What title for social shares?"
|
||||
4. "What image represents this page?" (1200x630px)
|
||||
@@ -0,0 +1,164 @@
|
||||
# Open Questions — Auto-Population Guide
|
||||
|
||||
**Purpose:** During page specification creation or audit, automatically add relevant questions based on page characteristics.
|
||||
|
||||
---
|
||||
|
||||
## How to Use
|
||||
|
||||
When creating or auditing a page specification:
|
||||
1. Review the checklist below
|
||||
2. For each applicable category, check if the page specification addresses it
|
||||
3. If not addressed, add to the Open Questions section
|
||||
|
||||
---
|
||||
|
||||
## Responsive Behavior
|
||||
|
||||
**Trigger:** Page metadata indicates multiple viewports OR page is responsive
|
||||
|
||||
| Condition | Add Question |
|
||||
|-----------|--------------|
|
||||
| No responsive sketches | "What are the responsive breakpoint layouts? (Mobile/Tablet/Desktop)" |
|
||||
| Mobile-first but no desktop spec | "How does the layout adapt for desktop users?" |
|
||||
| Desktop-first but no mobile spec | "How does the layout adapt for mobile users?" |
|
||||
| Touch + mouse interaction | "Are there hover states that need touch alternatives?" |
|
||||
|
||||
---
|
||||
|
||||
## Loading & Error States
|
||||
|
||||
**Trigger:** Page fetches data OR has async operations
|
||||
|
||||
| Condition | Add Question |
|
||||
|-----------|--------------|
|
||||
| API data but no loading state | "What does the user see while data is loading?" |
|
||||
| No error state documented | "What happens if the data fails to load?" |
|
||||
| No empty state documented | "What does the user see when there's no data?" |
|
||||
| Async actions (save, submit) | "What feedback does the user get during async operations?" |
|
||||
| Network-dependent features | "What happens if the user is offline?" |
|
||||
|
||||
---
|
||||
|
||||
## SEO & Meta Content
|
||||
|
||||
**Trigger:** Page is public (visibility = Public)
|
||||
|
||||
| Condition | Add Question |
|
||||
|-----------|--------------|
|
||||
| No page title specified | "What is the page title for SEO?" |
|
||||
| No meta description | "What is the meta description for search results?" |
|
||||
| No Open Graph tags | "What should the social sharing preview show?" |
|
||||
| Dynamic content | "How do we handle SEO for dynamic/personalized content?" |
|
||||
|
||||
---
|
||||
|
||||
## Accessibility
|
||||
|
||||
**Trigger:** All pages (accessibility is always relevant)
|
||||
|
||||
| Condition | Add Question |
|
||||
|-----------|--------------|
|
||||
| Live updating content (timers, feeds) | "Should live updates announce to screen readers (aria-live)?" |
|
||||
| Modal/drawer interactions | "Where does focus go when modal opens/closes?" |
|
||||
| Color-coded states | "Is information conveyed by color alone?" |
|
||||
| Custom components | "Do custom components have proper ARIA roles?" |
|
||||
| Animations | "Are animations respecting prefers-reduced-motion?" |
|
||||
| Complex interactions | "What is the keyboard navigation pattern?" |
|
||||
|
||||
---
|
||||
|
||||
## User Permissions & Roles
|
||||
|
||||
**Trigger:** Page has authenticated users OR multiple user types
|
||||
|
||||
| Condition | Add Question |
|
||||
|-----------|--------------|
|
||||
| Multi-user feature | "What does User B see when User A is performing an action?" |
|
||||
| Role-based access | "Which elements are visible/hidden per role?" |
|
||||
| Shared resources | "What happens if two users act simultaneously?" |
|
||||
| Destructive actions | "Should destructive actions require confirmation?" |
|
||||
|
||||
---
|
||||
|
||||
## Time-Sensitive Features
|
||||
|
||||
**Trigger:** Page has countdowns, timers, or time-based state changes
|
||||
|
||||
| Condition | Add Question |
|
||||
|-----------|--------------|
|
||||
| Countdown timer | "What happens when the countdown reaches zero?" |
|
||||
| Time windows | "Can users act before the time window opens?" |
|
||||
| Time windows | "What happens after the time window closes?" |
|
||||
| Background behavior | "Does the timer continue when app is backgrounded?" |
|
||||
| Session timeout | "What happens when the session expires?" |
|
||||
|
||||
---
|
||||
|
||||
## Form Interactions
|
||||
|
||||
**Trigger:** Page has form inputs
|
||||
|
||||
| Condition | Add Question |
|
||||
|-----------|--------------|
|
||||
| No validation rules | "What are the validation rules for each field?" |
|
||||
| No error messages | "What error messages are shown for each validation failure?" |
|
||||
| No success state | "What happens after successful form submission?" |
|
||||
| Partial completion | "Can users save partial progress?" |
|
||||
| Sensitive data | "Are there security considerations for this form data?" |
|
||||
|
||||
---
|
||||
|
||||
## Navigation & Flow
|
||||
|
||||
**Trigger:** Page is part of a multi-step flow
|
||||
|
||||
| Condition | Add Question |
|
||||
|-----------|--------------|
|
||||
| No back navigation | "Can users go back to the previous step?" |
|
||||
| Browser back button | "What happens when user presses browser back?" |
|
||||
| Unsaved changes | "Should we warn users about unsaved changes?" |
|
||||
| Deep linking | "Can this page be accessed via direct URL?" |
|
||||
|
||||
---
|
||||
|
||||
## Integration Checklist
|
||||
|
||||
When creating a page specification, check these categories:
|
||||
|
||||
```
|
||||
[ ] Responsive — Do we have all breakpoint layouts?
|
||||
[ ] Loading — Is the loading state documented?
|
||||
[ ] Error — Is the error state documented?
|
||||
[ ] Empty — Is the empty state documented?
|
||||
[ ] SEO — Is meta content defined (if public)?
|
||||
[ ] Accessibility — Are a11y requirements specified?
|
||||
[ ] Permissions — Are role-based views documented?
|
||||
[ ] Time — Are time-sensitive behaviors defined?
|
||||
[ ] Forms — Are validation rules specified?
|
||||
[ ] Navigation — Is back/forward behavior defined?
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Example Open Questions Section
|
||||
|
||||
For a responsive page with API data and timer:
|
||||
|
||||
```markdown
|
||||
## Open Questions
|
||||
|
||||
| # | Question | Context | Status |
|
||||
|---|----------|---------|--------|
|
||||
| 1 | What are the tablet/desktop layouts? | Only mobile sketch provided | 🔴 Open |
|
||||
| 2 | What does user see while loading? | API fetch on page load | 🔴 Open |
|
||||
| 3 | What happens if API call fails? | Error handling | 🔴 Open |
|
||||
| 4 | Does timer continue when app backgrounded? | Mobile behavior | 🔴 Open |
|
||||
| 5 | Should timer announce to screen readers? | Accessibility | 🔴 Open |
|
||||
|
||||
**Status Legend:** 🔴 Open | 🟡 In Discussion | 🟢 Resolved
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
_Use this guide during specification creation and audits to ensure comprehensive coverage._
|
||||
@@ -0,0 +1,64 @@
|
||||
# Responsive Behavior
|
||||
|
||||
**Include when:** Page needs different layouts across breakpoints
|
||||
|
||||
---
|
||||
|
||||
## Breakpoints
|
||||
|
||||
| Name | Range | Primary Use |
|
||||
|------|-------|-------------|
|
||||
| Mobile | < 768px | Touch, single column |
|
||||
| Tablet | 768px - 1024px | Touch/mouse, flexible |
|
||||
| Desktop | > 1024px | Mouse, multi-column |
|
||||
|
||||
---
|
||||
|
||||
## Mobile (< 768px)
|
||||
|
||||
### Layout Changes
|
||||
- {What changes from desktop}
|
||||
|
||||
### Hidden Elements
|
||||
- {Elements not shown on mobile}
|
||||
|
||||
### Mobile-Specific
|
||||
- {Touch targets, gestures, etc.}
|
||||
|
||||
---
|
||||
|
||||
## Tablet (768px - 1024px)
|
||||
|
||||
### Layout Changes
|
||||
- {What changes}
|
||||
|
||||
### Adaptations
|
||||
- {Specific tablet behaviors}
|
||||
|
||||
---
|
||||
|
||||
## Desktop (> 1024px)
|
||||
|
||||
### Full Layout
|
||||
- {Desktop-specific features}
|
||||
|
||||
### Enhancements
|
||||
- {Hover states, keyboard shortcuts}
|
||||
|
||||
---
|
||||
|
||||
## Component Breakpoint Behavior
|
||||
|
||||
| Component | Mobile | Tablet | Desktop |
|
||||
|-----------|--------|--------|---------|
|
||||
| `{component}` | {behavior} | {behavior} | {behavior} |
|
||||
|
||||
---
|
||||
|
||||
## Navigation Changes
|
||||
|
||||
| Breakpoint | Navigation Style |
|
||||
|------------|------------------|
|
||||
| Mobile | {hamburger / bottom nav / etc.} |
|
||||
| Tablet | {style} |
|
||||
| Desktop | {full nav / sidebar / etc.} |
|
||||
@@ -0,0 +1,163 @@
|
||||
# SEO Content Instructions
|
||||
|
||||
**Condition:** Include when page visibility = "Public"
|
||||
|
||||
---
|
||||
|
||||
## Purpose
|
||||
|
||||
Ensure every public page is optimized for search engines during specification — not as an afterthought during development.
|
||||
|
||||
---
|
||||
|
||||
## Required: Check Project Brief SEO Strategy
|
||||
|
||||
Before specifying this page, check the project brief's **SEO Strategy** section:
|
||||
|
||||
1. Find this page in the **Page-Keyword Map**
|
||||
2. Note the **primary keyword** and **secondary keywords**
|
||||
3. Note the **URL slug**
|
||||
4. Note any **structured data** requirements
|
||||
|
||||
If the page is missing from the keyword map, flag it as an open question.
|
||||
|
||||
---
|
||||
|
||||
## SEO Specification Checklist
|
||||
|
||||
### 1. URL Slug
|
||||
|
||||
```markdown
|
||||
**URL:** /{slug}
|
||||
```
|
||||
|
||||
- Short, descriptive, keyword-rich
|
||||
- Lowercase, hyphens between words
|
||||
- No special characters (å→a, ä→a, ö→o)
|
||||
- Consistent with URL structure pattern from project brief
|
||||
|
||||
### 2. Heading Hierarchy
|
||||
|
||||
Verify the page has:
|
||||
|
||||
- [ ] **Exactly one H1** — Contains primary keyword
|
||||
- [ ] **Logical H2 → H3 flow** — No skipped levels
|
||||
- [ ] **Keywords in headings** — Natural placement, not stuffed
|
||||
- [ ] **H1 differs from page title tag** if needed (H1 = on-page, title = search results)
|
||||
|
||||
Document in page spec:
|
||||
|
||||
```markdown
|
||||
### Heading Hierarchy
|
||||
|
||||
| Level | Content | Keyword |
|
||||
|-------|---------|---------|
|
||||
| H1 | {Main page heading} | {primary keyword} |
|
||||
| H2 | {Section heading} | {secondary keyword} |
|
||||
| H3 | {Subsection heading} | — |
|
||||
```
|
||||
|
||||
### 3. Internal Links
|
||||
|
||||
Every public page should link to at least 2 other pages on the site.
|
||||
|
||||
- [ ] **Descriptive anchor text** — "Läs mer om vår AC-service" not "Klicka här"
|
||||
- [ ] **Related content links** — Service ↔ vehicle type, article ↔ service
|
||||
- [ ] **CTA links** — Contact, phone, booking
|
||||
|
||||
Document link targets:
|
||||
|
||||
```markdown
|
||||
### Internal Links
|
||||
|
||||
| Anchor Text | Target Page | Context |
|
||||
|-------------|-------------|---------|
|
||||
| "Läs mer om service" | /service | About section |
|
||||
| "Ring oss" | tel:+46485-27070 | CTA section |
|
||||
```
|
||||
|
||||
### 4. Image SEO
|
||||
|
||||
For every image on the page:
|
||||
|
||||
- [ ] **Alt text in all languages** — Descriptive, keyword where relevant
|
||||
- [ ] **File name** — Descriptive (`verkstad-ac-service.jpg` not `IMG_001.jpg`)
|
||||
- [ ] **Dimensions specified** — Width and height attributes (prevents CLS)
|
||||
- [ ] **Max file size** — < 200KB per image (hero images < 400KB)
|
||||
- [ ] **Format** — WebP with JPEG/PNG fallback
|
||||
- [ ] **Lazy loading** — For below-the-fold images
|
||||
- [ ] **Responsive** — srcset for mobile/desktop versions of large images
|
||||
|
||||
### 5. Meta Content
|
||||
|
||||
Include the meta content section (see [meta-content.instructions.md](meta-content.instructions.md)):
|
||||
|
||||
- [ ] **Page title** — ≤ 60 chars, includes primary keyword + brand
|
||||
- [ ] **Meta description** — 150-160 chars, includes keyword + CTA
|
||||
- [ ] **Social sharing** — Title, description, image
|
||||
|
||||
### 6. Structured Data
|
||||
|
||||
If the project brief's structured data plan includes this page type:
|
||||
|
||||
```markdown
|
||||
### Structured Data
|
||||
|
||||
**Schema Type:** {e.g., Service, Article, FAQPage}
|
||||
|
||||
| Property | Value |
|
||||
|----------|-------|
|
||||
| name | {service/article name} |
|
||||
| description | {from meta description} |
|
||||
| provider | {business name} |
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## SEO Section Template
|
||||
|
||||
Add this section to the page specification:
|
||||
|
||||
```markdown
|
||||
## SEO & Search
|
||||
|
||||
**Primary Keyword (SE):** {keyword}
|
||||
**Primary Keyword (EN):** {keyword}
|
||||
**Primary Keyword (DE):** {keyword}
|
||||
**URL:** /{slug}
|
||||
|
||||
### Page Title (Browser Tab & Search Results)
|
||||
|
||||
- SE: "{title} | {brand}" (≤ 60 chars)
|
||||
- EN: "{title} | {brand}" (≤ 60 chars)
|
||||
- DE: "{title} | {brand}" (≤ 60 chars)
|
||||
|
||||
### Meta Description
|
||||
|
||||
- SE: "{description with keyword and CTA}" (150-160 chars)
|
||||
- EN: "{description with keyword and CTA}" (150-160 chars)
|
||||
- DE: "{description with keyword and CTA}" (150-160 chars)
|
||||
|
||||
### Heading Hierarchy
|
||||
|
||||
| Level | SE | EN | DE | Keyword |
|
||||
|-------|----|----|----|---------|
|
||||
| H1 | ... | ... | ... | primary |
|
||||
| H2 | ... | ... | ... | secondary |
|
||||
|
||||
### Structured Data
|
||||
|
||||
**Type:** {Schema type}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Related
|
||||
|
||||
- [Meta Content Instructions](meta-content.instructions.md) — Detailed meta content specification
|
||||
- [SEO Strategy Guide](../../../data/agent-guides/saga/seo-strategy-guide.md) — Comprehensive SEO reference
|
||||
- [Specification Quality](../../../data/agent-guides/freya/specification-quality.md) — Quality checklist
|
||||
|
||||
---
|
||||
|
||||
*Every public page is a search result. Specify it accordingly.*
|
||||
Reference in New Issue
Block a user