@@ -9,22 +9,23 @@ This skill complements `.github/instructions/documentation.instructions.md` (the
99
1010Custom components live in ` docs/.vitepress/theme/ ` :
1111
12- | File / folder | Role |
13- | ------------------------ | -- ------------------------------------------------------------------ |
14- | ` index.ts ` | Theme entry point — imports components and global CSS |
15- | ` custom.css ` | All CSS overrides — brand colours, typography, responsive, a11y |
16- | ` Layout.vue ` | Root layout wrapper (adds ` RichFooter ` , manages slot injection) |
17- | ` TerminalDemo.vue ` | Animated terminal on the hero — ` aria-hidden="true" ` (decorative) |
18- | ` ComparisonTable.vue ` | Feature comparison table with responsive 3-column layout |
19- | ` UseCaseTabs.vue ` | WAI-ARIA Tabs pattern (roving tabindex, ArrowLeft/Right/Home/End) |
20- | ` InstallSection.vue ` | Install command snippets with OS tabs |
21- | ` HowItWorks.vue ` | 3-step explainer with responsive card layout |
22- | ` TestimonialsSection.vue ` | Community testimonials carousel |
23- | ` ProductionCta.vue ` | "Used in production?" CTA banner (` <section aria-labelledby="…"> ` ) |
24- | ` VersionBadge.vue ` | Release badge — reads ` version ` from ` package.json ` at build time |
25- | ` RichFooter.vue ` | Custom footer replacing VitePress default |
12+ | File / folder | Role |
13+ | ------------------------- | ------------------------------------------------------------------ |
14+ | ` index.ts ` | Theme entry point — imports components and global CSS |
15+ | ` custom.css ` | All CSS overrides — brand colours, typography, responsive, a11y |
16+ | ` Layout.vue ` | Root layout wrapper (adds ` RichFooter ` , manages slot injection) |
17+ | ` TerminalDemo.vue ` | Animated terminal on the hero — ` aria-hidden="true" ` (decorative) |
18+ | ` ComparisonTable.vue ` | Feature comparison table with responsive 3-column layout |
19+ | ` UseCaseTabs.vue ` | WAI-ARIA Tabs pattern (roving tabindex, ArrowLeft/Right/Home/End) |
20+ | ` InstallSection.vue ` | Install command snippets with OS tabs |
21+ | ` HowItWorks.vue ` | 3-step explainer with responsive card layout |
22+ | ` TestimonialsSection.vue ` | Community testimonials carousel |
23+ | ` ProductionCta.vue ` | "Used in production?" CTA banner (` <section aria-labelledby="…"> ` ) |
24+ | ` VersionBadge.vue ` | Release badge — reads ` version ` from ` package.json ` at build time |
25+ | ` RichFooter.vue ` | Custom footer replacing VitePress default |
2626
2727** Extending a component:**
28+
28291 . Locate the ` .vue ` file above.
29302 . Follow the existing scoped ` <style> ` conventions (no global selectors inside ` <style scoped> ` ).
30313 . Add responsive styles inside the component's ` <style> ` or in ` custom.css ` if the rule is global.
@@ -36,17 +37,17 @@ Custom components live in `docs/.vitepress/theme/`:
3637
3738Always use VitePress CSS variables — never hard-code colours in component ` <style> ` blocks:
3839
39- | Variable | Meaning |
40- | --------------------- | ------------------------------------ |
41- | ` --vp-c-brand-1 ` | Violet ` #9933FF ` / ` #cc88ff ` (dark) |
42- | ` --vp-c-brand-2 ` | Hover darkening |
43- | ` --vp-c-brand-soft ` | Soft tint for backgrounds |
44- | ` --vp-c-text-1 ` | Primary text (≥ WCAG AA on bg) |
45- | ` --vp-c-text-2 ` | Secondary text (≥ WCAG AA on bg) |
46- | ` --vp-c-text-3 ` | ** Do not use for text** — 2.87:1 contrast, fails WCAG AA |
47- | ` --vp-c-divider ` | Border / separator |
48- | ` --vp-c-bg-soft ` | Card / inset background |
49- | ` --vp-font-family-mono ` | Monospace (code blocks) |
40+ | Variable | Meaning |
41+ | ----------------------- | -------------------- ------------------------------------ |
42+ | ` --vp-c-brand-1 ` | Violet ` #9933FF ` / ` #cc88ff ` (dark) |
43+ | ` --vp-c-brand-2 ` | Hover darkening |
44+ | ` --vp-c-brand-soft ` | Soft tint for backgrounds |
45+ | ` --vp-c-text-1 ` | Primary text (≥ WCAG AA on bg) |
46+ | ` --vp-c-text-2 ` | Secondary text (≥ WCAG AA on bg) |
47+ | ` --vp-c-text-3 ` | ** Do not use for text** — 2.87:1 contrast, fails WCAG AA |
48+ | ` --vp-c-divider ` | Border / separator |
49+ | ` --vp-c-bg-soft ` | Card / inset background |
50+ | ` --vp-font-family-mono ` | Monospace (code blocks) |
5051
5152Dark mode: VitePress applies a ` .dark ` class on ` <html> ` . Use ` .dark .selector { … } ` — never ` @media (prefers-color-scheme: dark) ` .
5253
@@ -68,17 +69,17 @@ Config: `.pa11yci.json`. F77 (Mermaid duplicate SVG IDs) is ignored — not bloc
6869
6970### Common patterns
7071
71- | Pattern | Correct implementation |
72- | ------------------------------------------ | ------------------------------------------------------------------ |
73- | Landmark regions | ` <section aria-labelledby="id"> ` + matching ` id ` on heading |
74- | Icon-only buttons / links | ` aria-label="Descriptive text" ` |
75- | Decorative images / SVG | ` aria-hidden="true" ` and no ` alt ` (or ` alt="" ` ) |
76- | External links (open in new tab) | ` aria-label="Label (opens in a new tab)" ` or ` .sr-only ` suffix |
77- | Check / cross icons in tables | ` aria-label="Yes" ` / ` aria-label="No" ` |
78- | Table column headers | ` <th scope="col"> ` + ` <caption class="sr-only"> ` on ` <table> ` |
79- | Interactive tabs | Full WAI-ARIA Tabs: ` role="tablist" ` , ` role="tab" ` , ` role="tabpanel" ` , roving ` tabindex ` , keyboard nav |
80- | Screen-reader-only text | ` .sr-only ` utility class defined in ` custom.css ` |
81- | Focus visibility | ` :focus-visible ` ring defined globally in ` custom.css ` |
72+ | Pattern | Correct implementation |
73+ | -------------------------------- | ------------------------------------ ------------------------------------------------------------------ |
74+ | Landmark regions | ` <section aria-labelledby="id"> ` + matching ` id ` on heading |
75+ | Icon-only buttons / links | ` aria-label="Descriptive text" ` |
76+ | Decorative images / SVG | ` aria-hidden="true" ` and no ` alt ` (or ` alt="" ` ) |
77+ | External links (open in new tab) | ` aria-label="Label (opens in a new tab)" ` or ` .sr-only ` suffix |
78+ | Check / cross icons in tables | ` aria-label="Yes" ` / ` aria-label="No" ` |
79+ | Table column headers | ` <th scope="col"> ` + ` <caption class="sr-only"> ` on ` <table> ` |
80+ | Interactive tabs | Full WAI-ARIA Tabs: ` role="tablist" ` , ` role="tab" ` , ` role="tabpanel" ` , roving ` tabindex ` , keyboard nav |
81+ | Screen-reader-only text | ` .sr-only ` utility class defined in ` custom.css ` |
82+ | Focus visibility | ` :focus-visible ` ring defined globally in ` custom.css ` |
8283
8384### Contrast minimums (WCAG AA)
8485
@@ -96,12 +97,12 @@ This project maintains **zero horizontal overflow** across 4 tested viewports vi
9697
9798### Tested viewports
9899
99- | Label | Width | Height |
100- | --------------- | ------ | ------ |
101- | Galaxy S21 | 360px | 800px |
102- | iPhone SE | 375px | 667px |
103- | iPhone 14 | 390px | 844px |
104- | Tablet portrait | 768px | 1024px |
100+ | Label | Width | Height |
101+ | --------------- | ----- | ------ |
102+ | Galaxy S21 | 360px | 800px |
103+ | iPhone SE | 375px | 667px |
104+ | iPhone 14 | 390px | 844px |
105+ | Tablet portrait | 768px | 1024px |
105106
106107### Tool
107108
@@ -119,22 +120,29 @@ VitePress hides its hamburger at `≥768px` and shows desktop nav links — whic
119120
120121``` css
121122@media (max-width : 960px ) {
122- .VPNavBarMenu , .VPNavBarExtra { display : none !important ; }
123- .VPNavBarHamburger { display : flex !important ; }
123+ .VPNavBarMenu ,
124+ .VPNavBarExtra {
125+ display : none !important ;
126+ }
127+ .VPNavBarHamburger {
128+ display : flex !important ;
129+ }
124130}
125131@media (min-width : 768px ) and (max-width : 960px ) {
126- .VPNavScreen { display : block !important ; }
132+ .VPNavScreen {
133+ display : block !important ;
134+ }
127135}
128136```
129137
130138### Responsive patterns for components
131139
132- | Problem | Solution |
133- | ------------------------------------------- | ------------------------------------------------------------ |
134- | Table columns too wide on mobile | ` table-layout: fixed ` , abbreviated headers via ` .ct-name-short ` / ` .ct-name-long ` toggle |
135- | Long feature descriptions push rows wider | ` display: none ` on ` .ct-feature-desc ` at ` ≤640px ` |
136- | Terminal/code blocks cause page scroll | ` overflow-x: auto ` on the scroll container, ` max-width: 100% ` on the block |
137- | Long strings in ` <pre> ` overflow | ` pre { max-width: 100%; overflow-x: auto; } ` in ` custom.css ` |
140+ | Problem | Solution |
141+ | ----------------------------------------- | ---------------------------- ------------------------------------------------------------ |
142+ | Table columns too wide on mobile | ` table-layout: fixed ` , abbreviated headers via ` .ct-name-short ` / ` .ct-name-long ` toggle |
143+ | Long feature descriptions push rows wider | ` display: none ` on ` .ct-feature-desc ` at ` ≤640px ` |
144+ | Terminal/code blocks cause page scroll | ` overflow-x: auto ` on the scroll container, ` max-width: 100% ` on the block |
145+ | Long strings in ` <pre> ` overflow | ` pre { max-width: 100%; overflow-x: auto; } ` in ` custom.css ` |
138146
139147Never use ` overflow-x: hidden ` on the page root — it silently clips content. Apply it only to specific containers where clipping is intentional.
140148
0 commit comments